From 9541fe6adff9941e487084c718ff2d46ed2929c6 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Thu, 9 May 2013 09:39:15 -0700 Subject: systemctl does not expand %u, so revert back to %I The description field is only displayed by systemctl, and it can't expand %u properly (it will always display "root"). --- units/user@.service.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/units/user@.service.in b/units/user@.service.in index 3cf1347b16..ece671d448 100644 --- a/units/user@.service.in +++ b/units/user@.service.in @@ -6,7 +6,7 @@ # (at your option) any later version. [Unit] -Description=User Manager for %u +Description=User Manager for %I After=systemd-user-sessions.service [Service] -- cgit v1.2.1 From b3af9646f8ac23e73fe1d7af3b69e35b1547b13e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 May 2013 20:00:51 +0200 Subject: bus: add API for appending/reading fixed arrays --- src/libsystemd-bus/bus-message.c | 183 +++++++++++++++++++++++++++++++++- src/libsystemd-bus/bus-message.h | 4 +- src/libsystemd-bus/bus-type.c | 17 ++++ src/libsystemd-bus/bus-type.h | 1 + src/libsystemd-bus/test-bus-marshal.c | 9 ++ src/systemd/sd-bus.h | 10 +- 6 files changed, 215 insertions(+), 9 deletions(-) diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c index 835a9f9a44..afd4551b4e 100644 --- a/src/libsystemd-bus/bus-message.c +++ b/src/libsystemd-bus/bus-message.c @@ -1438,6 +1438,7 @@ int sd_bus_message_open_container( struct bus_container *c, *w; uint32_t *array_size = NULL; char *signature; + size_t before; int r; if (!m) @@ -1459,6 +1460,11 @@ int sd_bus_message_open_container( if (!signature) return -ENOMEM; + /* Save old index in the parent container, in case we have to + * abort this container */ + c->saved_index = c->index; + before = m->header->body_size; + if (type == SD_BUS_TYPE_ARRAY) r = bus_message_open_array(m, c, contents, &array_size); else if (type == SD_BUS_TYPE_VARIANT) @@ -1481,7 +1487,8 @@ int sd_bus_message_open_container( w->signature = signature; w->index = 0; w->array_size = array_size; - w->begin = 0; + w->before = before; + w->begin = m->rindex; return 0; } @@ -1507,6 +1514,36 @@ int sd_bus_message_close_container(sd_bus_message *m) { return 0; } +static void message_abort_container(sd_bus_message *m) { + struct bus_container *c; + size_t delta; + + assert(m); + assert(!m->sealed); + assert(m->n_containers > 0); + + c = message_get_container(m); + + /* Undo appends */ + assert(m->header->body_size >= c->before); + delta = m->header->body_size - c->before; + m->header->body_size = c->before; + + /* Free container */ + free(c->signature); + m->n_containers--; + + /* Correct index of new top-level container */ + c = message_get_container(m); + c->index = c->saved_index; + + /* Correct array sizes all the way up */ + for (c = m->containers; c < m->containers + m->n_containers; c++) + if (c->array_size) { + assert(*c->array_size >= delta); + *c->array_size -= delta; + } +} typedef struct { const char *types; @@ -1762,6 +1799,68 @@ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) { return r; } +int sd_bus_message_append_array_ptr(sd_bus_message *m, char type, size_t size, void **ptr) { + ssize_t align, sz; + void *a; + int r; + + if (!m) + return -EINVAL; + if (m->sealed) + return -EPERM; + if (!bus_type_is_trivial(type)) + return -EINVAL; + if (!ptr && size > 0) + return -EINVAL; + + align = bus_type_get_alignment(type); + sz = bus_type_get_size(type); + + assert_se(align > 0); + assert_se(sz > 0); + + if (size % sz != 0) + return -EINVAL; + + r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type)); + if (r < 0) + return r; + + a = message_extend_body(m, align, size); + if (!a) { + r = -ENOMEM; + goto fail; + } + + r = sd_bus_message_close_container(m); + if (r < 0) + goto fail; + + *ptr = a; + return 0; + +fail: + message_abort_container(m); + return r; +} + +int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size) { + int r; + void *p; + + if (!ptr && size > 0) + return -EINVAL; + + r = sd_bus_message_append_array_ptr(m, type, size, &p); + if (r < 0) + return r; + + if (size > 0) + memcpy(p, ptr, size); + + return 0; +} + static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) { size_t k, start, n; @@ -1990,7 +2089,7 @@ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) { assert_not_reached("Unknown basic type..."); } - m->rindex = rindex; + m->rindex = rindex; break; } @@ -2186,6 +2285,7 @@ int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *con struct bus_container *c, *w; uint32_t *array_size = NULL; char *signature; + size_t before; int r; if (!m) @@ -2228,6 +2328,9 @@ int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *con if (!signature) return -ENOMEM; + c->saved_index = c->index; + before = m->rindex; + if (type == SD_BUS_TYPE_ARRAY) r = bus_message_enter_array(m, c, contents, &array_size); else if (type == SD_BUS_TYPE_VARIANT) @@ -2250,6 +2353,7 @@ int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *con w->signature = signature; w->index = 0; w->array_size = array_size; + w->before = before; w->begin = m->rindex; return 1; @@ -2284,6 +2388,28 @@ int sd_bus_message_exit_container(sd_bus_message *m) { return 1; } +static void message_quit_container(sd_bus_message *m) { + struct bus_container *c; + + assert(m); + assert(m->sealed); + assert(m->n_containers > 0); + + c = message_get_container(m); + + /* Undo seeks */ + assert(m->rindex >= c->before); + m->rindex = c->before; + + /* Free container */ + free(c->signature); + m->n_containers--; + + /* Correct index of new top-level container */ + c = message_get_container(m); + c->index = c->saved_index; +} + int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) { struct bus_container *c; int r; @@ -2627,6 +2753,59 @@ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) { return r; } +int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) { + struct bus_container *c; + void *p; + size_t sz; + ssize_t align; + int r; + + if (!m) + return -EINVAL; + if (!m->sealed) + return -EPERM; + if (!bus_type_is_trivial(type)) + return -EINVAL; + if (!ptr) + return -EINVAL; + if (!size) + return -EINVAL; + if (BUS_MESSAGE_NEED_BSWAP(m)) + return -ENOTSUP; + + align = bus_type_get_alignment(type); + if (align < 0) + return align; + + r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type)); + if (r < 0) + return r; + + c = message_get_container(m); + sz = BUS_MESSAGE_BSWAP32(m, *c->array_size); + + r = message_peek_body(m, &m->rindex, align, sz, &p); + if (r < 0) + goto fail; + if (r == 0) { + r = -EBADMSG; + goto fail; + } + + r = sd_bus_message_exit_container(m); + if (r < 0) + goto fail; + + *ptr = (const void*) p; + *size = sz; + + return 1; + +fail: + message_quit_container(m); + return r; +} + static int message_peek_fields( sd_bus_message *m, size_t *rindex, diff --git a/src/libsystemd-bus/bus-message.h b/src/libsystemd-bus/bus-message.h index 9c0829c7fa..eafbb7c6ce 100644 --- a/src/libsystemd-bus/bus-message.h +++ b/src/libsystemd-bus/bus-message.h @@ -34,10 +34,10 @@ struct bus_container { char enclosing; char *signature; - unsigned index; + unsigned index, saved_index; uint32_t *array_size; - size_t begin; + size_t before, begin; }; struct bus_header { diff --git a/src/libsystemd-bus/bus-type.c b/src/libsystemd-bus/bus-type.c index 0557328085..6354c84f2c 100644 --- a/src/libsystemd-bus/bus-type.c +++ b/src/libsystemd-bus/bus-type.c @@ -92,6 +92,23 @@ bool bus_type_is_basic(char c) { return !!memchr(valid, c, sizeof(valid)); } +bool bus_type_is_trivial(char c) { + static const char valid[] = { + SD_BUS_TYPE_BYTE, + SD_BUS_TYPE_BOOLEAN, + SD_BUS_TYPE_INT16, + SD_BUS_TYPE_UINT16, + SD_BUS_TYPE_INT32, + SD_BUS_TYPE_UINT32, + SD_BUS_TYPE_INT64, + SD_BUS_TYPE_UINT64, + SD_BUS_TYPE_DOUBLE + }; + + return !!memchr(valid, c, sizeof(valid)); +} + + bool bus_type_is_container(char c) { static const char valid[] = { SD_BUS_TYPE_ARRAY, diff --git a/src/libsystemd-bus/bus-type.h b/src/libsystemd-bus/bus-type.h index e261136084..122628c66b 100644 --- a/src/libsystemd-bus/bus-type.h +++ b/src/libsystemd-bus/bus-type.h @@ -29,6 +29,7 @@ bool bus_type_is_valid(char c); bool bus_type_is_valid_in_signature(char c); bool bus_type_is_basic(char c); +bool bus_type_is_trivial(char c); bool bus_type_is_container(char c); int bus_type_get_alignment(char c); int bus_type_get_size(char c); diff --git a/src/libsystemd-bus/test-bus-marshal.c b/src/libsystemd-bus/test-bus-marshal.c index 20ae723fbe..ac519531f7 100644 --- a/src/libsystemd-bus/test-bus-marshal.c +++ b/src/libsystemd-bus/test-bus-marshal.c @@ -43,6 +43,7 @@ int main(int argc, char *argv[]) { void *buffer = NULL; size_t sz; char *h; + const int32_t integer_array[] = { -1, -2, 0, 1, 2 }, *return_array; r = sd_bus_message_new_method_call(NULL, "foobar.waldo", "/", "foobar.waldo", "Piep", &m); assert_se(r >= 0); @@ -77,6 +78,9 @@ int main(int argc, char *argv[]) { r = sd_bus_message_close_container(m); assert_se(r >= 0); + r = sd_bus_message_append_array(m, 'i', integer_array, sizeof(integer_array)); + assert_se(r >= 0); + r = bus_message_seal(m, 4711); assert_se(r >= 0); @@ -168,6 +172,11 @@ int main(int argc, char *argv[]) { assert_se(streq(x, "foobar")); assert_se(streq(y, "waldo")); + r = sd_bus_message_read_array(m, 'i', (const void**) &return_array, &sz); + assert_se(r > 0); + assert_se(sz == sizeof(integer_array)); + assert_se(memcmp(integer_array, return_array, sz) == 0); + r = sd_bus_message_peek_type(m, NULL, NULL); assert_se(r == 0); diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h index c1ec50871f..2dab93d916 100644 --- a/src/systemd/sd-bus.h +++ b/src/systemd/sd-bus.h @@ -41,15 +41,10 @@ extern "C" { #endif /* TODO: - * - add page donation logic - * - api for appending/reading fixed arrays * - merge busctl into systemctl or so? * - default policy (allow uid == 0 and our own uid) - * * - enforce alignment of pointers passed in * - negotiation for attach attributes - * - * - for kernel and unix transports allow setting the unix user/access mode for the node */ typedef struct sd_bus sd_bus; @@ -173,6 +168,11 @@ int sd_bus_message_exit_container(sd_bus_message *m); int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents); int sd_bus_message_rewind(sd_bus_message *m, int complete); +int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size); +int sd_bus_message_append_array_ptr(sd_bus_message *m, char type, size_t size, void **ptr); + +int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size); + /* Convenience calls */ int sd_bus_emit_signal(sd_bus *bus, const char *path, const char *interface, const char *member, const char *types, ...); -- cgit v1.2.1 From 7ecec4705c0cacb1446af0eb7a4aee66c00d058f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 9 May 2013 18:10:30 -0400 Subject: systemd-python: wrap sd_login_monitor --- man/sd_login_monitor_new.xml | 2 +- src/python-systemd/_daemon.c | 49 ++++----- src/python-systemd/_reader.c | 22 +--- src/python-systemd/docs/journal.rst | 2 +- src/python-systemd/docs/login.rst | 23 ++++ src/python-systemd/login.c | 209 ++++++++++++++++++++++++++++++++++++ src/python-systemd/pyutil.c | 14 +++ src/python-systemd/pyutil.h | 1 + 8 files changed, 269 insertions(+), 53 deletions(-) diff --git a/man/sd_login_monitor_new.xml b/man/sd_login_monitor_new.xml index 26af0ea247..261ef1d9d3 100644 --- a/man/sd_login_monitor_new.xml +++ b/man/sd_login_monitor_new.xml @@ -96,7 +96,7 @@ Description sd_login_monitor_new() may - be used to monitor login sessions, users, seats and + be used to monitor login sessions, users, seats, and virtual machines/containers. Via a monitor object a file descriptor can be integrated into an application defined event loop which is woken up each time a user diff --git a/src/python-systemd/_daemon.c b/src/python-systemd/_daemon.c index d3b4807368..c6b14d4665 100644 --- a/src/python-systemd/_daemon.c +++ b/src/python-systemd/_daemon.c @@ -40,21 +40,6 @@ PyDoc_STRVAR(module__doc__, "running under systemd." ); -static PyObject* set_error(int r, const char* invalid_message) { - assert (r < 0); - - if (r == -EINVAL && invalid_message) - PyErr_SetString(PyExc_ValueError, invalid_message); - else if (r == -ENOMEM) - PyErr_SetString(PyExc_MemoryError, "Not enough memory"); - else { - errno = -r; - PyErr_SetFromErrno(PyExc_OSError); - } - - return NULL; -} - #if PY_MAJOR_VERSION >=3 && PY_MINOR_VERSION >= 1 static int Unicode_FSConverter(PyObject* obj, void *_result) { @@ -88,8 +73,8 @@ static PyObject* booted(PyObject *self, PyObject *args) { assert(args == NULL); r = sd_booted(); - if (r < 0) - return set_error(r, NULL); + if (set_error(r, NULL, NULL)) + return NULL; return PyBool_FromLong(r); } @@ -120,8 +105,8 @@ static PyObject* listen_fds(PyObject *self, PyObject *args) { #endif r = sd_listen_fds(unset); - if (r < 0) - return set_error(r, NULL); + if (set_error(r, NULL, NULL)) + return NULL; return long_FromLong(r); } @@ -148,8 +133,8 @@ static PyObject* is_fifo(PyObject *self, PyObject *args) { #endif r = sd_is_fifo(fd, path); - if (r < 0) - return set_error(r, NULL); + if (set_error(r, path, NULL)) + return NULL; return PyBool_FromLong(r); } @@ -176,8 +161,8 @@ static PyObject* is_mq(PyObject *self, PyObject *args) { #endif r = sd_is_mq(fd, path); - if (r < 0) - return set_error(r, NULL); + if (set_error(r, path, NULL)) + return NULL; return PyBool_FromLong(r); } @@ -200,8 +185,8 @@ static PyObject* is_socket(PyObject *self, PyObject *args) { return NULL; r = sd_is_socket(fd, family, type, listening); - if (r < 0) - return set_error(r, NULL); + if (set_error(r, NULL, NULL)) + return NULL; return PyBool_FromLong(r); } @@ -221,12 +206,14 @@ static PyObject* is_socket_inet(PyObject *self, PyObject *args) { &fd, &family, &type, &listening, &port)) return NULL; - if (port < 0 || port > INT16_MAX) - return set_error(-EINVAL, "port must fit into uint16_t"); + if (port < 0 || port > INT16_MAX) { + set_error(-EINVAL, NULL, "port must fit into uint16_t"); + return NULL; + } r = sd_is_socket_inet(fd, family, type, listening, (uint16_t) port); - if (r < 0) - return set_error(r, NULL); + if (set_error(r, NULL, NULL)) + return NULL; return PyBool_FromLong(r); } @@ -260,8 +247,8 @@ static PyObject* is_socket_unix(PyObject *self, PyObject *args) { #endif r = sd_is_socket_unix(fd, type, listening, path, length); - if (r < 0) - return set_error(r, NULL); + if (set_error(r, path, NULL)) + return NULL; return PyBool_FromLong(r); } diff --git a/src/python-systemd/_reader.c b/src/python-systemd/_reader.c index d20c58d2a8..c4c4fdfe1d 100644 --- a/src/python-systemd/_reader.c +++ b/src/python-systemd/_reader.c @@ -38,20 +38,6 @@ typedef struct { } Reader; static PyTypeObject ReaderType; -static int set_error(int r, const char* path, const char* invalid_message) { - if (r >= 0) - return r; - if (r == -EINVAL && invalid_message) - PyErr_SetString(PyExc_ValueError, invalid_message); - else if (r == -ENOMEM) - PyErr_SetString(PyExc_MemoryError, "Not enough memory"); - else { - errno = -r; - PyErr_SetFromErrnoWithFilename(PyExc_OSError, path); - } - return -1; -} - PyDoc_STRVAR(module__doc__, "Class to reads the systemd journal similar to journalctl."); @@ -177,7 +163,7 @@ PyDoc_STRVAR(Reader_get_timeout__doc__, "Returns a timeout value for usage in poll(), the time since the\n" "epoch of clock_gettime(2) in microseconds, or None if no timeout\n" "is necessary.\n\n" - "The return value must be converted to a relative timeout in \n" + "The return value must be converted to a relative timeout in\n" "milliseconds if it is to be used as an argument for poll().\n" "See man:sd_journal_get_timeout(3) for further discussion."); static PyObject* Reader_get_timeout(Reader *self, PyObject *args) @@ -275,11 +261,7 @@ PyDoc_STRVAR(Reader___exit____doc__, "Closes the journal.\n"); static PyObject* Reader___exit__(Reader *self, PyObject *args) { - assert(self); - - sd_journal_close(self->j); - self->j = NULL; - Py_RETURN_NONE; + return Reader_close(self, args); } diff --git a/src/python-systemd/docs/journal.rst b/src/python-systemd/docs/journal.rst index 08756b99be..e6c42061f3 100644 --- a/src/python-systemd/docs/journal.rst +++ b/src/python-systemd/docs/journal.rst @@ -42,7 +42,7 @@ event loop: >>> j = journal.Reader() >>> j.seek_tail() >>> p = select.poll() - >>> p.register(j, select.POLLIN) + >>> p.register(j, j.get_events()) >>> p.poll() [(3, 1)] >>> j.get_next() diff --git a/src/python-systemd/docs/login.rst b/src/python-systemd/docs/login.rst index 2cd9d8cbee..6b4de64c55 100644 --- a/src/python-systemd/docs/login.rst +++ b/src/python-systemd/docs/login.rst @@ -3,3 +3,26 @@ .. automodule:: systemd.login :members: + +.. autoclass:: Monitor + :undoc-members: + :inherited-members: + +Example: polling for events +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This example shows that session/uid/seat/machine events can be waited +for (using e.g. `poll`). This makes it easy to integrate Monitor in an +external event loop: + + >>> import select + >>> from systemd import login + >>> m = login.Monitor("machine") + >>> p = select.poll() + >>> p.register(m, m.get_events()) + >>> login.machine_names() + [] + >>> p.poll() + [(3, 1)] + >>> login.machine_names() + ['fedora-19.nspawn'] diff --git a/src/python-systemd/login.c b/src/python-systemd/login.c index 1dbe5ac5bf..57dc080215 100644 --- a/src/python-systemd/login.c +++ b/src/python-systemd/login.c @@ -133,6 +133,198 @@ static PyMethodDef methods[] = { {} /* Sentinel */ }; + +typedef struct { + PyObject_HEAD + sd_login_monitor *monitor; +} Monitor; +static PyTypeObject MonitorType; + +static void Monitor_dealloc(Monitor* self) +{ + sd_login_monitor_unref(self->monitor); + Py_TYPE(self)->tp_free((PyObject*)self); +} + +PyDoc_STRVAR(Monitor__doc__, + "Monitor([category]) -> ...\n\n" + "Monitor may be used to monitor login sessions, users, seats,\n" + "and virtual machines/containers. Monitor provides a file\n" + "descriptor which can be integrated in an external event loop.\n" + "See man:sd_login_monitor_new(3) for the details about what\n" + "can be monitored."); +static int Monitor_init(Monitor *self, PyObject *args, PyObject *keywds) +{ + const char *category = NULL; + int r; + + static const char* const kwlist[] = {"category", NULL}; + if (!PyArg_ParseTupleAndKeywords(args, keywds, "|z", (char**) kwlist, + &category)) + return -1; + + Py_BEGIN_ALLOW_THREADS + r = sd_login_monitor_new(category, &self->monitor); + Py_END_ALLOW_THREADS + + return set_error(r, NULL, "Invalid category"); +} + + +PyDoc_STRVAR(Monitor_fileno__doc__, + "fileno() -> int\n\n" + "Get a file descriptor to poll for events.\n" + "This method wraps sd_login_monitor_get_fd(3)."); +static PyObject* Monitor_fileno(Monitor *self, PyObject *args) +{ + int fd = sd_login_monitor_get_fd(self->monitor); + set_error(fd, NULL, NULL); + if (fd < 0) + return NULL; + return long_FromLong(fd); +} + + +PyDoc_STRVAR(Monitor_get_events__doc__, + "get_events() -> int\n\n" + "Returns a mask of poll() events to wait for on the file\n" + "descriptor returned by .fileno().\n\n" + "See man:sd_login_monitor_get_events(3) for further discussion."); +static PyObject* Monitor_get_events(Monitor *self, PyObject *args) +{ + int r = sd_login_monitor_get_events(self->monitor); + set_error(r, NULL, NULL); + if (r < 0) + return NULL; + return long_FromLong(r); +} + + +PyDoc_STRVAR(Monitor_get_timeout__doc__, + "get_timeout() -> int or None\n\n" + "Returns a timeout value for usage in poll(), the time since the\n" + "epoch of clock_gettime(2) in microseconds, or None if no timeout\n" + "is necessary.\n\n" + "The return value must be converted to a relative timeout in\n" + "milliseconds if it is to be used as an argument for poll().\n" + "See man:sd_login_monitor_get_timeout(3) for further discussion."); +static PyObject* Monitor_get_timeout(Monitor *self, PyObject *args) +{ + int r; + uint64_t t; + + r = sd_login_monitor_get_timeout(self->monitor, &t); + set_error(r, NULL, NULL); + if (r < 0) + return NULL; + + if (t == (uint64_t) -1) + Py_RETURN_NONE; + + assert_cc(sizeof(unsigned long long) == sizeof(t)); + return PyLong_FromUnsignedLongLong(t); +} + + +PyDoc_STRVAR(Monitor_get_timeout_ms__doc__, + "get_timeout_ms() -> int\n\n" + "Returns a timeout value suitable for usage in poll(), the value\n" + "returned by .get_timeout() converted to relative ms, or -1 if\n" + "no timeout is necessary."); +static PyObject* Monitor_get_timeout_ms(Monitor *self, PyObject *args) +{ + int r; + uint64_t t; + + r = sd_login_monitor_get_timeout(self->monitor, &t); + set_error(r, NULL, NULL); + if (r < 0) + return NULL; + + return absolute_timeout(t); +} + + +PyDoc_STRVAR(Monitor_close__doc__, + "close() -> None\n\n" + "Free resources allocated by this Monitor object.\n" + "This method invokes sd_login_monitor_unref().\n" + "See man:sd_login_monitor_unref(3)."); +static PyObject* Monitor_close(Monitor *self, PyObject *args) +{ + assert(self); + assert(!args); + + sd_login_monitor_unref(self->monitor); + self->monitor = NULL; + Py_RETURN_NONE; +} + + +PyDoc_STRVAR(Monitor_flush__doc__, + "flush() -> None\n\n" + "Reset the wakeup state of the monitor object.\n" + "This method invokes sd_login_monitor_flush().\n" + "See man:sd_login_monitor_flush(3)."); +static PyObject* Monitor_flush(Monitor *self, PyObject *args) +{ + assert(self); + assert(!args); + + sd_login_monitor_flush(self->monitor); + Py_RETURN_NONE; +} + + +PyDoc_STRVAR(Monitor___enter____doc__, + "__enter__() -> self\n\n" + "Part of the context manager protocol.\n" + "Returns self.\n"); +static PyObject* Monitor___enter__(PyObject *self, PyObject *args) +{ + assert(self); + assert(!args); + + Py_INCREF(self); + return self; +} + + +PyDoc_STRVAR(Monitor___exit____doc__, + "__exit__(type, value, traceback) -> None\n\n" + "Part of the context manager protocol.\n" + "Closes the monitor..\n"); +static PyObject* Monitor___exit__(Monitor *self, PyObject *args) +{ + return Monitor_close(self, args); +} + + +static PyMethodDef Monitor_methods[] = { + {"fileno", (PyCFunction) Monitor_fileno, METH_NOARGS, Monitor_fileno__doc__}, + {"get_events", (PyCFunction) Monitor_get_events, METH_NOARGS, Monitor_get_events__doc__}, + {"get_timeout", (PyCFunction) Monitor_get_timeout, METH_NOARGS, Monitor_get_timeout__doc__}, + {"get_timeout_ms", (PyCFunction) Monitor_get_timeout_ms, METH_NOARGS, Monitor_get_timeout_ms__doc__}, + {"close", (PyCFunction) Monitor_close, METH_NOARGS, Monitor_close__doc__}, + {"flush", (PyCFunction) Monitor_flush, METH_NOARGS, Monitor_flush__doc__}, + {"__enter__", (PyCFunction) Monitor___enter__, METH_NOARGS, Monitor___enter____doc__}, + {"__exit__", (PyCFunction) Monitor___exit__, METH_VARARGS, Monitor___exit____doc__}, + {} /* Sentinel */ +}; + +static PyTypeObject MonitorType = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "login.Monitor", + .tp_basicsize = sizeof(Monitor), + .tp_dealloc = (destructor) Monitor_dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .tp_doc = Monitor__doc__, + .tp_methods = Monitor_methods, + .tp_init = (initproc) Monitor_init, + .tp_new = PyType_GenericNew, +}; + + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmissing-prototypes" @@ -141,10 +333,17 @@ static PyMethodDef methods[] = { PyMODINIT_FUNC initlogin(void) { PyObject *m; + if (PyType_Ready(&MonitorType) < 0) + return; + m = Py_InitModule3("login", methods, module__doc__); if (m == NULL) return; + PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION); + + Py_INCREF(&MonitorType); + PyModule_AddObject(m, "Monitor", (PyObject *) &MonitorType); } #else @@ -159,6 +358,9 @@ static struct PyModuleDef module = { PyMODINIT_FUNC PyInit_login(void) { PyObject *m; + if (PyType_Ready(&MonitorType) < 0) + return NULL; + m = PyModule_Create(&module); if (m == NULL) return NULL; @@ -168,6 +370,13 @@ PyMODINIT_FUNC PyInit_login(void) { return NULL; } + Py_INCREF(&MonitorType); + if (PyModule_AddObject(m, "Monitor", (PyObject *) &MonitorType)) { + Py_DECREF(&MonitorType); + Py_DECREF(m); + return NULL; + } + return m; } diff --git a/src/python-systemd/pyutil.c b/src/python-systemd/pyutil.c index 9510acdddb..2f047e643a 100644 --- a/src/python-systemd/pyutil.c +++ b/src/python-systemd/pyutil.c @@ -44,3 +44,17 @@ PyObject* absolute_timeout(uint64_t t) { return PyLong_FromLong(msec); } } + +int set_error(int r, const char* path, const char* invalid_message) { + if (r >= 0) + return r; + if (r == -EINVAL && invalid_message) + PyErr_SetString(PyExc_ValueError, invalid_message); + else if (r == -ENOMEM) + PyErr_SetString(PyExc_MemoryError, "Not enough memory"); + else { + errno = -r; + PyErr_SetFromErrnoWithFilename(PyExc_OSError, path); + } + return -1; +} diff --git a/src/python-systemd/pyutil.h b/src/python-systemd/pyutil.h index 5c7ea37cdb..ea88840fa7 100644 --- a/src/python-systemd/pyutil.h +++ b/src/python-systemd/pyutil.h @@ -28,6 +28,7 @@ void cleanup_Py_DECREFp(PyObject **p); PyObject* absolute_timeout(uint64_t t); +int set_error(int r, const char* path, const char* invalid_message); #define _cleanup_Py_DECREF_ __attribute__((cleanup(cleanup_Py_DECREFp))) -- cgit v1.2.1 From a7739f8f973b1a57ee0f8a9404a7c8ed375f2197 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 9 May 2013 18:10:44 -0400 Subject: build-sys: add convinience 'make python-shell' This will launch $(PYTHON) with $LD_LIBRARY_PATH and $PYTHONPATH as ./configure-d and DESTDIR-ed. Use as: make install DESTDIR=/var/tmp/inst python-shell --- Makefile.am | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile.am b/Makefile.am index 3a196a65e7..0ac99a6889 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3826,6 +3826,10 @@ sphinx-%: $(AM_V_GEN)PYTHONPATH=$(DESTDIR)$(pyexecdir) LD_LIBRARY_PATH=$(DESTDIR)$(libdir) $(SPHINX_BUILD) -b $* $(SPHINXOPTS) $(top_srcdir)/src/python-systemd/docs $(top_builddir)/docs/html/python-systemd/ $(AM_V_at)echo Output has been generated in $(abs_top_builddir)/docs/html/python-systemd/ +python-shell: + $(AM_V_at)echo "Starting python with $(DESTDIR)$(pyexecdir)" + $(AM_V_at)PYTHONPATH=$(DESTDIR)$(pyexecdir) LD_LIBRARY_PATH=$(DESTDIR)$(libdir) $(PYTHON) + destdir-sphinx: all dir="$$(mktemp -d /tmp/systemd-install.XXXXXX)" && \ $(MAKE) DESTDIR="$$dir" install && \ -- cgit v1.2.1 From f49fd1d57a429d4a05ac86352c017a845f8185b3 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 7 May 2013 14:16:53 +0200 Subject: Start ctrl-alt-del.target irreversibly This makes ctrl-alt-del reboots more robust, just like "systemctl reboot". --- src/core/manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/manager.c b/src/core/manager.c index c7f8f20a70..0508628b21 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -1372,7 +1372,7 @@ static int manager_process_signal_fd(Manager *m) { case SIGINT: if (m->running_as == SYSTEMD_SYSTEM) { - manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE); + manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE_IRREVERSIBLY); break; } -- cgit v1.2.1 From 77b6e19458f37cfde127ec6aa9494c0ac45ad890 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 May 2013 00:14:12 +0200 Subject: audit: since audit is apparently never going to be fixed for containers tell the user what's going on Let's try to be helpful to the user and give him a hint what he can do to make nspawn work with normal OS containers. https://bugzilla.redhat.com/show_bug.cgi?id=893751 --- README | 7 +++++++ man/systemd-nspawn.xml | 15 +++++++++------ src/nspawn/nspawn.c | 19 +++++++++++++++++++ 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/README b/README index b8d1f42e25..3cd93f01f4 100644 --- a/README +++ b/README @@ -79,6 +79,13 @@ REQUIREMENTS: CONFIG_EFI_VARS CONFIG_EFI_PARTITION + Note that kernel auditing is broken when used with systemd's + container code. When using systemd in conjunction with + containers please make sure to either turn off auditing at + runtime using the kernel command line option "audit=0", or + turn it off at kernel compile time using: + CONFIG_AUDIT=n + dbus >= 1.4.0 libcap libblkid >= 2.20 (from util-linux) (optional) diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml index d9fb899895..1bc61e83a7 100644 --- a/man/systemd-nspawn.xml +++ b/man/systemd-nspawn.xml @@ -142,16 +142,19 @@ might be necessary to add this file to the container tree manually if the OS of the container is too old to contain this file out-of-the-box. + + + + Incompatibility with Auditing Note that the kernel auditing subsystem is currently broken when used together with containers. We hence recommend turning it off entirely - when using systemd-nspawn by - booting with audit=0 on the kernel - command line, or by turning it off at kernel build - time. If auditing is enabled in the kernel operating - systems booted in an nspawn container might refuse - log-in attempts. + by booting with audit=0 on the + kernel command line, or by turning it off at kernel + build time. If auditing is enabled in the kernel + operating systems booted in an nspawn container might + refuse log-in attempts. diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 09153c87ce..b91b0b8a91 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -1219,6 +1219,18 @@ finish: return r; } +static bool audit_enabled(void) { + int fd; + + fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_AUDIT); + if (fd >= 0) { + close_nointr_nofail(fd); + return true; + } + + return false; +} + int main(int argc, char *argv[]) { pid_t pid = 0; int r = EXIT_FAILURE, k; @@ -1284,6 +1296,13 @@ int main(int argc, char *argv[]) { goto finish; } + if (audit_enabled()) { + log_warning("The kernel auditing subsystem is known to be incompatible with containers.\n" + "Please make sure to turn off auditing with 'audit=0' on the kernel command\n" + "line before using systemd-nspawn. Sleeping for 5s...\n"); + sleep(5); + } + if (path_equal(arg_directory, "/")) { log_error("Spawning container on root directory not supported."); goto finish; -- cgit v1.2.1 From 04b33f69b6fba648b0d48aca03b9310b3cfdb02d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 9 May 2013 18:25:54 -0400 Subject: systemd-python: use consistent indentation --- src/python-systemd/login.c | 92 ++++++++++++++++++++++----------------------- src/python-systemd/pyutil.c | 48 +++++++++++------------ 2 files changed, 70 insertions(+), 70 deletions(-) diff --git a/src/python-systemd/login.c b/src/python-systemd/login.c index 57dc080215..b5cb811ec1 100644 --- a/src/python-systemd/login.c +++ b/src/python-systemd/login.c @@ -142,8 +142,8 @@ static PyTypeObject MonitorType; static void Monitor_dealloc(Monitor* self) { - sd_login_monitor_unref(self->monitor); - Py_TYPE(self)->tp_free((PyObject*)self); + sd_login_monitor_unref(self->monitor); + Py_TYPE(self)->tp_free((PyObject*)self); } PyDoc_STRVAR(Monitor__doc__, @@ -192,11 +192,11 @@ PyDoc_STRVAR(Monitor_get_events__doc__, "See man:sd_login_monitor_get_events(3) for further discussion."); static PyObject* Monitor_get_events(Monitor *self, PyObject *args) { - int r = sd_login_monitor_get_events(self->monitor); - set_error(r, NULL, NULL); - if (r < 0) - return NULL; - return long_FromLong(r); + int r = sd_login_monitor_get_events(self->monitor); + set_error(r, NULL, NULL); + if (r < 0) + return NULL; + return long_FromLong(r); } @@ -210,19 +210,19 @@ PyDoc_STRVAR(Monitor_get_timeout__doc__, "See man:sd_login_monitor_get_timeout(3) for further discussion."); static PyObject* Monitor_get_timeout(Monitor *self, PyObject *args) { - int r; - uint64_t t; + int r; + uint64_t t; - r = sd_login_monitor_get_timeout(self->monitor, &t); - set_error(r, NULL, NULL); - if (r < 0) - return NULL; + r = sd_login_monitor_get_timeout(self->monitor, &t); + set_error(r, NULL, NULL); + if (r < 0) + return NULL; - if (t == (uint64_t) -1) - Py_RETURN_NONE; + if (t == (uint64_t) -1) + Py_RETURN_NONE; - assert_cc(sizeof(unsigned long long) == sizeof(t)); - return PyLong_FromUnsignedLongLong(t); + assert_cc(sizeof(unsigned long long) == sizeof(t)); + return PyLong_FromUnsignedLongLong(t); } @@ -233,15 +233,15 @@ PyDoc_STRVAR(Monitor_get_timeout_ms__doc__, "no timeout is necessary."); static PyObject* Monitor_get_timeout_ms(Monitor *self, PyObject *args) { - int r; - uint64_t t; + int r; + uint64_t t; - r = sd_login_monitor_get_timeout(self->monitor, &t); - set_error(r, NULL, NULL); - if (r < 0) - return NULL; + r = sd_login_monitor_get_timeout(self->monitor, &t); + set_error(r, NULL, NULL); + if (r < 0) + return NULL; - return absolute_timeout(t); + return absolute_timeout(t); } @@ -282,11 +282,11 @@ PyDoc_STRVAR(Monitor___enter____doc__, "Returns self.\n"); static PyObject* Monitor___enter__(PyObject *self, PyObject *args) { - assert(self); - assert(!args); + assert(self); + assert(!args); - Py_INCREF(self); - return self; + Py_INCREF(self); + return self; } @@ -301,27 +301,27 @@ static PyObject* Monitor___exit__(Monitor *self, PyObject *args) static PyMethodDef Monitor_methods[] = { - {"fileno", (PyCFunction) Monitor_fileno, METH_NOARGS, Monitor_fileno__doc__}, - {"get_events", (PyCFunction) Monitor_get_events, METH_NOARGS, Monitor_get_events__doc__}, - {"get_timeout", (PyCFunction) Monitor_get_timeout, METH_NOARGS, Monitor_get_timeout__doc__}, - {"get_timeout_ms", (PyCFunction) Monitor_get_timeout_ms, METH_NOARGS, Monitor_get_timeout_ms__doc__}, - {"close", (PyCFunction) Monitor_close, METH_NOARGS, Monitor_close__doc__}, - {"flush", (PyCFunction) Monitor_flush, METH_NOARGS, Monitor_flush__doc__}, - {"__enter__", (PyCFunction) Monitor___enter__, METH_NOARGS, Monitor___enter____doc__}, - {"__exit__", (PyCFunction) Monitor___exit__, METH_VARARGS, Monitor___exit____doc__}, - {} /* Sentinel */ + {"fileno", (PyCFunction) Monitor_fileno, METH_NOARGS, Monitor_fileno__doc__}, + {"get_events", (PyCFunction) Monitor_get_events, METH_NOARGS, Monitor_get_events__doc__}, + {"get_timeout", (PyCFunction) Monitor_get_timeout, METH_NOARGS, Monitor_get_timeout__doc__}, + {"get_timeout_ms", (PyCFunction) Monitor_get_timeout_ms, METH_NOARGS, Monitor_get_timeout_ms__doc__}, + {"close", (PyCFunction) Monitor_close, METH_NOARGS, Monitor_close__doc__}, + {"flush", (PyCFunction) Monitor_flush, METH_NOARGS, Monitor_flush__doc__}, + {"__enter__", (PyCFunction) Monitor___enter__, METH_NOARGS, Monitor___enter____doc__}, + {"__exit__", (PyCFunction) Monitor___exit__, METH_VARARGS, Monitor___exit____doc__}, + {} /* Sentinel */ }; static PyTypeObject MonitorType = { - PyVarObject_HEAD_INIT(NULL, 0) - .tp_name = "login.Monitor", - .tp_basicsize = sizeof(Monitor), - .tp_dealloc = (destructor) Monitor_dealloc, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - .tp_doc = Monitor__doc__, - .tp_methods = Monitor_methods, - .tp_init = (initproc) Monitor_init, - .tp_new = PyType_GenericNew, + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "login.Monitor", + .tp_basicsize = sizeof(Monitor), + .tp_dealloc = (destructor) Monitor_dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .tp_doc = Monitor__doc__, + .tp_methods = Monitor_methods, + .tp_init = (initproc) Monitor_init, + .tp_new = PyType_GenericNew, }; diff --git a/src/python-systemd/pyutil.c b/src/python-systemd/pyutil.c index 2f047e643a..42e7ba72cf 100644 --- a/src/python-systemd/pyutil.c +++ b/src/python-systemd/pyutil.c @@ -30,31 +30,31 @@ void cleanup_Py_DECREFp(PyObject **p) { } PyObject* absolute_timeout(uint64_t t) { - if (t == (uint64_t) -1) - return PyLong_FromLong(-1); - else { - struct timespec ts; - uint64_t n; - int msec; - - clock_gettime(CLOCK_MONOTONIC, &ts); - n = (uint64_t) ts.tv_sec * 1000000 + ts.tv_nsec / 1000; - msec = t > n ? (int) ((t - n + 999) / 1000) : 0; - - return PyLong_FromLong(msec); - } + if (t == (uint64_t) -1) + return PyLong_FromLong(-1); + else { + struct timespec ts; + uint64_t n; + int msec; + + clock_gettime(CLOCK_MONOTONIC, &ts); + n = (uint64_t) ts.tv_sec * 1000000 + ts.tv_nsec / 1000; + msec = t > n ? (int) ((t - n + 999) / 1000) : 0; + + return PyLong_FromLong(msec); + } } int set_error(int r, const char* path, const char* invalid_message) { - if (r >= 0) - return r; - if (r == -EINVAL && invalid_message) - PyErr_SetString(PyExc_ValueError, invalid_message); - else if (r == -ENOMEM) - PyErr_SetString(PyExc_MemoryError, "Not enough memory"); - else { - errno = -r; - PyErr_SetFromErrnoWithFilename(PyExc_OSError, path); - } - return -1; + if (r >= 0) + return r; + if (r == -EINVAL && invalid_message) + PyErr_SetString(PyExc_ValueError, invalid_message); + else if (r == -ENOMEM) + PyErr_SetString(PyExc_MemoryError, "Not enough memory"); + else { + errno = -r; + PyErr_SetFromErrnoWithFilename(PyExc_OSError, path); + } + return -1; } -- cgit v1.2.1 From c15602af5efd0cf8d30c6ad8161e0442acb5dce2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 9 May 2013 18:28:15 -0400 Subject: systemd-python: allow threads around flush flush() is potentially costly. --- src/python-systemd/login.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/python-systemd/login.c b/src/python-systemd/login.c index b5cb811ec1..1e86193f6b 100644 --- a/src/python-systemd/login.c +++ b/src/python-systemd/login.c @@ -271,7 +271,9 @@ static PyObject* Monitor_flush(Monitor *self, PyObject *args) assert(self); assert(!args); + Py_BEGIN_ALLOW_THREADS sd_login_monitor_flush(self->monitor); + Py_END_ALLOW_THREADS Py_RETURN_NONE; } -- cgit v1.2.1 From e13e1fad8b231e187bd5de3ce668411bdcd3ac1a Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 9 May 2013 18:32:32 -0400 Subject: Fix previous commit for !HAVE_AUDIT --- src/nspawn/nspawn.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index b91b0b8a91..33153c9507 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -1220,6 +1220,7 @@ finish: } static bool audit_enabled(void) { +#ifdef HAVE_AUDIT int fd; fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_AUDIT); @@ -1227,7 +1228,7 @@ static bool audit_enabled(void) { close_nointr_nofail(fd); return true; } - +#endif return false; } -- cgit v1.2.1 From 2e996f4d4b642c5682c608c9692ad2ffae398ab2 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 9 May 2013 19:31:20 -0400 Subject: nspawn: Include netlink headers rather than using #ifdef This is a better fix than e13e1fad8b231e187bd5de3ce668411bdcd3ac1a for failing to compile without audit that 77b6e19458f37cfde127ec6aa9494c0ac45ad890 introduced. --- src/nspawn/nspawn.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 33153c9507..95d76eb3c3 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -1220,7 +1221,6 @@ finish: } static bool audit_enabled(void) { -#ifdef HAVE_AUDIT int fd; fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_AUDIT); @@ -1228,7 +1228,6 @@ static bool audit_enabled(void) { close_nointr_nofail(fd); return true; } -#endif return false; } -- cgit v1.2.1 From f8e013f8bf476e6d61fb2e218c85e23032a46302 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 May 2013 01:12:15 +0200 Subject: bus: add sd_bus_message_append_string_space() for zero-copy string appending --- src/libsystemd-bus/bus-message.c | 58 +++++++++++++++++++++++++++++++++-- src/libsystemd-bus/test-bus-marshal.c | 9 ++++++ src/systemd/sd-bus.h | 9 +++--- 3 files changed, 69 insertions(+), 7 deletions(-) diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c index afd4551b4e..fdc3ac6813 100644 --- a/src/libsystemd-bus/bus-message.c +++ b/src/libsystemd-bus/bus-message.c @@ -1207,6 +1207,60 @@ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) { return message_append_basic(m, type, p, NULL); } +int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) { + struct bus_container *c; + char *e; + void *a; + int r; + + if (!m) + return -EINVAL; + if (!s) + return -EINVAL; + if (m->sealed) + return -EPERM; + + c = message_get_container(m); + + if (c->signature && c->signature[c->index]) { + /* Container signature is already set */ + + if (c->signature[c->index] != SD_BUS_TYPE_STRING) + return -ENXIO; + } else { + /* Maybe we can append to the signature? But only if this is the top-level container*/ + if (c->enclosing != 0) + return -ENXIO; + + e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL); + if (!e) + return -ENOMEM; + } + + + a = message_extend_body(m, 4, 4 + size + 1); + if (!a) { + r = -ENOMEM; + goto fail; + } + + *(uint32_t*) a = size; + *s = (char*) a + 4; + + (*s)[size] = 0; + + if (c->enclosing != SD_BUS_TYPE_ARRAY) + c->index++; + + return 0; + +fail: + if (e) + c->signature[c->index] = 0; + + return r; +} + static int bus_message_open_array( sd_bus_message *m, struct bus_container *c, @@ -1799,7 +1853,7 @@ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) { return r; } -int sd_bus_message_append_array_ptr(sd_bus_message *m, char type, size_t size, void **ptr) { +int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr) { ssize_t align, sz; void *a; int r; @@ -1851,7 +1905,7 @@ int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, s if (!ptr && size > 0) return -EINVAL; - r = sd_bus_message_append_array_ptr(m, type, size, &p); + r = sd_bus_message_append_array_space(m, type, size, &p); if (r < 0) return r; diff --git a/src/libsystemd-bus/test-bus-marshal.c b/src/libsystemd-bus/test-bus-marshal.c index ac519531f7..ef1a77f5fc 100644 --- a/src/libsystemd-bus/test-bus-marshal.c +++ b/src/libsystemd-bus/test-bus-marshal.c @@ -44,6 +44,7 @@ int main(int argc, char *argv[]) { size_t sz; char *h; const int32_t integer_array[] = { -1, -2, 0, 1, 2 }, *return_array; + char *s; r = sd_bus_message_new_method_call(NULL, "foobar.waldo", "/", "foobar.waldo", "Piep", &m); assert_se(r >= 0); @@ -78,6 +79,10 @@ int main(int argc, char *argv[]) { r = sd_bus_message_close_container(m); assert_se(r >= 0); + r = sd_bus_message_append_string_space(m, 5, &s); + assert_se(r >= 0); + strcpy(s, "hallo"); + r = sd_bus_message_append_array(m, 'i', integer_array, sizeof(integer_array)); assert_se(r >= 0); @@ -172,6 +177,10 @@ int main(int argc, char *argv[]) { assert_se(streq(x, "foobar")); assert_se(streq(y, "waldo")); + r = sd_bus_message_read_basic(m, 's', &s); + assert_se(r > 0); + assert_se(streq(s, "hallo")); + r = sd_bus_message_read_array(m, 'i', (const void**) &return_array, &sz); assert_se(r > 0); assert_se(sz == sizeof(integer_array)); diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h index 2dab93d916..28c8536992 100644 --- a/src/systemd/sd-bus.h +++ b/src/systemd/sd-bus.h @@ -158,21 +158,20 @@ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination); int sd_bus_message_append(sd_bus_message *m, const char *types, ...); int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p); +int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size); +int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr); +int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s); int sd_bus_message_open_container(sd_bus_message *m, char type, const char *contents); int sd_bus_message_close_container(sd_bus_message *m); int sd_bus_message_read(sd_bus_message *m, const char *types, ...); int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p); +int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size); int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents); int sd_bus_message_exit_container(sd_bus_message *m); int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents); int sd_bus_message_rewind(sd_bus_message *m, int complete); -int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size); -int sd_bus_message_append_array_ptr(sd_bus_message *m, char type, size_t size, void **ptr); - -int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size); - /* Convenience calls */ int sd_bus_emit_signal(sd_bus *bus, const char *path, const char *interface, const char *member, const char *types, ...); -- cgit v1.2.1 From fd8d62d94016d1981f65b9414af2218250fba070 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 May 2013 03:36:55 +0200 Subject: bus: catch up with latest kdbus --- src/libsystemd-bus/bus-internal.h | 2 + src/libsystemd-bus/bus-kernel.c | 168 ++++++++++++++++++++--------------- src/libsystemd-bus/bus-message.c | 6 ++ src/libsystemd-bus/bus-message.h | 3 + src/libsystemd-bus/kdbus.h | 35 +++++--- src/libsystemd-bus/test-bus-kernel.c | 3 + 6 files changed, 136 insertions(+), 81 deletions(-) diff --git a/src/libsystemd-bus/bus-internal.h b/src/libsystemd-bus/bus-internal.h index 4babfac86d..05184fd560 100644 --- a/src/libsystemd-bus/bus-internal.h +++ b/src/libsystemd-bus/bus-internal.h @@ -150,6 +150,8 @@ struct sd_bus { uint64_t hello_serial; unsigned iteration_counter; + + void *kdbus_buffer; }; static inline void bus_unrefp(sd_bus **b) { diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index 0762b7836f..aecf408645 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -25,6 +25,7 @@ #include #include +#include #include "util.h" @@ -44,6 +45,8 @@ #define KDBUS_ITEM_HEADER_SIZE offsetof(struct kdbus_item, data) #define KDBUS_ITEM_SIZE(s) ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE) +#define KDBUS_BUFFER_SIZE (4*1024*1024) + static int parse_unique_name(const char *s, uint64_t *id) { int r; @@ -111,7 +114,7 @@ static void append_fds(struct kdbus_item **d, const int fds[], unsigned n_fds) { *d = ALIGN8_PTR(*d); (*d)->size = offsetof(struct kdbus_item, fds) + sizeof(int) * n_fds; - (*d)->type = KDBUS_MSG_UNIX_FDS; + (*d)->type = KDBUS_MSG_FDS; memcpy((*d)->fds, fds, sizeof(int) * n_fds); *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size); @@ -275,17 +278,12 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) { } int bus_kernel_take_fd(sd_bus *b) { - struct kdbus_cmd_hello hello = { - .conn_flags = - KDBUS_HELLO_ACCEPT_FD| - KDBUS_HELLO_ATTACH_COMM| - KDBUS_HELLO_ATTACH_EXE| - KDBUS_HELLO_ATTACH_CMDLINE| - KDBUS_HELLO_ATTACH_CGROUP| - KDBUS_HELLO_ATTACH_CAPS| - KDBUS_HELLO_ATTACH_SECLABEL| - KDBUS_HELLO_ATTACH_AUDIT - }; + uint8_t h[ALIGN8(sizeof(struct kdbus_cmd_hello)) + + ALIGN8(KDBUS_ITEM_HEADER_SIZE) + + ALIGN8(sizeof(struct kdbus_vec))] = {}; + + struct kdbus_cmd_hello *hello = (struct kdbus_cmd_hello*) h; + int r; assert(b); @@ -293,20 +291,44 @@ int bus_kernel_take_fd(sd_bus *b) { if (b->is_server) return -EINVAL; - r = ioctl(b->input_fd, KDBUS_CMD_HELLO, &hello); + if (!b->kdbus_buffer) { + b->kdbus_buffer = mmap(NULL, KDBUS_BUFFER_SIZE, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); + if (b->kdbus_buffer == MAP_FAILED) { + b->kdbus_buffer = NULL; + return -errno; + } + } + + hello->size = sizeof(h); + hello->conn_flags = + KDBUS_HELLO_ACCEPT_FD| + KDBUS_HELLO_ATTACH_COMM| + KDBUS_HELLO_ATTACH_EXE| + KDBUS_HELLO_ATTACH_CMDLINE| + KDBUS_HELLO_ATTACH_CGROUP| + KDBUS_HELLO_ATTACH_CAPS| + KDBUS_HELLO_ATTACH_SECLABEL| + KDBUS_HELLO_ATTACH_AUDIT; + + hello->items[0].type = KDBUS_HELLO_BUFFER; + hello->items[0].size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec); + hello->items[0].vec.address = (uint64_t) b->kdbus_buffer; + hello->items[0].vec.size = KDBUS_BUFFER_SIZE; + + r = ioctl(b->input_fd, KDBUS_CMD_HELLO, hello); if (r < 0) return -errno; /* The higher 32bit of both flags fields are considered * 'incompatible flags'. Refuse them all for now. */ - if (hello.bus_flags > 0xFFFFFFFFULL || - hello.conn_flags > 0xFFFFFFFFULL) + if (hello->bus_flags > 0xFFFFFFFFULL || + hello->conn_flags > 0xFFFFFFFFULL) return -ENOTSUP; - if (hello.bloom_size != BLOOM_SIZE) + if (hello->bloom_size != BLOOM_SIZE) return -ENOTSUP; - if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello.id) < 0) + if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello->id) < 0) return -ENOMEM; b->is_kernel = true; @@ -356,18 +378,36 @@ int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m) { return 1; } -static void close_kdbus_msg(struct kdbus_msg *k) { +static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) { struct kdbus_item *d; + assert(bus); + assert(k); + + ioctl(bus->input_fd, KDBUS_CMD_MSG_RELEASE, k); + KDBUS_ITEM_FOREACH(d, k) { - if (d->type != KDBUS_MSG_UNIX_FDS) + if (d->type != KDBUS_MSG_FDS) continue; close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int)); } } +static bool range_contains(size_t astart, size_t asize, size_t bstart, size_t bsize, void *a, void **b) { + + if (bstart < astart) + return false; + + if (bstart + bsize > astart + asize) + return false; + + *b = (uint8_t*) a + (bstart - astart); + + return true; +} + static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_message **ret) { sd_bus_message *m = NULL; struct kdbus_item *d; @@ -390,19 +430,19 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess l = d->size - offsetof(struct kdbus_item, data); - if (d->type == KDBUS_MSG_PAYLOAD) { + if (d->type == KDBUS_MSG_PAYLOAD_VEC) { if (!h) { - if (l < sizeof(struct bus_header)) + if (d->vec.size < sizeof(struct bus_header)) return -EBADMSG; - h = (struct bus_header*) d->data; + h = (struct bus_header*) d->vec.address; } n_payload++; - n_bytes += l; + n_bytes += d->vec.size; - } else if (d->type == KDBUS_MSG_UNIX_FDS) { + } else if (d->type == KDBUS_MSG_FDS) { int *f; unsigned j; @@ -431,6 +471,9 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess if (n_bytes != total) return -EBADMSG; + if (n_payload > 2) + return -EBADMSG; + r = bus_message_from_header(h, sizeof(struct bus_header), fds, n_fds, NULL, seclabel, 0, &m); if (r < 0) return r; @@ -440,20 +483,13 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess l = d->size - offsetof(struct kdbus_item, data); - if (d->type == KDBUS_MSG_PAYLOAD) { - - if (idx == sizeof(struct bus_header) && - l == ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m))) - m->fields = d->data; - else if (idx == sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m)) && - l == BUS_MESSAGE_BODY_SIZE(m)) - m->body = d->data; - else if (!(idx == 0 && l == sizeof(struct bus_header))) { - sd_bus_message_unref(m); - return -EBADMSG; - } + if (d->type == KDBUS_MSG_PAYLOAD_VEC) { + + range_contains(idx, d->vec.size, ALIGN8(sizeof(struct bus_header)), BUS_MESSAGE_FIELDS_SIZE(m), (void*) d->vec.address, &m->fields); + range_contains(idx, d->vec.size, ALIGN8(sizeof(struct bus_header)) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m)), BUS_MESSAGE_BODY_SIZE(m), (void*) d->vec.address, &m->body); + + idx += d->vec.size; - idx += l; } else if (d->type == KDBUS_MSG_SRC_CREDS) { m->pid_starttime = d->creds.starttime / NSEC_PER_USEC; m->uid = d->creds.uid; @@ -480,10 +516,18 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess else if (d->type == KDBUS_MSG_SRC_CAPS) { m->capability = d->data; m->capability_size = l; - } else + } else if (d->type != KDBUS_MSG_FDS && + d->type != KDBUS_MSG_DST_NAME && + d->type != KDBUS_MSG_SRC_SECLABEL) log_debug("Got unknown field from kernel %llu", d->type); } + if ((BUS_MESSAGE_FIELDS_SIZE(m) > 0 && !m->fields) || + (BUS_MESSAGE_BODY_SIZE(m) > 0 && !m->body)) { + sd_bus_message_unref(m); + return -EBADMSG; + } + r = bus_message_parse_fields(m); if (r < 0) { sd_bus_message_unref(m); @@ -509,7 +553,8 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess /* We take possession of the kmsg struct now */ m->kdbus = k; - m->free_kdbus = true; + m->bus = sd_bus_ref(bus); + m->release_kdbus = true; m->free_fds = true; fds = NULL; @@ -520,48 +565,31 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess int bus_kernel_read_message(sd_bus *bus, sd_bus_message **m) { struct kdbus_msg *k; - size_t sz = 1024; int r; assert(bus); assert(m); - for (;;) { - void *q; - - q = memalign(8, sz); - if (!q) - return -errno; - - free(bus->rbuffer); - k = bus->rbuffer = q; - k->size = sz; - - /* Let's tell valgrind that there's really no need to - * initialize this fully. This should be removed again - * when valgrind learned the kdbus ioctls natively. */ -#ifdef HAVE_VALGRIND_MEMCHECK_H - VALGRIND_MAKE_MEM_DEFINED(k, sz); -#endif - - r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, bus->rbuffer); - if (r >= 0) - break; - + r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &k); + if (r < 0) { if (errno == EAGAIN) return 0; - if (errno != ENOBUFS) - return -errno; - - sz *= 2; + return -errno; } + +/* /\* Let's tell valgrind that there's really no need to */ +/* * initialize this fully. This should be removed again */ +/* * when valgrind learned the kdbus ioctls natively. *\/ */ +/* #ifdef HAVE_VALGRIND_MEMCHECK_H */ +/* VALGRIND_MAKE_MEM_DEFINED(k, sz); */ +/* #endif */ + + r = bus_kernel_make_message(bus, k, m); - if (r > 0) - bus->rbuffer = NULL; - else - close_kdbus_msg(k); + if (r <= 0) + close_kdbus_msg(bus, k); return r < 0 ? r : 1; } diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c index fdc3ac6813..cc2b78a8c5 100644 --- a/src/libsystemd-bus/bus-message.c +++ b/src/libsystemd-bus/bus-message.c @@ -66,11 +66,17 @@ static void message_free(sd_bus_message *m) { if (m->free_kdbus) free(m->kdbus); + if (m->release_kdbus) + ioctl(m->bus->input_fd, KDBUS_CMD_MSG_RELEASE, m->kdbus); + if (m->free_fds) { close_many(m->fds, m->n_fds); free(m->fds); } + if (m->bus) + sd_bus_unref(m->bus); + free(m->cmdline_array); reset_containers(m); diff --git a/src/libsystemd-bus/bus-message.h b/src/libsystemd-bus/bus-message.h index eafbb7c6ce..86a41a73b6 100644 --- a/src/libsystemd-bus/bus-message.h +++ b/src/libsystemd-bus/bus-message.h @@ -53,6 +53,8 @@ struct bus_header { struct sd_bus_message { unsigned n_ref; + sd_bus *bus; + uint32_t reply_serial; const char *path; @@ -81,6 +83,7 @@ struct sd_bus_message { bool free_body:1; bool free_kdbus:1; bool free_fds:1; + bool release_kdbus:1; struct bus_header *header; void *fields; diff --git a/src/libsystemd-bus/kdbus.h b/src/libsystemd-bus/kdbus.h index db5e243c17..a2eba186ca 100644 --- a/src/libsystemd-bus/kdbus.h +++ b/src/libsystemd-bus/kdbus.h @@ -70,14 +70,15 @@ enum { KDBUS_MSG_NULL, /* Filled in by userspace */ - KDBUS_MSG_PAYLOAD, /* .data, inline memory */ KDBUS_MSG_PAYLOAD_VEC, /* .data_vec, reference to memory area */ - KDBUS_MSG_UNIX_FDS, /* .data_fds of file descriptors */ + KDBUS_MSG_PAYLOAD_MEMFD, /* file descriptor of a special data file */ + KDBUS_MSG_FDS, /* .data_fds of file descriptors */ KDBUS_MSG_BLOOM, /* for broadcasts, carries bloom filter blob in .data */ KDBUS_MSG_DST_NAME, /* destination's well-known name, in .str */ + KDBUS_MSG_PRIORITY, /* queue priority for message */ /* Filled in by kernelspace */ - KDBUS_MSG_SRC_NAMES = 0x200,/* NUL separated string list with well-known names of source */ + KDBUS_MSG_SRC_NAMES = 0x400,/* NUL separated string list with well-known names of source */ KDBUS_MSG_TIMESTAMP, /* .timestamp */ KDBUS_MSG_SRC_CREDS, /* .creds */ KDBUS_MSG_SRC_PID_COMM, /* optional, in .str */ @@ -90,7 +91,7 @@ enum { KDBUS_MSG_SRC_AUDIT, /* .audit */ /* Special messages from kernel, consisting of one and only one of these data blocks */ - KDBUS_MSG_NAME_ADD = 0x400,/* .name_change */ + KDBUS_MSG_NAME_ADD = 0x800,/* .name_change */ KDBUS_MSG_NAME_REMOVE, /* .name_change */ KDBUS_MSG_NAME_CHANGE, /* .name_change */ KDBUS_MSG_ID_ADD, /* .id_change */ @@ -99,14 +100,14 @@ enum { KDBUS_MSG_REPLY_DEAD, /* dito */ }; -enum { - KDBUS_VEC_ALIGNED = 1 << 0, -}; - struct kdbus_vec { __u64 address; __u64 size; - __u64 flags; +}; + +struct kdbus_memfd { + __u64 size; + int fd; }; /** @@ -137,6 +138,7 @@ struct kdbus_item { struct kdbus_timestamp timestamp; /* specific fields */ + int fd; int fds[0]; struct kdbus_manager_msg_name_change name_change; struct kdbus_manager_msg_id_change id_change; @@ -236,6 +238,8 @@ enum { /* Items to append to struct kdbus_cmd_hello */ enum { KDBUS_HELLO_NULL, + KDBUS_HELLO_BUFFER, /* kdbus_vec, userspace supplied buffer to + * place received messages */ }; struct kdbus_cmd_hello { @@ -276,7 +280,7 @@ enum { * cgroup membership paths * to messages. */ KDBUS_MAKE_CRED, /* allow translator services which connect * to the bus on behalf of somebody else, - * allow specifying the credentials of the + * allow specifiying the credentials of the * client to connect on behalf on. Needs * privileges */ }; @@ -401,7 +405,8 @@ enum kdbus_cmd { /* kdbus ep node commands: require connected state */ KDBUS_CMD_MSG_SEND = _IOWR(KDBUS_IOC_MAGIC, 0x40, struct kdbus_msg), - KDBUS_CMD_MSG_RECV = _IOWR(KDBUS_IOC_MAGIC, 0x41, struct kdbus_msg), + KDBUS_CMD_MSG_RECV = _IOWR(KDBUS_IOC_MAGIC, 0x41, struct kdbus_msg *), + KDBUS_CMD_MSG_RELEASE = _IOWR(KDBUS_IOC_MAGIC, 0x42, struct kdbus_msg), KDBUS_CMD_NAME_ACQUIRE = _IOWR(KDBUS_IOC_MAGIC, 0x50, struct kdbus_cmd_name), KDBUS_CMD_NAME_RELEASE = _IOWR(KDBUS_IOC_MAGIC, 0x51, struct kdbus_cmd_name), @@ -414,5 +419,13 @@ enum kdbus_cmd { /* kdbus ep node commands: require ep owner state */ KDBUS_CMD_EP_POLICY_SET = _IOWR(KDBUS_IOC_MAGIC, 0x70, struct kdbus_cmd_policy), + + /* kdbus ep node commands: */ + KDBUS_CMD_MEMFD_NEW = _IOWR(KDBUS_IOC_MAGIC, 0x80, int *), + + /* kdbus memfd commands: */ + KDBUS_CMD_MEMFD_SIZE_GET = _IOWR(KDBUS_IOC_MAGIC, 0x81, __u64 *), + KDBUS_CMD_MEMFD_SEAL_GET = _IOWR(KDBUS_IOC_MAGIC, 0x82, int *), + KDBUS_CMD_MEMFD_SEAL_SET = _IOWR(KDBUS_IOC_MAGIC, 0x83, int), }; #endif diff --git a/src/libsystemd-bus/test-bus-kernel.c b/src/libsystemd-bus/test-bus-kernel.c index 1095e57e42..72514a3dee 100644 --- a/src/libsystemd-bus/test-bus-kernel.c +++ b/src/libsystemd-bus/test-bus-kernel.c @@ -22,6 +22,7 @@ #include #include "util.h" +#include "log.h" #include "sd-bus.h" #include "bus-message.h" @@ -36,6 +37,8 @@ int main(int argc, char *argv[]) { sd_bus *a, *b; int r, pipe_fds[2]; + log_set_max_level(LOG_DEBUG); + bus_ref = bus_kernel_create("deine-mutter", &bus_name); if (bus_ref == -ENOENT) return EXIT_TEST_SKIP; -- cgit v1.2.1 From 72455f9bf092ce65b0ca6c7f8b91366e21175615 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 10 May 2013 04:55:43 +0200 Subject: kdbus: update kdbus.h from upstream --- src/libsystemd-bus/kdbus.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libsystemd-bus/kdbus.h b/src/libsystemd-bus/kdbus.h index a2eba186ca..a8922c76e3 100644 --- a/src/libsystemd-bus/kdbus.h +++ b/src/libsystemd-bus/kdbus.h @@ -138,7 +138,6 @@ struct kdbus_item { struct kdbus_timestamp timestamp; /* specific fields */ - int fd; int fds[0]; struct kdbus_manager_msg_name_change name_change; struct kdbus_manager_msg_id_change id_change; @@ -425,7 +424,8 @@ enum kdbus_cmd { /* kdbus memfd commands: */ KDBUS_CMD_MEMFD_SIZE_GET = _IOWR(KDBUS_IOC_MAGIC, 0x81, __u64 *), - KDBUS_CMD_MEMFD_SEAL_GET = _IOWR(KDBUS_IOC_MAGIC, 0x82, int *), - KDBUS_CMD_MEMFD_SEAL_SET = _IOWR(KDBUS_IOC_MAGIC, 0x83, int), + KDBUS_CMD_MEMFD_SIZE_SET = _IOWR(KDBUS_IOC_MAGIC, 0x82, __u64), + KDBUS_CMD_MEMFD_SEAL_GET = _IOWR(KDBUS_IOC_MAGIC, 0x83, int *), + KDBUS_CMD_MEMFD_SEAL_SET = _IOWR(KDBUS_IOC_MAGIC, 0x84, int), }; #endif -- cgit v1.2.1 From ddeb424198649c3993a54efc81652325b6e3bfa5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 May 2013 14:34:57 +0200 Subject: bus: add new API for kdbus memfd functionality --- .gitignore | 2 + Makefile.am | 17 ++- src/libsystemd-bus/kdbus.h | 2 +- src/libsystemd-bus/sd-memfd.c | 207 ++++++++++++++++++++++++++++++++++++ src/libsystemd-bus/test-bus-memfd.c | 85 +++++++++++++++ src/systemd/sd-memfd.h | 56 ++++++++++ 6 files changed, 366 insertions(+), 3 deletions(-) create mode 100644 src/libsystemd-bus/sd-memfd.c create mode 100644 src/libsystemd-bus/test-bus-memfd.c create mode 100644 src/systemd/sd-memfd.h diff --git a/.gitignore b/.gitignore index c1fe85d656..d53e75a43e 100644 --- a/.gitignore +++ b/.gitignore @@ -85,6 +85,7 @@ /test-bus-kernel /test-bus-marshal /test-bus-match +/test-bus-memfd /test-bus-signature /test-bus-server /test-calendarspec @@ -97,6 +98,7 @@ /test-engine /test-env-replace /test-fileio +/test-hashmap /test-hostname /test-id128 /test-inhibit diff --git a/Makefile.am b/Makefile.am index 0ac99a6889..eb85c8dada 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1718,6 +1718,7 @@ EXTRA_DIST += \ libsystemd_bus_la_SOURCES = \ src/systemd/sd-bus.h \ src/systemd/sd-bus-protocol.h \ + src/systemd/sd-memfd.h \ src/libsystemd-bus/sd-bus.c \ src/libsystemd-bus/bus-control.c \ src/libsystemd-bus/bus-control.h \ @@ -1739,7 +1740,8 @@ libsystemd_bus_la_SOURCES = \ src/libsystemd-bus/bus-match.h \ src/libsystemd-bus/bus-bloom.c \ src/libsystemd-bus/bus-bloom.h \ - src/libsystemd-bus/kdbus.h + src/libsystemd-bus/kdbus.h \ + src/libsystemd-bus/sd-memfd.c libsystemd_bus_la_LIBADD = \ libsystemd-id128-internal.la \ @@ -1755,7 +1757,8 @@ tests += \ test-bus-chat \ test-bus-server \ test-bus-match \ - test-bus-kernel + test-bus-kernel \ + test-bus-memfd noinst_PROGRAMS += \ busctl @@ -1827,6 +1830,16 @@ test_bus_kernel_LDADD = \ libsystemd-bus.la \ libsystemd-id128-internal.la +test_bus_memfd_SOURCES = \ + src/libsystemd-bus/test-bus-memfd.c + +test_bus_memfd_CFLAGS = \ + $(AM_CFLAGS) + +test_bus_memfd_LDADD = \ + libsystemd-shared.la \ + libsystemd-bus.la + busctl_SOURCES = \ src/libsystemd-bus/busctl.c diff --git a/src/libsystemd-bus/kdbus.h b/src/libsystemd-bus/kdbus.h index a8922c76e3..bb339ae69c 100644 --- a/src/libsystemd-bus/kdbus.h +++ b/src/libsystemd-bus/kdbus.h @@ -424,7 +424,7 @@ enum kdbus_cmd { /* kdbus memfd commands: */ KDBUS_CMD_MEMFD_SIZE_GET = _IOWR(KDBUS_IOC_MAGIC, 0x81, __u64 *), - KDBUS_CMD_MEMFD_SIZE_SET = _IOWR(KDBUS_IOC_MAGIC, 0x82, __u64), + KDBUS_CMD_MEMFD_SIZE_SET = _IOWR(KDBUS_IOC_MAGIC, 0x82, __u64 *), KDBUS_CMD_MEMFD_SEAL_GET = _IOWR(KDBUS_IOC_MAGIC, 0x83, int *), KDBUS_CMD_MEMFD_SEAL_SET = _IOWR(KDBUS_IOC_MAGIC, 0x84, int), }; diff --git a/src/libsystemd-bus/sd-memfd.c b/src/libsystemd-bus/sd-memfd.c new file mode 100644 index 0000000000..51b111e8b5 --- /dev/null +++ b/src/libsystemd-bus/sd-memfd.c @@ -0,0 +1,207 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include + +#include "util.h" +#include "kdbus.h" + +#include "sd-memfd.h" + +struct sd_memfd { + int fd; + FILE *f; +}; + +int sd_memfd_new(sd_memfd **m) { + _cleanup_close_ int kdbus = -1; + sd_memfd *n; + int fd; + + if (!m) + return -EINVAL; + + kdbus = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return -errno; + + if (ioctl(kdbus, KDBUS_CMD_MEMFD_NEW, &fd) < 0) + return -errno; + + n = new0(struct sd_memfd, 1); + if (!n) + return -ENOMEM; + + n->fd = fd; + *m = n; + return 0; +} + +int sd_memfd_make(int fd, sd_memfd **m) { + sd_memfd *n; + uint64_t sz; + + if (!m) + return -EINVAL; + if (fd < 0) + return -EINVAL; + + /* Check if this is a valid memfd */ + if (ioctl(fd, KDBUS_CMD_MEMFD_SIZE_GET, &sz) < 0) + return -ENOTTY; + + n = new0(struct sd_memfd, 1); + if (!n) + return -ENOMEM; + + n->fd = fd; + *m = n; + + return 0; +} + +void sd_memfd_free(sd_memfd *m) { + if (!m) + return; + + if (m->f) + fclose(m->f); + else + close_nointr_nofail(m->fd); + + free(m); +} + +int sd_memfd_get_fd(sd_memfd *m) { + if (!m) + return -EINVAL; + + return m->fd; +} + +int sd_memfd_get_file(sd_memfd *m, FILE **f) { + if (!m) + return -EINVAL; + if (!f) + return -EINVAL; + + if (!m->fd) { + m->f = fdopen(m->fd, "r+"); + if (!m->f) + return -errno; + } + + *f = m->f; + return 0; +} + +int sd_memfd_dup_fd(sd_memfd *m) { + int fd; + + if (!m) + return -EINVAL; + + fd = fcntl(m->fd, F_DUPFD_CLOEXEC, 3); + if (fd < 0) + return -errno; + + return fd; +} + +int sd_memfd_map(sd_memfd *m, uint64_t offset, size_t size, void **p) { + void *q; + int sealed; + + if (!m) + return -EINVAL; + if (size <= 0) + return -EINVAL; + if (!p) + return -EINVAL; + + sealed = sd_memfd_get_sealed(m); + if (sealed < 0) + return sealed; + + q = mmap(NULL, size, sealed ? PROT_READ : PROT_READ|PROT_WRITE, MAP_SHARED, m->fd, offset); + if (q == MAP_FAILED) + return -errno; + + *p = q; + return 0; +} + +int sd_memfd_set_sealed(sd_memfd *m, int b) { + int r; + + if (!m) + return -EINVAL; + + r = ioctl(m->fd, KDBUS_CMD_MEMFD_SEAL_SET, b); + if (r < 0) + return -errno; + + return 0; +} + +int sd_memfd_get_sealed(sd_memfd *m) { + int r, b; + + if (!m) + return -EINVAL; + + r = ioctl(m->fd, KDBUS_CMD_MEMFD_SEAL_GET, &b); + if (r < 0) + return -errno; + + return !!b; +} + +int sd_memfd_get_size(sd_memfd *m, uint64_t *sz) { + int r; + + if (!m) + return -EINVAL; + if (!sz) + return -EINVAL; + + r = ioctl(m->fd, KDBUS_CMD_MEMFD_SIZE_GET, sz); + if (r < 0) + return -errno; + + return r; +} + +int sd_memfd_set_size(sd_memfd *m, uint64_t sz) { + int r; + + if (!m) + return -EINVAL; + + r = ioctl(m->fd, KDBUS_CMD_MEMFD_SIZE_SET, &sz); + if (r < 0) + return -errno; + + return r; +} diff --git a/src/libsystemd-bus/test-bus-memfd.c b/src/libsystemd-bus/test-bus-memfd.c new file mode 100644 index 0000000000..4c5ae21a8c --- /dev/null +++ b/src/libsystemd-bus/test-bus-memfd.c @@ -0,0 +1,85 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include + +#include "log.h" +#include "macro.h" +#include "util.h" + +#include "sd-memfd.h" + +int main(int argc, char *argv[]) { + sd_memfd *m; + char *s; + uint64_t sz; + int r, fd; + + log_set_max_level(LOG_DEBUG); + + r = sd_memfd_new(&m); + if (r == -ENOENT) + return EXIT_TEST_SKIP; + + r = sd_memfd_map(m, 0, 6, (void**) &s); + assert_se(r >= 0); + + strcpy(s, "hallo"); + assert_se(munmap(s, 6) == 0); + + assert_se(write(sd_memfd_get_fd(m), "he", 2) == 2); + + r = sd_memfd_get_sealed(m); + assert_se(r == 0); + + r = sd_memfd_set_sealed(m, 1); + assert_se(r >= 0); + + r = sd_memfd_get_sealed(m); + assert_se(r == 1); + + r = sd_memfd_get_size(m, &sz); + assert_se(r >= 0); + assert_se(sz = page_size()); + + r = sd_memfd_set_size(m, 6); + assert_se(r >= 0); + + fd = sd_memfd_dup_fd(m); + assert_se(fd >= 0); + + sd_memfd_free(m); + + r = sd_memfd_make(fd, &m); + assert_se(r >= 0); + + r = sd_memfd_get_size(m, &sz); + assert_se(r >= 0); + assert_se(sz = 6); + + r = sd_memfd_map(m, 0, 6, (void**) &s); + assert_se(r >= 0); + + assert_se(streq(s, "hello")); + assert_se(munmap(s, 6) == 0); + + return 0; +} diff --git a/src/systemd/sd-memfd.h b/src/systemd/sd-memfd.h new file mode 100644 index 0000000000..8594a3b61f --- /dev/null +++ b/src/systemd/sd-memfd.h @@ -0,0 +1,56 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foosdmemfdhfoo +#define foosdmemfdhfoo + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct sd_memfd sd_memfd; + +int sd_memfd_new(sd_memfd **m); +int sd_memfd_make(int fd, sd_memfd **m); + +void sd_memfd_free(sd_memfd *m); + +int sd_memfd_get_fd(sd_memfd *m); +int sd_memfd_get_file(sd_memfd *m, FILE **f); +int sd_memfd_dup_fd(sd_memfd *n); + +int sd_memfd_map(sd_memfd *m, uint64_t offset, size_t size, void **p); + +int sd_memfd_set_sealed(sd_memfd *m, int b); +int sd_memfd_get_sealed(sd_memfd *m); + +int sd_memfd_get_size(sd_memfd *m, uint64_t *sz); +int sd_memfd_set_size(sd_memfd *m, uint64_t sz); + +#ifdef __cplusplus +} +#endif + +#endif -- cgit v1.2.1 From c2384970ff604e6341879bc965305b84533cdebf Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Fri, 10 May 2013 08:59:00 -0400 Subject: nspawn: only warn about audit when booting the container The audit subsystem isn't relevant when nspawn is only being used as a chroot. --- src/nspawn/nspawn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 95d76eb3c3..32cfe05dcd 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -1296,7 +1296,7 @@ int main(int argc, char *argv[]) { goto finish; } - if (audit_enabled()) { + if (arg_boot && audit_enabled()) { log_warning("The kernel auditing subsystem is known to be incompatible with containers.\n" "Please make sure to turn off auditing with 'audit=0' on the kernel command\n" "line before using systemd-nspawn. Sleeping for 5s...\n"); -- cgit v1.2.1 From a7c54c8c1fc4101e784c101e680975f2143381ce Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 May 2013 17:33:44 +0200 Subject: bus: extend memfd test --- TODO | 2 ++ src/libsystemd-bus/sd-memfd.c | 2 +- src/libsystemd-bus/test-bus-memfd.c | 47 +++++++++++++++++++++++++++++++------ 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/TODO b/TODO index 4f5af140f0..8d4b937a5a 100644 --- a/TODO +++ b/TODO @@ -29,6 +29,8 @@ Fedora 19: Features: +* maybe add "journalctl -k" as shortcut for "-b _TRANSPORT=kernel" + * Introduce a way how we can kill the main process of a service with KillSignal, but all processes with SIGKILL later on https://bugzilla.redhat.com/show_bug.cgi?id=952634 diff --git a/src/libsystemd-bus/sd-memfd.c b/src/libsystemd-bus/sd-memfd.c index 51b111e8b5..98a8e0893a 100644 --- a/src/libsystemd-bus/sd-memfd.c +++ b/src/libsystemd-bus/sd-memfd.c @@ -106,7 +106,7 @@ int sd_memfd_get_file(sd_memfd *m, FILE **f) { if (!f) return -EINVAL; - if (!m->fd) { + if (!m->f) { m->f = fdopen(m->fd, "r+"); if (!m->f) return -errno; diff --git a/src/libsystemd-bus/test-bus-memfd.c b/src/libsystemd-bus/test-bus-memfd.c index 4c5ae21a8c..4b22ea9a68 100644 --- a/src/libsystemd-bus/test-bus-memfd.c +++ b/src/libsystemd-bus/test-bus-memfd.c @@ -32,6 +32,7 @@ int main(int argc, char *argv[]) { char *s; uint64_t sz; int r, fd; + FILE *f; log_set_max_level(LOG_DEBUG); @@ -43,18 +44,31 @@ int main(int argc, char *argv[]) { assert_se(r >= 0); strcpy(s, "hallo"); - assert_se(munmap(s, 6) == 0); + + r = sd_memfd_set_sealed(m, 1); + assert_se(r == -EPERM); assert_se(write(sd_memfd_get_fd(m), "he", 2) == 2); + assert_se(write(sd_memfd_get_fd(m), "HE", 2) == 2); - r = sd_memfd_get_sealed(m); - assert_se(r == 0); + log_error("lseek = %llu", (unsigned long long) lseek(sd_memfd_get_fd(m), 0, SEEK_CUR)); - r = sd_memfd_set_sealed(m, 1); - assert_se(r >= 0); + log_info("<%s>", s); + + access("HUHU", F_OK); + + assert_se(sd_memfd_get_file(m, &f) >= 0); + fputc('L', f); + fflush(f); + + access("HAHA", F_OK); + + log_info("<%s>", s); + + assert_se(munmap(s, 6) == 0); r = sd_memfd_get_sealed(m); - assert_se(r == 1); + assert_se(r == 0); r = sd_memfd_get_size(m, &sz); assert_se(r >= 0); @@ -63,6 +77,12 @@ int main(int argc, char *argv[]) { r = sd_memfd_set_size(m, 6); assert_se(r >= 0); + r = sd_memfd_set_sealed(m, 1); + assert_se(r >= 0); + + r = sd_memfd_get_sealed(m); + assert_se(r == 1); + fd = sd_memfd_dup_fd(m); assert_se(fd >= 0); @@ -78,8 +98,21 @@ int main(int argc, char *argv[]) { r = sd_memfd_map(m, 0, 6, (void**) &s); assert_se(r >= 0); - assert_se(streq(s, "hello")); + r = sd_memfd_set_sealed(m, 1); + assert_se(r == -EALREADY); + + r = sd_memfd_set_sealed(m, 0); + assert_se(r == -EPERM); + + log_info("<%s>", s); + + assert_se(streq(s, "heLlo")); assert_se(munmap(s, 6) == 0); + r = sd_memfd_set_sealed(m, 0); + assert_se(r >= 0); + + sd_memfd_free(m); + return 0; } -- cgit v1.2.1 From 0d1b9a964746336bc7e493ee82ad6cf1bdf49dbb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 May 2013 19:15:55 +0200 Subject: bus: fix error check in memfd code --- src/libsystemd-bus/sd-memfd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsystemd-bus/sd-memfd.c b/src/libsystemd-bus/sd-memfd.c index 98a8e0893a..2712a26f66 100644 --- a/src/libsystemd-bus/sd-memfd.c +++ b/src/libsystemd-bus/sd-memfd.c @@ -43,7 +43,7 @@ int sd_memfd_new(sd_memfd **m) { return -EINVAL; kdbus = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC); - if (fd < 0) + if (kdbus < 0) return -errno; if (ioctl(kdbus, KDBUS_CMD_MEMFD_NEW, &fd) < 0) -- cgit v1.2.1 From 13019ef5ea284b03a74f25897a49fa5670974568 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 10 May 2013 19:58:05 +0200 Subject: bus: fix test-bus-memfd --- src/libsystemd-bus/bus-kernel.c | 8 ++++---- src/libsystemd-bus/kdbus.h | 2 +- src/libsystemd-bus/test-bus-memfd.c | 32 ++++++++++---------------------- 3 files changed, 15 insertions(+), 27 deletions(-) diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index aecf408645..3fb5822a8f 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -45,7 +45,7 @@ #define KDBUS_ITEM_HEADER_SIZE offsetof(struct kdbus_item, data) #define KDBUS_ITEM_SIZE(s) ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE) -#define KDBUS_BUFFER_SIZE (4*1024*1024) +#define KDBUS_POOL_SIZE (4*1024*1024) static int parse_unique_name(const char *s, uint64_t *id) { int r; @@ -292,7 +292,7 @@ int bus_kernel_take_fd(sd_bus *b) { return -EINVAL; if (!b->kdbus_buffer) { - b->kdbus_buffer = mmap(NULL, KDBUS_BUFFER_SIZE, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); + b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); if (b->kdbus_buffer == MAP_FAILED) { b->kdbus_buffer = NULL; return -errno; @@ -310,10 +310,10 @@ int bus_kernel_take_fd(sd_bus *b) { KDBUS_HELLO_ATTACH_SECLABEL| KDBUS_HELLO_ATTACH_AUDIT; - hello->items[0].type = KDBUS_HELLO_BUFFER; + hello->items[0].type = KDBUS_HELLO_POOL; hello->items[0].size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec); hello->items[0].vec.address = (uint64_t) b->kdbus_buffer; - hello->items[0].vec.size = KDBUS_BUFFER_SIZE; + hello->items[0].vec.size = KDBUS_POOL_SIZE; r = ioctl(b->input_fd, KDBUS_CMD_HELLO, hello); if (r < 0) diff --git a/src/libsystemd-bus/kdbus.h b/src/libsystemd-bus/kdbus.h index bb339ae69c..1f855b040b 100644 --- a/src/libsystemd-bus/kdbus.h +++ b/src/libsystemd-bus/kdbus.h @@ -237,7 +237,7 @@ enum { /* Items to append to struct kdbus_cmd_hello */ enum { KDBUS_HELLO_NULL, - KDBUS_HELLO_BUFFER, /* kdbus_vec, userspace supplied buffer to + KDBUS_HELLO_POOL, /* kdbus_vec, userspace supplied buffer to * place received messages */ }; diff --git a/src/libsystemd-bus/test-bus-memfd.c b/src/libsystemd-bus/test-bus-memfd.c index 4b22ea9a68..37e150a397 100644 --- a/src/libsystemd-bus/test-bus-memfd.c +++ b/src/libsystemd-bus/test-bus-memfd.c @@ -40,32 +40,22 @@ int main(int argc, char *argv[]) { if (r == -ENOENT) return EXIT_TEST_SKIP; - r = sd_memfd_map(m, 0, 6, (void**) &s); + r = sd_memfd_map(m, 0, 12, (void**) &s); assert_se(r >= 0); - strcpy(s, "hallo"); + strcpy(s, "----- world"); r = sd_memfd_set_sealed(m, 1); assert_se(r == -EPERM); assert_se(write(sd_memfd_get_fd(m), "he", 2) == 2); - assert_se(write(sd_memfd_get_fd(m), "HE", 2) == 2); - - log_error("lseek = %llu", (unsigned long long) lseek(sd_memfd_get_fd(m), 0, SEEK_CUR)); - - log_info("<%s>", s); - - access("HUHU", F_OK); + assert_se(write(sd_memfd_get_fd(m), "ll", 2) == 2); assert_se(sd_memfd_get_file(m, &f) >= 0); - fputc('L', f); + fputc('o', f); fflush(f); - access("HAHA", F_OK); - - log_info("<%s>", s); - - assert_se(munmap(s, 6) == 0); + assert_se(munmap(s, 12) == 0); r = sd_memfd_get_sealed(m); assert_se(r == 0); @@ -74,7 +64,7 @@ int main(int argc, char *argv[]) { assert_se(r >= 0); assert_se(sz = page_size()); - r = sd_memfd_set_size(m, 6); + r = sd_memfd_set_size(m, 12); assert_se(r >= 0); r = sd_memfd_set_sealed(m, 1); @@ -93,9 +83,9 @@ int main(int argc, char *argv[]) { r = sd_memfd_get_size(m, &sz); assert_se(r >= 0); - assert_se(sz = 6); + assert_se(sz = 12); - r = sd_memfd_map(m, 0, 6, (void**) &s); + r = sd_memfd_map(m, 0, 12, (void**) &s); assert_se(r >= 0); r = sd_memfd_set_sealed(m, 1); @@ -104,10 +94,8 @@ int main(int argc, char *argv[]) { r = sd_memfd_set_sealed(m, 0); assert_se(r == -EPERM); - log_info("<%s>", s); - - assert_se(streq(s, "heLlo")); - assert_se(munmap(s, 6) == 0); + assert_se(streq(s, "hello world")); + assert_se(munmap(s, 12) == 0); r = sd_memfd_set_sealed(m, 0); assert_se(r >= 0); -- cgit v1.2.1 From 8573e652d9ca9bd1fe90e80d5a6637d390758833 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 11 May 2013 14:48:24 +0200 Subject: bus: update test-bus-memfd --- src/libsystemd-bus/test-bus-memfd.c | 81 ++++++++++++++++++++++++++++++++++--- 1 file changed, 75 insertions(+), 6 deletions(-) diff --git a/src/libsystemd-bus/test-bus-memfd.c b/src/libsystemd-bus/test-bus-memfd.c index 37e150a397..3300470e0f 100644 --- a/src/libsystemd-bus/test-bus-memfd.c +++ b/src/libsystemd-bus/test-bus-memfd.c @@ -33,6 +33,9 @@ int main(int argc, char *argv[]) { uint64_t sz; int r, fd; FILE *f; + char buf[3] = {}; + struct iovec iov[3] = {}; + char bufv[3][3] = {}; log_set_max_level(LOG_DEBUG); @@ -49,12 +52,20 @@ int main(int argc, char *argv[]) { assert_se(r == -EPERM); assert_se(write(sd_memfd_get_fd(m), "he", 2) == 2); + assert_se(write(sd_memfd_get_fd(m), "XXX", 3) == 3); + assert_se(streq(s, "heXXX world")); + + /* fix "hello" */ + assert_se(lseek(sd_memfd_get_fd(m), 2, SEEK_SET) == 2); assert_se(write(sd_memfd_get_fd(m), "ll", 2) == 2); assert_se(sd_memfd_get_file(m, &f) >= 0); fputc('o', f); fflush(f); + /* check content */ + assert_se(streq(s, "hello world")); + assert_se(munmap(s, 12) == 0); r = sd_memfd_get_sealed(m); @@ -64,9 +75,15 @@ int main(int argc, char *argv[]) { assert_se(r >= 0); assert_se(sz = page_size()); - r = sd_memfd_set_size(m, 12); + /* truncate it */ + r = sd_memfd_set_size(m, 6); assert_se(r >= 0); + /* get back new value */ + r = sd_memfd_get_size(m, &sz); + assert_se(r >= 0); + assert_se(sz == 6); + r = sd_memfd_set_sealed(m, 1); assert_se(r >= 0); @@ -78,27 +95,79 @@ int main(int argc, char *argv[]) { sd_memfd_free(m); + /* new sd_memfd, same underlying memfd */ r = sd_memfd_make(fd, &m); assert_se(r >= 0); + /* we did truncate it to 6 */ r = sd_memfd_get_size(m, &sz); - assert_se(r >= 0); - assert_se(sz = 12); + assert_se(sz == 6); - r = sd_memfd_map(m, 0, 12, (void**) &s); + /* map it, check content */ + r = sd_memfd_map(m, 0, 12, (void **)&s); assert_se(r >= 0); + /* we only see the truncated size */ + assert_se(streq(s, "hello ")); + + /* it was already sealed */ r = sd_memfd_set_sealed(m, 1); assert_se(r == -EALREADY); + /* we cannot break the seal, it is mapped */ r = sd_memfd_set_sealed(m, 0); assert_se(r == -EPERM); - assert_se(streq(s, "hello world")); + /* unmap it; become the single owner */ assert_se(munmap(s, 12) == 0); + /* now we can do flip the sealing */ r = sd_memfd_set_sealed(m, 0); - assert_se(r >= 0); + assert_se(r == 0); + r = sd_memfd_get_sealed(m); + assert_se(r == 0); + + r = sd_memfd_set_sealed(m, 1); + assert_se(r == 0); + r = sd_memfd_get_sealed(m); + assert_se(r == 1); + + r = sd_memfd_set_sealed(m, 0); + assert_se(r == 0); + r = sd_memfd_get_sealed(m); + assert_se(r == 0); + + /* seek at 2, read() 2 bytes */ + assert_se(lseek(fd, 2, SEEK_SET) == 2); + assert_se(read(fd, buf, 2) == 2); + + /* check content */ + assert_se(memcmp(buf, "ll", 2) == 0); + + /* writev it out*/ + iov[0].iov_base = (char *)"ABC"; + iov[0].iov_len = 3; + iov[1].iov_base = (char *)"DEF"; + iov[1].iov_len = 3; + iov[2].iov_base = (char *)"GHI"; + iov[2].iov_len = 3; + assert_se(lseek(fd, 0, SEEK_SET) == 0); + assert_se(writev(fd, iov, 3) == 9); + + /* readv it back */ + iov[0].iov_base = bufv[0]; + iov[0].iov_len = 3; + iov[1].iov_base = bufv[1]; + iov[1].iov_len = 3; + iov[2].iov_base = bufv[2]; + iov[2].iov_len = 3; + assert_se(lseek(fd, 0, SEEK_SET) == 0); + assert_se(readv(fd, iov, 3) == 9); + + /* check content */ + assert_se(memcmp(bufv[0], "ABC", 3) == 0); + assert_se(memcmp(bufv[1], "DEF", 3) == 0); + assert_se(memcmp(bufv[2], "GHI", 3) == 0); sd_memfd_free(m); -- cgit v1.2.1 From a41f47abd349b55fc4077fbb69d5da7eb6663668 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Sat, 11 May 2013 13:35:38 -0700 Subject: Re-indent with spaces. --- src/core/condition.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/condition.c b/src/core/condition.c index 16cae6d23b..abed4e5bf0 100644 --- a/src/core/condition.c +++ b/src/core/condition.c @@ -162,10 +162,10 @@ static bool test_security(const char *parameter) { if (streq(parameter, "selinux")) return is_selinux_enabled() > 0; #endif - if (streq(parameter, "apparmor")) - return access("/sys/kernel/security/apparmor/", F_OK) == 0; - if (streq(parameter, "smack")) - return access("/sys/fs/smackfs", F_OK) == 0; + if (streq(parameter, "apparmor")) + return access("/sys/kernel/security/apparmor/", F_OK) == 0; + if (streq(parameter, "smack")) + return access("/sys/fs/smackfs", F_OK) == 0; return false; } -- cgit v1.2.1 From 9d995d54b54dcf9c776a0d88edad3b6aab3c36b5 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Sat, 11 May 2013 13:40:08 -0700 Subject: Add support for ConditionSecurity=ima Just as with SMACK, we don't really know if a policy has been loaded or not, as the policy interface is write-only. Assume therefore that if ima is present in securityfs that it is enabled. Update the man page to reflect that "ima" is a valid option now as well. --- TODO | 2 -- man/systemd.unit.xml | 5 +++-- src/core/condition.c | 2 ++ 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/TODO b/TODO index 8d4b937a5a..9b276746f1 100644 --- a/TODO +++ b/TODO @@ -456,8 +456,6 @@ Features: * ExecOnFailure=/usr/bin/foo -* ConditionSecurity= should learn about IMA and SMACK - * udev: - remove src/udev/udev-builtin-firmware.c (CONFIG_FW_LOADER_USER_HELPER=n) - move to LGPL diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index c56837a6e5..5ab988178d 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -983,9 +983,10 @@ ConditionSecurity= may be used to check whether the given security module is enabled on the - system. Currently the only recognized + system. Currently the recognized values values are selinux, - apparmor, and + apparmor, + ima and smack. The test may be negated by prepending an exclamation diff --git a/src/core/condition.c b/src/core/condition.c index abed4e5bf0..4293d6d1f1 100644 --- a/src/core/condition.c +++ b/src/core/condition.c @@ -164,6 +164,8 @@ static bool test_security(const char *parameter) { #endif if (streq(parameter, "apparmor")) return access("/sys/kernel/security/apparmor/", F_OK) == 0; + if (streq(parameter, "ima")) + return access("/sys/kernel/security/ima/", F_OK) == 0; if (streq(parameter, "smack")) return access("/sys/fs/smackfs", F_OK) == 0; return false; -- cgit v1.2.1 From 18cd014f13cb988037acc16f8150b8f6d7042cd5 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 12 May 2013 20:11:03 +0200 Subject: bus: remove KDBUS_MAKE_ACCESS_WORLD, remove (n_payload > 2) check KDBUS_MAKE_ACCESS_WORLD is no longer needed, the kernel creates the kdbus device node with the uid/gid of the caller now. --- src/libsystemd-bus/bus-kernel.c | 16 +++++++++------- src/libsystemd-bus/kdbus.h | 8 +++----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index 3fb5822a8f..e329b14be8 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -72,7 +72,7 @@ static void append_payload_vec(struct kdbus_item **d, const void *p, size_t sz) (*d)->size = offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec); (*d)->type = KDBUS_MSG_PAYLOAD_VEC; - (*d)->vec.address = (intptr_t) p; + (*d)->vec.address = (uint64_t) p; (*d)->vec.size = sz; *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size); @@ -436,7 +436,7 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess if (d->vec.size < sizeof(struct bus_header)) return -EBADMSG; - h = (struct bus_header*) d->vec.address; + h = (struct bus_header*)(uintptr_t) d->vec.address; } n_payload++; @@ -471,8 +471,8 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess if (n_bytes != total) return -EBADMSG; - if (n_payload > 2) - return -EBADMSG; + //if (n_payload > 2) + // return -EBADMSG; r = bus_message_from_header(h, sizeof(struct bus_header), fds, n_fds, NULL, seclabel, 0, &m); if (r < 0) @@ -485,8 +485,10 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess if (d->type == KDBUS_MSG_PAYLOAD_VEC) { - range_contains(idx, d->vec.size, ALIGN8(sizeof(struct bus_header)), BUS_MESSAGE_FIELDS_SIZE(m), (void*) d->vec.address, &m->fields); - range_contains(idx, d->vec.size, ALIGN8(sizeof(struct bus_header)) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m)), BUS_MESSAGE_BODY_SIZE(m), (void*) d->vec.address, &m->body); + range_contains(idx, d->vec.size, ALIGN8(sizeof(struct bus_header)), BUS_MESSAGE_FIELDS_SIZE(m), + (void *)(uintptr_t) d->vec.address, &m->fields); + range_contains(idx, d->vec.size, ALIGN8(sizeof(struct bus_header)) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m)), + BUS_MESSAGE_BODY_SIZE(m), (void *)(uintptr_t) d->vec.address, &m->body); idx += d->vec.size; @@ -624,7 +626,7 @@ int bus_kernel_create(const char *name, char **s) { n->size = KDBUS_ITEM_HEADER_SIZE + strlen(n->str) + 1; make->size = offsetof(struct kdbus_cmd_bus_make, items) + cg->size + n->size; - make->flags = KDBUS_MAKE_ACCESS_WORLD | KDBUS_MAKE_POLICY_OPEN; + make->flags = KDBUS_MAKE_POLICY_OPEN; make->bus_flags = 0; make->bloom_size = BLOOM_SIZE; assert_cc(BLOOM_SIZE % 8 == 0); diff --git a/src/libsystemd-bus/kdbus.h b/src/libsystemd-bus/kdbus.h index 1f855b040b..9dd28a71c2 100644 --- a/src/libsystemd-bus/kdbus.h +++ b/src/libsystemd-bus/kdbus.h @@ -214,7 +214,7 @@ struct kdbus_policy { struct kdbus_cmd_policy { __u64 size; - __u8 buffer[0]; /* a series of KDBUS_POLICY_NAME plus one or + __u8 data[0]; /* a series of KDBUS_POLICY_NAME plus one or * more KDBUS_POLICY_ACCESS each. */ }; @@ -237,7 +237,7 @@ enum { /* Items to append to struct kdbus_cmd_hello */ enum { KDBUS_HELLO_NULL, - KDBUS_HELLO_POOL, /* kdbus_vec, userspace supplied buffer to + KDBUS_HELLO_POOL, /* kdbus_vec, userspace supplied pool to * place received messages */ }; @@ -419,10 +419,8 @@ enum kdbus_cmd { /* kdbus ep node commands: require ep owner state */ KDBUS_CMD_EP_POLICY_SET = _IOWR(KDBUS_IOC_MAGIC, 0x70, struct kdbus_cmd_policy), - /* kdbus ep node commands: */ - KDBUS_CMD_MEMFD_NEW = _IOWR(KDBUS_IOC_MAGIC, 0x80, int *), - /* kdbus memfd commands: */ + KDBUS_CMD_MEMFD_NEW = _IOWR(KDBUS_IOC_MAGIC, 0x80, int *), KDBUS_CMD_MEMFD_SIZE_GET = _IOWR(KDBUS_IOC_MAGIC, 0x81, __u64 *), KDBUS_CMD_MEMFD_SIZE_SET = _IOWR(KDBUS_IOC_MAGIC, 0x82, __u64 *), KDBUS_CMD_MEMFD_SEAL_GET = _IOWR(KDBUS_IOC_MAGIC, 0x83, int *), -- cgit v1.2.1 From c8150fa751ac4490583d1b2c8688a73edb7cd76c Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 13 May 2013 05:56:31 +0200 Subject: bus: update test-bus-memfd --- src/libsystemd-bus/kdbus.h | 1 + src/libsystemd-bus/test-bus-memfd.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libsystemd-bus/kdbus.h b/src/libsystemd-bus/kdbus.h index 9dd28a71c2..20b804539b 100644 --- a/src/libsystemd-bus/kdbus.h +++ b/src/libsystemd-bus/kdbus.h @@ -138,6 +138,7 @@ struct kdbus_item { struct kdbus_timestamp timestamp; /* specific fields */ + struct kdbus_memfd memfd; int fds[0]; struct kdbus_manager_msg_name_change name_change; struct kdbus_manager_msg_id_change id_change; diff --git a/src/libsystemd-bus/test-bus-memfd.c b/src/libsystemd-bus/test-bus-memfd.c index 3300470e0f..db199d46db 100644 --- a/src/libsystemd-bus/test-bus-memfd.c +++ b/src/libsystemd-bus/test-bus-memfd.c @@ -49,7 +49,7 @@ int main(int argc, char *argv[]) { strcpy(s, "----- world"); r = sd_memfd_set_sealed(m, 1); - assert_se(r == -EPERM); + assert_se(r == -ETXTBSY); assert_se(write(sd_memfd_get_fd(m), "he", 2) == 2); assert_se(write(sd_memfd_get_fd(m), "XXX", 3) == 3); @@ -116,7 +116,7 @@ int main(int argc, char *argv[]) { /* we cannot break the seal, it is mapped */ r = sd_memfd_set_sealed(m, 0); - assert_se(r == -EPERM); + assert_se(r == -ETXTBSY); /* unmap it; become the single owner */ assert_se(munmap(s, 12) == 0); -- cgit v1.2.1 From 9976dcb2f6ed34ae9b54015b75906634ed4b44d8 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 13 May 2013 15:12:25 +0200 Subject: bus: test-bus-memfd - use pread()/pwrite() --- src/libsystemd-bus/test-bus-memfd.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/libsystemd-bus/test-bus-memfd.c b/src/libsystemd-bus/test-bus-memfd.c index db199d46db..05ef555f0d 100644 --- a/src/libsystemd-bus/test-bus-memfd.c +++ b/src/libsystemd-bus/test-bus-memfd.c @@ -20,6 +20,7 @@ ***/ #include +#include #include "log.h" #include "macro.h" @@ -151,8 +152,7 @@ int main(int argc, char *argv[]) { iov[1].iov_len = 3; iov[2].iov_base = (char *)"GHI"; iov[2].iov_len = 3; - assert_se(lseek(fd, 0, SEEK_SET) == 0); - assert_se(writev(fd, iov, 3) == 9); + assert_se(pwritev(fd, iov, 3, 0) == 9); /* readv it back */ iov[0].iov_base = bufv[0]; @@ -161,8 +161,7 @@ int main(int argc, char *argv[]) { iov[1].iov_len = 3; iov[2].iov_base = bufv[2]; iov[2].iov_len = 3; - assert_se(lseek(fd, 0, SEEK_SET) == 0); - assert_se(readv(fd, iov, 3) == 9); + assert_se(preadv(fd, iov, 3, 0) == 9); /* check content */ assert_se(memcmp(bufv[0], "ABC", 3) == 0); -- cgit v1.2.1 From 32821c76d5901276e2fc8635202dde088268a65f Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 13 May 2013 22:21:54 +0200 Subject: TODO: add "debug" kernel cmdline switch --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index 9b276746f1..6fa88255a7 100644 --- a/TODO +++ b/TODO @@ -28,6 +28,8 @@ Fedora 19: - localectl: support new converted x11→console keymaps Features: +* read the kernel's console "debug" keyword like we read "quiet" and adjust: + systemd.log_level=debug and maybe systemd.log_target=kmsg * maybe add "journalctl -k" as shortcut for "-b _TRANSPORT=kernel" -- cgit v1.2.1 From 8060a8b32d9f0c6244dfb6814fb0e339475bcd98 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Mon, 13 May 2013 14:40:55 -0700 Subject: journald-stream: typo in error message. --- src/journal/journald-stream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c index 6d51c29083..3ce1c9ac47 100644 --- a/src/journal/journald-stream.c +++ b/src/journal/journald-stream.c @@ -440,7 +440,7 @@ int server_open_stdout_socket(Server *s) { chmod(sa.un.sun_path, 0666); if (listen(s->stdout_fd, SOMAXCONN) < 0) { - log_error("liste() failed: %m"); + log_error("listen() failed: %m"); return -errno; } } else -- cgit v1.2.1 From 7e853a9b9a858edbc24e6c85d134478cec840173 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 14 May 2013 14:01:20 +0200 Subject: update TODO --- TODO | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/TODO b/TODO index 6fa88255a7..62016e1e43 100644 --- a/TODO +++ b/TODO @@ -31,6 +31,11 @@ Features: * read the kernel's console "debug" keyword like we read "quiet" and adjust: systemd.log_level=debug and maybe systemd.log_target=kmsg +* add an option to nspawn that uses seccomp to make socket(AF_NETLINK, + SOCK_RAW, NETLINK_AUDIT) fail the the appropriate error code that + makes the audit userspace to think auditing is not available in the + kernel. + * maybe add "journalctl -k" as shortcut for "-b _TRANSPORT=kernel" * Introduce a way how we can kill the main process of a service with KillSignal, but all processes with SIGKILL later on -- cgit v1.2.1 From a3dc35472f3a48ea8445ad7a943e2ff253170417 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 14 May 2013 16:13:52 +0200 Subject: bus: add and use UINT64_TO_PTR() --- src/libsystemd-bus/bus-kernel.c | 6 +++--- src/shared/macro.h | 26 ++++++++++++++------------ 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index e329b14be8..071f2b9708 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -436,7 +436,7 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess if (d->vec.size < sizeof(struct bus_header)) return -EBADMSG; - h = (struct bus_header*)(uintptr_t) d->vec.address; + h = (struct bus_header*)UINT64_TO_PTR(d->vec.address); } n_payload++; @@ -486,9 +486,9 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess if (d->type == KDBUS_MSG_PAYLOAD_VEC) { range_contains(idx, d->vec.size, ALIGN8(sizeof(struct bus_header)), BUS_MESSAGE_FIELDS_SIZE(m), - (void *)(uintptr_t) d->vec.address, &m->fields); + UINT64_TO_PTR(d->vec.address), &m->fields); range_contains(idx, d->vec.size, ALIGN8(sizeof(struct bus_header)) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m)), - BUS_MESSAGE_BODY_SIZE(m), (void *)(uintptr_t) d->vec.address, &m->body); + BUS_MESSAGE_BODY_SIZE(m), UINT64_TO_PTR(d->vec.address), &m->body); idx += d->vec.size; diff --git a/src/shared/macro.h b/src/shared/macro.h index 0874102ece..2f151bcc8c 100644 --- a/src/shared/macro.h +++ b/src/shared/macro.h @@ -159,23 +159,25 @@ static inline size_t ALIGN_TO(size_t l, size_t ali) { } while (false) #endif +#define PTR_TO_INT(p) ((int) ((intptr_t) (p))) +#define INT_TO_PTR(u) ((void *) ((intptr_t) (u))) #define PTR_TO_UINT(p) ((unsigned int) ((uintptr_t) (p))) -#define UINT_TO_PTR(u) ((void*) ((uintptr_t) (u))) - -#define PTR_TO_UINT32(p) ((uint32_t) ((uintptr_t) (p))) -#define UINT32_TO_PTR(u) ((void*) ((uintptr_t) (u))) +#define UINT_TO_PTR(u) ((void *) ((uintptr_t) (u))) +#define PTR_TO_LONG(p) ((long) ((intptr_t) (p))) +#define LONG_TO_PTR(u) ((void *) ((intptr_t) (u))) #define PTR_TO_ULONG(p) ((unsigned long) ((uintptr_t) (p))) -#define ULONG_TO_PTR(u) ((void*) ((uintptr_t) (u))) +#define ULONG_TO_PTR(u) ((void *) ((uintptr_t) (u))) -#define PTR_TO_INT(p) ((int) ((intptr_t) (p))) -#define INT_TO_PTR(u) ((void*) ((intptr_t) (u))) - -#define TO_INT32(p) ((int32_t) ((intptr_t) (p))) -#define INT32_TO_PTR(u) ((void*) ((intptr_t) (u))) +#define PTR_TO_INT32(p) ((int32_t) ((intptr_t) (p))) +#define INT32_TO_PTR(u) ((void *) ((intptr_t) (u))) +#define PTR_TO_UINT32(p) ((uint32_t) ((uintptr_t) (p))) +#define UINT32_TO_PTR(u) ((void *) ((uintptr_t) (u))) -#define PTR_TO_LONG(p) ((long) ((intptr_t) (p))) -#define LONG_TO_PTR(u) ((void*) ((intptr_t) (u))) +#define PTR_TO_INT64(p) ((int64_t) ((intptr_t) (p))) +#define INT64_TO_PTR(u) ((void *) ((intptr_t) (u))) +#define PTR_TO_UINT64(p) ((uint64_t) ((uintptr_t) (p))) +#define UINT64_TO_PTR(u) ((void *) ((uintptr_t) (u))) #define memzero(x,l) (memset((x), 0, (l))) #define zero(x) (memzero(&(x), sizeof(x))) -- cgit v1.2.1 From bc7fd8cdbef54ebd3902cdd455ecad3e095f7450 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 14 May 2013 22:24:26 +0200 Subject: bus: properly handle message bodies that are a chain of memory areas rather than a single one --- src/libsystemd-bus/bus-internal.h | 4 + src/libsystemd-bus/bus-kernel.c | 120 ++++++++- src/libsystemd-bus/bus-kernel.h | 14 + src/libsystemd-bus/bus-message.c | 548 ++++++++++++++++++++++++++++---------- src/libsystemd-bus/bus-message.h | 26 +- src/libsystemd-bus/bus-socket.c | 50 +++- src/libsystemd-bus/sd-bus.c | 3 +- 7 files changed, 596 insertions(+), 169 deletions(-) diff --git a/src/libsystemd-bus/bus-internal.h b/src/libsystemd-bus/bus-internal.h index 05184fd560..504dac7f09 100644 --- a/src/libsystemd-bus/bus-internal.h +++ b/src/libsystemd-bus/bus-internal.h @@ -33,6 +33,7 @@ #include "sd-bus.h" #include "bus-error.h" #include "bus-match.h" +#include "bus-kernel.h" struct reply_callback { sd_bus_message_handler_t callback; @@ -152,6 +153,9 @@ struct sd_bus { unsigned iteration_counter; void *kdbus_buffer; + + struct memfd_cache memfd_cache[MEMFD_CACHE_MAX]; + unsigned n_memfd_cache; }; static inline void bus_unrefp(sd_bus **b) { diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index 071f2b9708..b11df300b6 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -189,6 +189,7 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) { uint64_t unique; size_t sz, dl; int r; + struct bus_body_part *part; assert(b); assert(m); @@ -209,7 +210,8 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) { sz = offsetof(struct kdbus_msg, items); /* Add in fixed header, fields header and payload */ - sz += 3 * ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec)); + sz += (1 + !!m->fields + m->n_body_parts) * + ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec)); /* Add space for bloom filter */ sz += ALIGN8(offsetof(struct kdbus_item, data) + BLOOM_SIZE); @@ -251,8 +253,8 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) { if (m->fields) append_payload_vec(&d, m->fields, ALIGN8(m->header->fields_size)); - if (m->body) - append_payload_vec(&d, m->body, m->header->body_size); + for (part = &m->body; part && part->size > 0; part = part->next) + append_payload_vec(&d, part->data, part->size); if (m->kdbus->dst_id == KDBUS_DST_ID_BROADCAST) { void *p; @@ -395,7 +397,10 @@ static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) { } } -static bool range_contains(size_t astart, size_t asize, size_t bstart, size_t bsize, void *a, void **b) { +static bool range_contains( + size_t astart, size_t asize, + size_t bstart, size_t bsize, + void *a, void **b) { if (bstart < astart) return false; @@ -484,11 +489,35 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess l = d->size - offsetof(struct kdbus_item, data); if (d->type == KDBUS_MSG_PAYLOAD_VEC) { + size_t begin_body; + /* Fill in fields material */ range_contains(idx, d->vec.size, ALIGN8(sizeof(struct bus_header)), BUS_MESSAGE_FIELDS_SIZE(m), UINT64_TO_PTR(d->vec.address), &m->fields); - range_contains(idx, d->vec.size, ALIGN8(sizeof(struct bus_header)) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m)), - BUS_MESSAGE_BODY_SIZE(m), UINT64_TO_PTR(d->vec.address), &m->body); + + begin_body = ALIGN8(sizeof(struct bus_header)) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m)); + + if (idx + d->vec.size > begin_body) { + struct bus_body_part *part; + + /* Contains body material */ + + part = message_append_part(m); + if (!part) { + sd_bus_message_unref(m); + return -ENOMEM; + } + + if (idx >= begin_body) { + part->data = (void*) d->vec.address; + part->size = d->vec.size; + } else { + part->data = (uint8_t*) (uintptr_t) d->vec.address + (begin_body - idx); + part->size = d->vec.size - (begin_body - idx); + } + + part->sealed = true; + } idx += d->vec.size; @@ -524,8 +553,7 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess log_debug("Got unknown field from kernel %llu", d->type); } - if ((BUS_MESSAGE_FIELDS_SIZE(m) > 0 && !m->fields) || - (BUS_MESSAGE_BODY_SIZE(m) > 0 && !m->body)) { + if ((BUS_MESSAGE_FIELDS_SIZE(m) > 0 && !m->fields) || BUS_MESSAGE_SIZE(m) != idx) { sd_bus_message_unref(m); return -EBADMSG; } @@ -646,3 +674,79 @@ int bus_kernel_create(const char *name, char **s) { return fd; } + +int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) { + struct memfd_cache *c; + + assert(address); + assert(size); + + if (!bus || !bus->is_kernel) + return -ENOTSUP; + + if (bus->n_memfd_cache <= 0) { + int fd; + + fd = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, &fd); + if (fd < 0) + return -errno; + + *address = NULL; + *size = 0; + return fd; + } + + c = &bus->memfd_cache[-- bus->n_memfd_cache]; + + assert(c->fd >= 0); + assert(c->size == 0 || c->address); + + *address = c->address; + *size = c->size; + + return c->fd; +} + +void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) { + struct memfd_cache *c; + + assert(fd >= 0); + assert(size == 0 || address); + + if (!bus || !bus->is_kernel || + bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) { + + if (size > 0) + assert_se(munmap(address, PAGE_ALIGN(size)) == 0); + + close_nointr_nofail(fd); + return; + } + + c = &bus->memfd_cache[bus->n_memfd_cache++]; + c->fd = fd; + c->address = address; + + /* If overly long, let's return a bit to the OS */ + if (size > MEMFD_CACHE_ITEM_SIZE_MAX) { + uint64_t sz = MEMFD_CACHE_ITEM_SIZE_MAX; + + ioctl(bus->input_fd, KDBUS_CMD_MEMFD_SIZE_SET, &sz); + + c->size = MEMFD_CACHE_ITEM_SIZE_MAX; + } else + c->size = size; +} + +void bus_kernel_flush_memfd(sd_bus *b) { + unsigned i; + + assert(b); + + for (i = 0; i < b->n_memfd_cache; i++) { + if (b->memfd_cache[i].size > 0) + assert_se(munmap(b->memfd_cache[i].address, PAGE_ALIGN(b->memfd_cache[i].size)) == 0); + + close_nointr_nofail(b->memfd_cache[i].fd); + } +} diff --git a/src/libsystemd-bus/bus-kernel.h b/src/libsystemd-bus/bus-kernel.h index ac746afe03..ed3f987ccd 100644 --- a/src/libsystemd-bus/bus-kernel.h +++ b/src/libsystemd-bus/bus-kernel.h @@ -23,6 +23,15 @@ #include "sd-bus.h" +#define MEMFD_CACHE_MAX 32 +#define MEMFD_CACHE_ITEM_SIZE_MAX (128*1024) + +struct memfd_cache { + int fd; + void *address; + size_t size; +}; + int bus_kernel_connect(sd_bus *b); int bus_kernel_take_fd(sd_bus *b); @@ -30,3 +39,8 @@ int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m); int bus_kernel_read_message(sd_bus *bus, sd_bus_message **m); int bus_kernel_create(const char *name, char **s); + +int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size); +void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size); + +void bus_kernel_flush_memfd(sd_bus *bus); diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c index cc2b78a8c5..7444a30a51 100644 --- a/src/libsystemd-bus/bus-message.c +++ b/src/libsystemd-bus/bus-message.c @@ -21,6 +21,7 @@ #include #include +#include #include "util.h" #include "utf8.h" @@ -36,7 +37,65 @@ static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored); -static void reset_containers(sd_bus_message *m) { +static void *adjust_pointer(const void *p, void *old_base, size_t sz, void *new_base) { + + if (p == NULL) + return NULL; + + if (old_base == new_base) + return (void*) p; + + if ((uint8_t*) p < (uint8_t*) old_base) + return (void*) p; + + if ((uint8_t*) p >= (uint8_t*) old_base + sz) + return (void*) p; + + return (uint8_t*) new_base + ((uint8_t*) p - (uint8_t*) old_base); +} + +static void message_free_part(sd_bus_message *m, struct bus_body_part *part) { + assert(m); + assert(part); + + if (part->memfd >= 0) { + + if (!part->sealed) + bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped); + else { + if (part->size > 0) + assert_se(munmap(part->data, PAGE_ALIGN(part->size)) == 0); + + close_nointr_nofail(part->memfd); + } + + } else if (part->free_this) + free(part->data); + + if (part != &m->body) + free(part); +} + +static void message_reset_parts(sd_bus_message *m) { + struct bus_body_part *part; + + assert(m); + + part = &m->body; + while (m->n_body_parts > 0) { + struct bus_body_part *next = part->next; + message_free_part(m, part); + part = next; + m->n_body_parts--; + } + + m->body_end = NULL; + + m->cached_rindex_part = NULL; + m->cached_rindex_part_begin = 0; +} + +static void message_reset_containers(sd_bus_message *m) { unsigned i; assert(m); @@ -60,8 +119,7 @@ static void message_free(sd_bus_message *m) { if (m->free_fields) free(m->fields); - if (m->free_body) - free(m->body); + message_reset_parts(m); if (m->free_kdbus) free(m->kdbus); @@ -77,9 +135,12 @@ static void message_free(sd_bus_message *m) { if (m->bus) sd_bus_unref(m->bus); + if (m->iovec != m->iovec_fixed) + free(m->iovec); + free(m->cmdline_array); - reset_containers(m); + message_reset_containers(m); free(m->root_container.signature); free(m->peeked_signature); @@ -91,7 +152,7 @@ static void message_free(sd_bus_message *m) { } static void* buffer_extend(void **p, uint32_t *sz, size_t align, size_t extend) { - size_t start, n; + size_t start, end; void *k; assert(p); @@ -99,15 +160,15 @@ static void* buffer_extend(void **p, uint32_t *sz, size_t align, size_t extend) assert(align > 0); start = ALIGN_TO((size_t) *sz, align); - n = start + extend; + end = start + extend; - if (n == *sz) + if (end == *sz) return (uint8_t*) *p + start; - if (n > (size_t) ((uint32_t) -1)) + if (end > (size_t) ((uint32_t) -1)) return NULL; - k = realloc(*p, n); + k = realloc(*p, end); if (!k) return NULL; @@ -116,38 +177,37 @@ static void* buffer_extend(void **p, uint32_t *sz, size_t align, size_t extend) memset((uint8_t*) k + *sz, 0, start - *sz); *p = k; - *sz = n; + *sz = end; return (uint8_t*) k + start; } static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) { - void *p, *o; + void *p, *op; + size_t os; assert(m); - o = m->fields; - p = buffer_extend(&m->fields, &m->header->fields_size, align, sz); - if (!p) + if (m->poisoned) return NULL; - if (o != m->fields) { - /* Adjust quick access pointers */ - - if (m->path) - m->path = (const char*) m->fields + (m->path - (const char*) o); - if (m->interface) - m->interface = (const char*) m->fields + (m->interface - (const char*) o); - if (m->member) - m->member = (const char*) m->fields + (m->member - (const char*) o); - if (m->destination) - m->destination = (const char*) m->fields + (m->destination - (const char*) o); - if (m->sender) - m->sender = (const char*) m->fields + (m->sender - (const char*) o); - if (m->error.name) - m->error.name = (const char*) m->fields + (m->error.name - (const char*) o); + op = m->fields; + os = m->header->fields_size; + + p = buffer_extend(&m->fields, &m->header->fields_size, align, sz); + if (!p) { + m->poisoned = true; + return NULL; } + /* Adjust quick access pointers */ + m->path = adjust_pointer(m->path, op, os, m->fields); + m->interface = adjust_pointer(m->interface, op, os, m->fields); + m->member = adjust_pointer(m->member, op, os, m->fields); + m->destination = adjust_pointer(m->destination, op, os, m->fields); + m->sender = adjust_pointer(m->sender, op, os, m->fields); + m->error.name = adjust_pointer(m->error.name, op, os, m->fields); + m->free_fields = true; return p; @@ -183,7 +243,7 @@ static int message_append_field_string( memcpy(p + 8, s, l + 1); if (ret) - *ret = (const char*) p + 8; + *ret = (char*) p + 8; return 0; } @@ -331,9 +391,15 @@ int bus_message_from_malloc( } m->fields = (uint8_t*) buffer + sizeof(struct bus_header); - m->body = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m)); + + m->n_body_parts = 1; + m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m)); + m->body.size = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m)); + m->body.sealed = true; + m->body.memfd = -1; m->n_iovec = 1; + m->iovec = m->iovec_fixed; m->iovec[0].iov_base = buffer; m->iovec[0].iov_len = length; @@ -1022,35 +1088,188 @@ static struct bus_container *message_get_container(sd_bus_message *m) { return m->containers + m->n_containers - 1; } +struct bus_body_part *message_append_part(sd_bus_message *m) { + struct bus_body_part *part; + + assert(m); + + if (m->poisoned) + return NULL; + + if (m->n_body_parts <= 0) { + part = &m->body; + zero(*part); + } else { + assert(m->body_end); + + part = new0(struct bus_body_part, 1); + if (!part) { + m->poisoned = true; + return NULL; + } + + m->body_end->next = part; + } + + part->memfd = -1; + m->body_end = part; + m->n_body_parts ++; + + return part; +} + +static void part_zero(struct bus_body_part *part, size_t sz) { + assert(part); + assert(sz > 0); + assert(sz < 8); + + part->data = NULL; + part->size = sz; +} + +static int part_make_space( + struct sd_bus_message *m, + struct bus_body_part *part, + size_t sz, + void **q) { + + void *n; + int r; + + assert(m); + assert(part); + assert(!part->sealed); + + if (m->poisoned) + return -ENOMEM; + + if (!part->data && part->memfd < 0) + part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped); + + if (part->memfd >= 0) { + uint64_t u = sz; + + r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u); + if (r < 0) { + m->poisoned = true; + return -errno; + } + + if (sz > part->mapped) { + size_t psz = PAGE_ALIGN(sz); + + if (part->mapped <= 0) + n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0); + else + n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE); + + if (n == MAP_FAILED) { + m->poisoned = true; + return -errno; + } + + part->mapped = psz; + part->data = n; + } + } else { + n = realloc(part->data, sz); + if (!n) { + m->poisoned = true; + return -ENOMEM; + } + + part->data = n; + part->free_this = true; + } + + if (q) + *q = part->data ? (uint8_t*) part->data + part->size : NULL; + + part->size = sz; + return 0; +} + static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) { - void *p, *o; - size_t added; struct bus_container *c; + struct bus_body_part *part = NULL; + size_t start_body, end_body, padding, start_part, end_part, added; + bool add_new_part; + void *p; + int r; assert(m); assert(align > 0); + assert(!m->sealed); - o = m->body; - added = m->header->body_size; + if (m->poisoned) + return NULL; - p = buffer_extend(&m->body, &m->header->body_size, align, sz); - if (!p) + start_body = ALIGN_TO((size_t) m->header->body_size, align); + end_body = start_body + sz; + + padding = start_body - m->header->body_size; + added = padding + sz; + + /* Check for 32bit overflows */ + if (end_body > (size_t) ((uint32_t) -1)) { + m->poisoned = true; return NULL; + } - added = m->header->body_size - added; + add_new_part = + m->n_body_parts <= 0 || + m->body_end->sealed || + padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size; - for (c = m->containers; c < m->containers + m->n_containers; c++) - if (c->array_size) { - c->array_size = (uint32_t*) ((uint8_t*) m->body + ((uint8_t*) c->array_size - (uint8_t*) o)); - *c->array_size += added; + if (add_new_part) { + if (padding > 0) { + part = message_append_part(m); + if (!part) + return NULL; + + part_zero(part, padding); + } + + part = message_append_part(m); + if (!part) + return NULL; + + r = part_make_space(m, part, sz, &p); + if (r < 0) + return NULL; + } else { + void *op; + size_t os; + + part = m->body_end; + op = part->data; + os = part->size; + + start_part = ALIGN_TO(part->size, align); + end_part = start_part + sz; + + r = part_make_space(m, part, end_part, &p); + if (r < 0) + return NULL; + + if (padding > 0) { + memset(p, 0, padding); + p = (uint8_t*) p + padding; } - if (o != m->body) { - if (m->error.message) - m->error.message = (const char*) m->body + (m->error.message - (const char*) o); + /* Readjust pointers */ + for (c = m->containers; c < m->containers + m->n_containers; c++) + c->array_size = adjust_pointer(c->array_size, op, os, part->data); + + m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data); } - m->free_body = true; + /* Update counters */ + for (c = m->containers; c < m->containers + m->n_containers; c++) + if (c->array_size) + *c->array_size += added; + + m->header->body_size = end_body; return p; } @@ -1073,6 +1292,8 @@ int message_append_basic(sd_bus_message *m, char type, const void *p, const void return -EPERM; if (!bus_type_is_basic(type)) return -EINVAL; + if (m->poisoned) + return -ESTALE; c = message_get_container(m); @@ -1087,8 +1308,10 @@ int message_append_basic(sd_bus_message *m, char type, const void *p, const void return -ENXIO; e = strextend(&c->signature, CHAR_TO_STR(type), NULL); - if (!e) + if (!e) { + m->poisoned = true; return -ENOMEM; + } } switch (type) { @@ -1139,6 +1362,7 @@ int message_append_basic(sd_bus_message *m, char type, const void *p, const void f = realloc(m->fds, sizeof(int) * (m->n_fds + 1)); if (!f) { + m->poisoned = true; r = -ENOMEM; goto fail; } @@ -1199,10 +1423,6 @@ int message_append_basic(sd_bus_message *m, char type, const void *p, const void return 0; fail: - /* Truncate extended signature again */ - if (e) - c->signature[c->index] = 0; - if (fd >= 0) close_nointr_nofail(fd); @@ -1217,7 +1437,6 @@ int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) struct bus_container *c; char *e; void *a; - int r; if (!m) return -EINVAL; @@ -1225,6 +1444,8 @@ int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) return -EINVAL; if (m->sealed) return -EPERM; + if (m->poisoned) + return -ESTALE; c = message_get_container(m); @@ -1239,16 +1460,16 @@ int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) return -ENXIO; e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL); - if (!e) + if (!e) { + m->poisoned = true; return -ENOMEM; + } } a = message_extend_body(m, 4, 4 + size + 1); - if (!a) { - r = -ENOMEM; - goto fail; - } + if (!a) + return -ENOMEM; *(uint32_t*) a = size; *s = (char*) a + 4; @@ -1259,12 +1480,6 @@ int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) c->index++; return 0; - -fail: - if (e) - c->signature[c->index] = 0; - - return r; } static int bus_message_open_array( @@ -1275,9 +1490,10 @@ static int bus_message_open_array( unsigned nindex; char *e = NULL; - void *a, *b; + void *a, *op; int alignment; - size_t saved; + size_t os; + struct bus_body_part *o; assert(m); assert(c); @@ -1309,39 +1525,34 @@ static int bus_message_open_array( /* Extend the existing signature */ e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL); - if (!e) + if (!e) { + m->poisoned = true; return -ENOMEM; + } nindex = e - c->signature; } - saved = m->header->body_size; a = message_extend_body(m, 4, 4); - if (!a) { - /* Truncate extended signature again */ - if (e) - c->signature[c->index] = 0; - + if (!a) return -ENOMEM; - } - b = m->body; - if (!message_extend_body(m, alignment, 0)) { - /* Add alignment between size and first element */ - if (e) - c->signature[c->index] = 0; + o = m->body_end; + op = m->body_end->data; + os = m->body_end->size; - m->header->body_size = saved; + /* Add alignment between size and first element */ + if (!message_extend_body(m, alignment, 0)) return -ENOMEM; - } if (c->enclosing != SD_BUS_TYPE_ARRAY) c->index = nindex; - /* m->body might have changed so let's readjust a */ - a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b); - *(uint32_t*) a = 0; + /* location of array size might have changed so let's readjust a */ + if (o == m->body_end) + a = adjust_pointer(a, op, os, m->body_end->data); + *(uint32_t*) a = 0; *array_size = a; return 0; } @@ -1375,19 +1586,16 @@ static int bus_message_open_variant( return -ENXIO; e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL); - if (!e) + if (!e) { + m->poisoned = true; return -ENOMEM; + } } l = strlen(contents); a = message_extend_body(m, 1, 1 + l + 1); - if (!a) { - /* Truncate extended signature again */ - if (e) - c->signature[c->index] = 0; - + if (!a) return -ENOMEM; - } *(uint8_t*) a = l; memcpy((uint8_t*) a + 1, contents, l + 1); @@ -1429,19 +1637,17 @@ static int bus_message_open_struct( return -ENXIO; e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL); - if (!e) + if (!e) { + m->poisoned = true; return -ENOMEM; + } nindex = e - c->signature; } /* Align contents to 8 byte boundary */ - if (!message_extend_body(m, 8, 0)) { - if (e) - c->signature[c->index] = 0; - + if (!message_extend_body(m, 8, 0)) return -ENOMEM; - } if (c->enclosing != SD_BUS_TYPE_ARRAY) c->index = nindex; @@ -1507,18 +1713,25 @@ int sd_bus_message_open_container( return -EPERM; if (!contents) return -EINVAL; + if (m->poisoned) + return -ESTALE; /* Make sure we have space for one more container */ w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1)); - if (!w) + if (!w) { + m->poisoned = true; return -ENOMEM; + } + m->containers = w; c = message_get_container(m); signature = strdup(contents); - if (!signature) + if (!signature) { + m->poisoned = true; return -ENOMEM; + } /* Save old index in the parent container, in case we have to * abort this container */ @@ -1562,6 +1775,8 @@ int sd_bus_message_close_container(sd_bus_message *m) { return -EPERM; if (m->n_containers <= 0) return -EINVAL; + if (m->poisoned) + return -ESTALE; c = message_get_container(m); if (c->enclosing != SD_BUS_TYPE_ARRAY) @@ -1574,37 +1789,6 @@ int sd_bus_message_close_container(sd_bus_message *m) { return 0; } -static void message_abort_container(sd_bus_message *m) { - struct bus_container *c; - size_t delta; - - assert(m); - assert(!m->sealed); - assert(m->n_containers > 0); - - c = message_get_container(m); - - /* Undo appends */ - assert(m->header->body_size >= c->before); - delta = m->header->body_size - c->before; - m->header->body_size = c->before; - - /* Free container */ - free(c->signature); - m->n_containers--; - - /* Correct index of new top-level container */ - c = message_get_container(m); - c->index = c->saved_index; - - /* Correct array sizes all the way up */ - for (c = m->containers; c < m->containers + m->n_containers; c++) - if (c->array_size) { - assert(*c->array_size >= delta); - *c->array_size -= delta; - } -} - typedef struct { const char *types; unsigned n_struct; @@ -1849,6 +2033,8 @@ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) { return -EINVAL; if (m->sealed) return -EPERM; + if (m->poisoned) + return -ESTALE; if (!types) return 0; @@ -1872,6 +2058,8 @@ int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, return -EINVAL; if (!ptr && size > 0) return -EINVAL; + if (m->poisoned) + return -ESTALE; align = bus_type_get_alignment(type); sz = bus_type_get_size(type); @@ -1887,21 +2075,15 @@ int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, return r; a = message_extend_body(m, align, size); - if (!a) { - r = -ENOMEM; - goto fail; - } + if (!a) + return -ENOMEM; r = sd_bus_message_close_container(m); if (r < 0) - goto fail; + return r; *ptr = a; return 0; - -fail: - message_abort_container(m); - return r; } int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size) { @@ -1922,15 +2104,15 @@ int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, s } static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) { - size_t k, start, n; + size_t k, start, end; assert(rindex); assert(align > 0); start = ALIGN_TO((size_t) *rindex, align); - n = start + nbytes; + end = start + nbytes; - if (n > sz) + if (end > sz) return -EBADMSG; /* Verify that padding is 0 */ @@ -1941,7 +2123,7 @@ static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, if (r) *r = (uint8_t*) p + start; - *rindex = n; + *rindex = end; return 1; } @@ -1958,7 +2140,50 @@ static bool message_end_of_array(sd_bus_message *m, size_t index) { return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size); } -static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) { +static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) { + struct bus_body_part *part; + size_t begin; + assert(m); + + if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) { + part = m->cached_rindex_part; + begin = m->cached_rindex_part_begin; + } else { + part = &m->body; + begin = 0; + } + + while (part) { + if (index < begin) + return NULL; + + if (index + sz <= begin + part->size) { + if (p) + *p = part->data ? (uint8_t*) part->data + index - begin : NULL; + + m->cached_rindex_part = part; + m->cached_rindex_part_begin = begin; + + return part; + } + + part = part->next; + } + + return NULL; +} + +static int message_peek_body( + sd_bus_message *m, + size_t *rindex, + size_t align, + size_t nbytes, + void **ret) { + + size_t k, start, end, padding; + struct bus_body_part *part; + uint8_t *q; + assert(m); assert(rindex); assert(align > 0); @@ -1966,7 +2191,34 @@ static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, si if (message_end_of_array(m, *rindex)) return 0; - return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret); + start = ALIGN_TO((size_t) *rindex, align); + padding = start - *rindex; + end = start + nbytes; + + if (end > BUS_MESSAGE_BODY_SIZE(m)) + return -EBADMSG; + + part = find_part(m, *rindex, padding, (void**) &q); + if (!part) + return -EBADMSG; + + if (q) { + /* Verify padding */ + for (k = 0; k < padding; k++) + if (q[k] != 0) + return -EBADMSG; + } + + part = find_part(m, start, nbytes, (void**) &q); + if (!part || !q) + return -EBADMSG; + + *rindex = end; + + if (ret) + *ret = q; + + return 1; } static bool validate_nul(const char *s, size_t l) { @@ -2601,7 +2853,7 @@ int sd_bus_message_rewind(sd_bus_message *m, int complete) { return -EPERM; if (complete) { - reset_containers(m); + message_reset_containers(m); m->rindex = 0; m->root_container.index = 0; @@ -3620,6 +3872,8 @@ int bus_message_dump(sd_bus_message *m) { int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) { size_t total; void *p, *e; + unsigned i; + struct bus_body_part *part; assert(m); assert(buffer); @@ -3640,8 +3894,8 @@ int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) { e = mempset(e, 0, 8 - (m->header->fields_size % 8)); } - if (m->body) - e = mempcpy(e, m->body, m->header->body_size); + for (i = 0, part = &m->body; i < m->n_body_parts; i++, part = part->next) + e = mempcpy(e, part->data, part->size); assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p)); diff --git a/src/libsystemd-bus/bus-message.h b/src/libsystemd-bus/bus-message.h index 86a41a73b6..1c50c7357a 100644 --- a/src/libsystemd-bus/bus-message.h +++ b/src/libsystemd-bus/bus-message.h @@ -50,6 +50,16 @@ struct bus_header { uint32_t fields_size; } _packed_; +struct bus_body_part { + void *data; + size_t size; + size_t mapped; + int memfd; + bool free_this:1; + bool sealed:1; + struct bus_body_part *next; +}; + struct sd_bus_message { unsigned n_ref; @@ -80,19 +90,22 @@ struct sd_bus_message { bool gid_valid:1; bool free_header:1; bool free_fields:1; - bool free_body:1; bool free_kdbus:1; bool free_fds:1; bool release_kdbus:1; + bool poisoned:1; struct bus_header *header; void *fields; - void *body; - struct kdbus_msg *kdbus; + struct bus_body_part body; + struct bus_body_part *body_end; + unsigned n_body_parts; char *label; size_t rindex; + struct bus_body_part *cached_rindex_part; + size_t cached_rindex_part_begin; uint32_t n_fds; int *fds; @@ -100,9 +113,12 @@ struct sd_bus_message { struct bus_container root_container, *containers; unsigned n_containers; - struct iovec iovec[3]; + struct iovec *iovec; + struct iovec iovec_fixed[3]; unsigned n_iovec; + struct kdbus_msg *kdbus; + char *peeked_signature; usec_t timeout; @@ -199,3 +215,5 @@ int bus_message_append_ap(sd_bus_message *m, const char *types, va_list ap); int bus_message_parse_fields(sd_bus_message *m); int bus_header_size(struct bus_header *h, size_t *sum); + +struct bus_body_part *message_append_part(sd_bus_message *m); diff --git a/src/libsystemd-bus/bus-socket.c b/src/libsystemd-bus/bus-socket.c index 8a86b02c68..4dafe1fdb7 100644 --- a/src/libsystemd-bus/bus-socket.c +++ b/src/libsystemd-bus/bus-socket.c @@ -58,7 +58,7 @@ static void iovec_advance(struct iovec iov[], unsigned *idx, size_t size) { } } -static void append_iovec(sd_bus_message *m, const void *p, size_t sz) { +static int append_iovec(sd_bus_message *m, const void *p, size_t sz) { assert(m); assert(p); assert(sz > 0); @@ -66,22 +66,51 @@ static void append_iovec(sd_bus_message *m, const void *p, size_t sz) { m->iovec[m->n_iovec].iov_base = (void*) p; m->iovec[m->n_iovec].iov_len = sz; m->n_iovec++; + + return 0; } -static void bus_message_setup_iovec(sd_bus_message *m) { +static int bus_message_setup_iovec(sd_bus_message *m) { + struct bus_body_part *part; + unsigned n; + int r; + assert(m); assert(m->sealed); if (m->n_iovec > 0) - return; + return 0; + + assert(!m->iovec); + + n = 1 + !!m->fields + m->n_body_parts; + if (n < ELEMENTSOF(m->iovec_fixed)) + m->iovec = m->iovec_fixed; + else { + m->iovec = new(struct iovec, n); + if (!m->iovec) + return -ENOMEM; + } + + r = append_iovec(m, m->header, sizeof(*m->header)); + if (r < 0) + return r; + + if (m->fields) { + r = append_iovec(m, m->fields, ALIGN8(m->header->fields_size)); + if (r < 0) + return r; + } - append_iovec(m, m->header, sizeof(*m->header)); + for (part = &m->body; part && part->size > 0; part = part->next) { + r = append_iovec(m, part->data, part->size); + if (r < 0) + return r; + } - if (m->fields) - append_iovec(m, m->fields, ALIGN8(m->header->fields_size)); + assert(n == m->n_iovec); - if (m->body) - append_iovec(m, m->body, m->header->body_size); + return 0; } bool bus_socket_auth_needs_write(sd_bus *b) { @@ -749,6 +778,7 @@ int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) { ssize_t k; size_t n; unsigned j; + int r; assert(bus); assert(m); @@ -758,7 +788,9 @@ int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) { if (*idx >= BUS_MESSAGE_SIZE(m)) return 0; - bus_message_setup_iovec(m); + r = bus_message_setup_iovec(m); + if (r < 0) + return r; n = m->n_iovec * sizeof(struct iovec); iov = alloca(n); diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c index 7d6d848ec5..2537ba52d5 100644 --- a/src/libsystemd-bus/sd-bus.c +++ b/src/libsystemd-bus/sd-bus.c @@ -86,9 +86,10 @@ static void bus_free(sd_bus *b) { } hashmap_free(b->object_callbacks); - bus_match_free(&b->match_callbacks); + bus_kernel_flush_memfd(b); + free(b); } -- cgit v1.2.1 From 9b05bc48662051314b47b18a3ef8b43b193f2367 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 14 May 2013 22:52:58 +0200 Subject: bus: fix allocation of body parts from memfd --- src/libsystemd-bus/bus-kernel.c | 13 +++++-------- src/libsystemd-bus/bus-message.c | 3 +++ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index b11df300b6..5b1769c0e1 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -441,7 +441,7 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess if (d->vec.size < sizeof(struct bus_header)) return -EBADMSG; - h = (struct bus_header*)UINT64_TO_PTR(d->vec.address); + h = UINT64_TO_PTR(d->vec.address); } n_payload++; @@ -476,9 +476,6 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess if (n_bytes != total) return -EBADMSG; - //if (n_payload > 2) - // return -EBADMSG; - r = bus_message_from_header(h, sizeof(struct bus_header), fds, n_fds, NULL, seclabel, 0, &m); if (r < 0) return r; @@ -553,7 +550,7 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess log_debug("Got unknown field from kernel %llu", d->type); } - if ((BUS_MESSAGE_FIELDS_SIZE(m) > 0 && !m->fields) || BUS_MESSAGE_SIZE(m) != idx) { + if ((BUS_MESSAGE_FIELDS_SIZE(m) > 0 && !m->fields)) { sd_bus_message_unref(m); return -EBADMSG; } @@ -685,10 +682,10 @@ int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) { return -ENOTSUP; if (bus->n_memfd_cache <= 0) { - int fd; + int fd, r; - fd = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, &fd); - if (fd < 0) + r = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, &fd); + if (r < 0) return -errno; *address = NULL; diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c index 7444a30a51..e0fb1f41db 100644 --- a/src/libsystemd-bus/bus-message.c +++ b/src/libsystemd-bus/bus-message.c @@ -433,6 +433,9 @@ static sd_bus_message *message_new(sd_bus *bus, uint8_t type) { m->header->version = bus ? bus->message_version : 1; m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING); + if (bus) + m->bus = sd_bus_ref(bus); + return m; } -- cgit v1.2.1 From 47e6ce32bb5bc8353c2070b8247be82410f4d78e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 15 May 2013 00:46:24 +0200 Subject: bus: seal off memfds when sealing messages --- src/libsystemd-bus/bus-message.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c index e0fb1f41db..5783140cf8 100644 --- a/src/libsystemd-bus/bus-message.c +++ b/src/libsystemd-bus/bus-message.c @@ -3555,8 +3555,10 @@ int bus_message_parse_fields(sd_bus_message *m) { } int bus_message_seal(sd_bus_message *m, uint64_t serial) { - int r; + struct bus_body_part *part; size_t l, a; + unsigned i; + int r; assert(m); @@ -3595,6 +3597,10 @@ int bus_message_seal(sd_bus_message *m, uint64_t serial) { m->header->fields_size -= a; } + for (i = 0, part = &m->body; i < m->n_body_parts; i++, part = part->next) + if (part->memfd >= 0 && part->sealed) + ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1); + m->header->serial = serial; m->sealed = true; -- cgit v1.2.1 From 13c299d3a8603db8fdfc715eaea69ce5acd7aecb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 15 May 2013 01:36:09 +0200 Subject: bus: minor fixes --- src/libsystemd-bus/bus-message.c | 3 +++ src/libsystemd-bus/bus-socket.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c index 5783140cf8..721dafe38b 100644 --- a/src/libsystemd-bus/bus-message.c +++ b/src/libsystemd-bus/bus-message.c @@ -3568,6 +3568,9 @@ int bus_message_seal(sd_bus_message *m, uint64_t serial) { if (m->n_containers > 0) return -EBADMSG; + if (m->poisoned) + return -ESTALE; + /* If there's a non-trivial signature set, then add it in here */ if (!isempty(m->root_container.signature)) { r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL); diff --git a/src/libsystemd-bus/bus-socket.c b/src/libsystemd-bus/bus-socket.c index 4dafe1fdb7..4a07869157 100644 --- a/src/libsystemd-bus/bus-socket.c +++ b/src/libsystemd-bus/bus-socket.c @@ -72,7 +72,7 @@ static int append_iovec(sd_bus_message *m, const void *p, size_t sz) { static int bus_message_setup_iovec(sd_bus_message *m) { struct bus_body_part *part; - unsigned n; + unsigned n, i; int r; assert(m); @@ -102,7 +102,7 @@ static int bus_message_setup_iovec(sd_bus_message *m) { return r; } - for (part = &m->body; part && part->size > 0; part = part->next) { + for (i = 0, part = &m->body; i < m->n_body_parts; i++, part = part->next) { r = append_iovec(m, part->data, part->size); if (r < 0) return r; -- cgit v1.2.1 From 9b29bb6853987bf6fef21531f69864fdfb39eb9a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 15 May 2013 01:43:15 +0200 Subject: bus: add macro for iterating through body parts of a message --- src/libsystemd-bus/bus-kernel.c | 5 +++-- src/libsystemd-bus/bus-message.c | 8 +++++--- src/libsystemd-bus/bus-message.h | 3 +++ src/libsystemd-bus/bus-socket.c | 2 +- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index 5b1769c0e1..3aa408414e 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -184,12 +184,13 @@ static int bus_message_setup_bloom(sd_bus_message *m, void *bloom) { } static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) { + struct bus_body_part *part; struct kdbus_item *d; bool well_known; uint64_t unique; size_t sz, dl; + unsigned i; int r; - struct bus_body_part *part; assert(b); assert(m); @@ -253,7 +254,7 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) { if (m->fields) append_payload_vec(&d, m->fields, ALIGN8(m->header->fields_size)); - for (part = &m->body; part && part->size > 0; part = part->next) + MESSAGE_FOREACH_PART(part, i, m) append_payload_vec(&d, part->data, part->size); if (m->kdbus->dst_id == KDBUS_DST_ID_BROADCAST) { diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c index 721dafe38b..3790102a75 100644 --- a/src/libsystemd-bus/bus-message.c +++ b/src/libsystemd-bus/bus-message.c @@ -3600,9 +3600,11 @@ int bus_message_seal(sd_bus_message *m, uint64_t serial) { m->header->fields_size -= a; } - for (i = 0, part = &m->body; i < m->n_body_parts; i++, part = part->next) - if (part->memfd >= 0 && part->sealed) + MESSAGE_FOREACH_PART(part, i, m) + if (part->memfd >= 0 && !part->sealed) { ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1); + part->sealed = true; + } m->header->serial = serial; m->sealed = true; @@ -3906,7 +3908,7 @@ int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) { e = mempset(e, 0, 8 - (m->header->fields_size % 8)); } - for (i = 0, part = &m->body; i < m->n_body_parts; i++, part = part->next) + MESSAGE_FOREACH_PART(part, i, m) e = mempcpy(e, part->data, part->size); assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p)); diff --git a/src/libsystemd-bus/bus-message.h b/src/libsystemd-bus/bus-message.h index 1c50c7357a..01a1e01230 100644 --- a/src/libsystemd-bus/bus-message.h +++ b/src/libsystemd-bus/bus-message.h @@ -217,3 +217,6 @@ int bus_message_parse_fields(sd_bus_message *m); int bus_header_size(struct bus_header *h, size_t *sum); struct bus_body_part *message_append_part(sd_bus_message *m); + +#define MESSAGE_FOREACH_PART(part, i, m) \ + for ((i) = 0, (part) = &(m)->body; (i) < (m)->n_body_parts; (i)++, (part) = (part)->next) diff --git a/src/libsystemd-bus/bus-socket.c b/src/libsystemd-bus/bus-socket.c index 4a07869157..f43b7da05c 100644 --- a/src/libsystemd-bus/bus-socket.c +++ b/src/libsystemd-bus/bus-socket.c @@ -102,7 +102,7 @@ static int bus_message_setup_iovec(sd_bus_message *m) { return r; } - for (i = 0, part = &m->body; i < m->n_body_parts; i++, part = part->next) { + MESSAGE_FOREACH_PART(part, i, m) { r = append_iovec(m, part->data, part->size); if (r < 0) return r; -- cgit v1.2.1 From c91cb83c4dbc9a95a0a2a38e7028e0a7f4af3b35 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 15 May 2013 02:56:45 +0200 Subject: bus: rework message struct to keep header with fields in same malloc() block This allows us to guarantee that the first payload_vec we pass to the kernel for each message is guaranteed to include the full header and all its field. --- src/libsystemd-bus/bus-kernel.c | 47 +++---------- src/libsystemd-bus/bus-message.c | 140 ++++++++++++++++++--------------------- src/libsystemd-bus/bus-message.h | 17 +++-- src/libsystemd-bus/bus-socket.c | 10 +-- 4 files changed, 90 insertions(+), 124 deletions(-) diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index 3aa408414e..81469365f0 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -211,7 +211,7 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) { sz = offsetof(struct kdbus_msg, items); /* Add in fixed header, fields header and payload */ - sz += (1 + !!m->fields + m->n_body_parts) * + sz += (1 + m->n_body_parts) * ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec)); /* Add space for bloom filter */ @@ -249,11 +249,7 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) { if (well_known) append_destination(&d, m->destination, dl); - append_payload_vec(&d, m->header, sizeof(*m->header)); - - if (m->fields) - append_payload_vec(&d, m->fields, ALIGN8(m->header->fields_size)); - + append_payload_vec(&d, m->header, BUS_MESSAGE_BODY_BEGIN(m)); MESSAGE_FOREACH_PART(part, i, m) append_payload_vec(&d, part->data, part->size); @@ -398,22 +394,6 @@ static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) { } } -static bool range_contains( - size_t astart, size_t asize, - size_t bstart, size_t bsize, - void *a, void **b) { - - if (bstart < astart) - return false; - - if (bstart + bsize > astart + asize) - return false; - - *b = (uint8_t*) a + (bstart - astart); - - return true; -} - static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_message **ret) { sd_bus_message *m = NULL; struct kdbus_item *d; @@ -439,10 +419,10 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess if (d->type == KDBUS_MSG_PAYLOAD_VEC) { if (!h) { - if (d->vec.size < sizeof(struct bus_header)) - return -EBADMSG; - h = UINT64_TO_PTR(d->vec.address); + + if (!bus_header_is_complete(h, d->vec.size)) + return -EBADMSG; } n_payload++; @@ -470,7 +450,7 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess if (!h) return -EBADMSG; - r = bus_header_size(h, &total); + r = bus_header_message_size(h, &total); if (r < 0) return r; @@ -489,11 +469,7 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess if (d->type == KDBUS_MSG_PAYLOAD_VEC) { size_t begin_body; - /* Fill in fields material */ - range_contains(idx, d->vec.size, ALIGN8(sizeof(struct bus_header)), BUS_MESSAGE_FIELDS_SIZE(m), - UINT64_TO_PTR(d->vec.address), &m->fields); - - begin_body = ALIGN8(sizeof(struct bus_header)) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m)); + begin_body = BUS_MESSAGE_BODY_BEGIN(m); if (idx + d->vec.size > begin_body) { struct bus_body_part *part; @@ -507,10 +483,10 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess } if (idx >= begin_body) { - part->data = (void*) d->vec.address; + part->data = UINT64_TO_PTR(d->vec.address); part->size = d->vec.size; } else { - part->data = (uint8_t*) (uintptr_t) d->vec.address + (begin_body - idx); + part->data = (uint8_t*) UINT64_TO_PTR(d->vec.address) + (begin_body - idx); part->size = d->vec.size - (begin_body - idx); } @@ -551,11 +527,6 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess log_debug("Got unknown field from kernel %llu", d->type); } - if ((BUS_MESSAGE_FIELDS_SIZE(m) > 0 && !m->fields)) { - sd_bus_message_unref(m); - return -EBADMSG; - } - r = bus_message_parse_fields(m); if (r < 0) { sd_bus_message_unref(m); diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c index 3790102a75..c1e1c468b8 100644 --- a/src/libsystemd-bus/bus-message.c +++ b/src/libsystemd-bus/bus-message.c @@ -116,9 +116,6 @@ static void message_free(sd_bus_message *m) { if (m->free_header) free(m->header); - if (m->free_fields) - free(m->fields); - message_reset_parts(m); if (m->free_kdbus) @@ -151,66 +148,64 @@ static void message_free(sd_bus_message *m) { free(m); } -static void* buffer_extend(void **p, uint32_t *sz, size_t align, size_t extend) { - size_t start, end; - void *k; - - assert(p); - assert(sz); - assert(align > 0); - - start = ALIGN_TO((size_t) *sz, align); - end = start + extend; - - if (end == *sz) - return (uint8_t*) *p + start; +static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) { + void *op, *np; + size_t old_size, new_size, start; - if (end > (size_t) ((uint32_t) -1)) - return NULL; + assert(m); - k = realloc(*p, end); - if (!k) + if (m->poisoned) return NULL; - /* Zero out padding */ - if (start > *sz) - memset((uint8_t*) k + *sz, 0, start - *sz); + old_size = sizeof(struct bus_header) + m->header->fields_size; + start = ALIGN_TO(old_size, align); + new_size = start + sz; - *p = k; - *sz = end; + if (old_size == new_size) + return (uint8_t*) m->header + old_size; - return (uint8_t*) k + start; -} + if (new_size > (size_t) ((uint32_t) -1)) + goto poison; -static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) { - void *p, *op; - size_t os; + if (m->free_header) { + np = realloc(m->header, ALIGN8(new_size)); + if (!np) + goto poison; + } else { + /* Initially, the header is allocated as part of of + * the sd_bus_message itself, let's replace it by + * dynamic data */ - assert(m); + np = malloc(ALIGN8(new_size)); + if (!np) + goto poison; - if (m->poisoned) - return NULL; + memcpy(np, m->header, sizeof(struct bus_header)); + } - op = m->fields; - os = m->header->fields_size; + /* Zero out padding */ + if (start > old_size) + memset((uint8_t*) np + old_size, 0, start - old_size); - p = buffer_extend(&m->fields, &m->header->fields_size, align, sz); - if (!p) { - m->poisoned = true; - return NULL; - } + op = m->header; + m->header = np; + m->header->fields_size = new_size - sizeof(struct bus_header); /* Adjust quick access pointers */ - m->path = adjust_pointer(m->path, op, os, m->fields); - m->interface = adjust_pointer(m->interface, op, os, m->fields); - m->member = adjust_pointer(m->member, op, os, m->fields); - m->destination = adjust_pointer(m->destination, op, os, m->fields); - m->sender = adjust_pointer(m->sender, op, os, m->fields); - m->error.name = adjust_pointer(m->error.name, op, os, m->fields); + m->path = adjust_pointer(m->path, op, old_size, m->header); + m->interface = adjust_pointer(m->interface, op, old_size, m->header); + m->member = adjust_pointer(m->member, op, old_size, m->header); + m->destination = adjust_pointer(m->destination, op, old_size, m->header); + m->sender = adjust_pointer(m->sender, op, old_size, m->header); + m->error.name = adjust_pointer(m->error.name, op, old_size, m->header); - m->free_fields = true; + m->free_header = true; - return p; + return (uint8_t*) np + start; + +poison: + m->poisoned = true; + return NULL; } static int message_append_field_string( @@ -390,8 +385,6 @@ int bus_message_from_malloc( goto fail; } - m->fields = (uint8_t*) buffer + sizeof(struct bus_header); - m->n_body_parts = 1; m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m)); m->body.size = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m)); @@ -3132,7 +3125,7 @@ static int message_peek_fields( assert(rindex); assert(align > 0); - return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret); + return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret); } static int message_peek_field_uint32( @@ -3584,21 +3577,13 @@ int bus_message_seal(sd_bus_message *m, uint64_t serial) { return r; } + /* Add padding at the end, since we know the body + * needs to start at an 8 byte alignment. */ + l = BUS_MESSAGE_FIELDS_SIZE(m); a = ALIGN8(l) - l; - - if (a > 0) { - /* Add padding at the end, since we know the body - * needs to start at an 8 byte alignment. */ - void *p; - - p = message_extend_fields(m, 1, a); - if (!p) - return -ENOMEM; - - memset(p, 0, a); - m->header->fields_size -= a; - } + if (a > 0) + memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a); MESSAGE_FOREACH_PART(part, i, m) if (part->memfd >= 0 && !part->sealed) { @@ -3899,15 +3884,7 @@ int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) { if (!p) return -ENOMEM; - e = mempcpy(p, m->header, sizeof(*m->header)); - - if (m->fields) { - e = mempcpy(e, m->fields, m->header->fields_size); - - if (m->header->fields_size % 8 != 0) - e = mempset(e, 0, 8 - (m->header->fields_size % 8)); - } - + e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m)); MESSAGE_FOREACH_PART(part, i, m) e = mempcpy(e, part->data, part->size); @@ -3981,7 +3958,22 @@ const char* bus_message_get_arg(sd_bus_message *m, unsigned i) { return t; } -int bus_header_size(struct bus_header *h, size_t *sum) { +bool bus_header_is_complete(struct bus_header *h, size_t size) { + size_t full; + + assert(h); + assert(size); + + if (size < sizeof(struct bus_header)) + return false; + + full = sizeof(struct bus_header) + + (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size)); + + return size >= full; +} + +int bus_header_message_size(struct bus_header *h, size_t *sum) { size_t fs, bs; assert(h); diff --git a/src/libsystemd-bus/bus-message.h b/src/libsystemd-bus/bus-message.h index 01a1e01230..2517514bac 100644 --- a/src/libsystemd-bus/bus-message.h +++ b/src/libsystemd-bus/bus-message.h @@ -89,14 +89,12 @@ struct sd_bus_message { bool uid_valid:1; bool gid_valid:1; bool free_header:1; - bool free_fields:1; bool free_kdbus:1; bool free_fds:1; bool release_kdbus:1; bool poisoned:1; struct bus_header *header; - void *fields; struct bus_body_part body; struct bus_body_part *body_end; unsigned n_body_parts; @@ -114,7 +112,7 @@ struct sd_bus_message { unsigned n_containers; struct iovec *iovec; - struct iovec iovec_fixed[3]; + struct iovec iovec_fixed[2]; unsigned n_iovec; struct kdbus_msg *kdbus; @@ -178,6 +176,16 @@ static inline uint32_t BUS_MESSAGE_SIZE(sd_bus_message *m) { BUS_MESSAGE_BODY_SIZE(m); } +static inline uint32_t BUS_MESSAGE_BODY_BEGIN(sd_bus_message *m) { + return + sizeof(struct bus_header) + + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m)); +} + +static inline void* BUS_MESSAGE_FIELDS(sd_bus_message *m) { + return (uint8_t*) m->header + sizeof(struct bus_header); +} + static inline void bus_message_unrefp(sd_bus_message **m) { sd_bus_message_unref(*m); } @@ -214,7 +222,8 @@ int bus_message_append_ap(sd_bus_message *m, const char *types, va_list ap); int bus_message_parse_fields(sd_bus_message *m); -int bus_header_size(struct bus_header *h, size_t *sum); +bool bus_header_is_complete(struct bus_header *h, size_t size); +int bus_header_message_size(struct bus_header *h, size_t *sum); struct bus_body_part *message_append_part(sd_bus_message *m); diff --git a/src/libsystemd-bus/bus-socket.c b/src/libsystemd-bus/bus-socket.c index f43b7da05c..4635da4b9e 100644 --- a/src/libsystemd-bus/bus-socket.c +++ b/src/libsystemd-bus/bus-socket.c @@ -83,7 +83,7 @@ static int bus_message_setup_iovec(sd_bus_message *m) { assert(!m->iovec); - n = 1 + !!m->fields + m->n_body_parts; + n = 1 + m->n_body_parts; if (n < ELEMENTSOF(m->iovec_fixed)) m->iovec = m->iovec_fixed; else { @@ -92,16 +92,10 @@ static int bus_message_setup_iovec(sd_bus_message *m) { return -ENOMEM; } - r = append_iovec(m, m->header, sizeof(*m->header)); + r = append_iovec(m, m->header, BUS_MESSAGE_BODY_BEGIN(m)); if (r < 0) return r; - if (m->fields) { - r = append_iovec(m, m->fields, ALIGN8(m->header->fields_size)); - if (r < 0) - return r; - } - MESSAGE_FOREACH_PART(part, i, m) { r = append_iovec(m, part->data, part->size); if (r < 0) -- cgit v1.2.1 From 53789059e0e9378041697c25af06a08a433fb964 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Heikkil=C3=A4?= Date: Fri, 3 May 2013 16:59:51 +0300 Subject: keymap: Add support for Eject button on MSI GE60/GE70 --- src/udev/keymap/95-keymap.rules | 1 + 1 file changed, 1 insertion(+) diff --git a/src/udev/keymap/95-keymap.rules b/src/udev/keymap/95-keymap.rules index 7956092030..2fb296c92b 100644 --- a/src/udev/keymap/95-keymap.rules +++ b/src/udev/keymap/95-keymap.rules @@ -138,6 +138,7 @@ ENV{DMI_VENDOR}=="MEDION*", ATTR{[dmi/id]product_name}=="*FID2060*", RUN+="keyma ENV{DMI_VENDOR}=="MEDIONNB", ATTR{[dmi/id]product_name}=="A555*", RUN+="keymap $name medionnb-a555" ENV{DMI_VENDOR}=="MICRO-STAR*|Micro-Star*", RUN+="keymap $name micro-star" +ENV{DMI_VENDOR}=="MICRO-STAR*|Micro-Star*", ATTR{[dmi/id]product_name}=="GE60*|GE70*", RUN+="keymap $name 0xC2 ejectcd" # some MSI models generate ACPI/input events on the LNXVIDEO input devices, # plus some extra synthesized ones on atkbd as an echo of actually changing the -- cgit v1.2.1 From 39887731d4a36292674f92effa30e5941419c201 Mon Sep 17 00:00:00 2001 From: Thomas Hindoe Paaboel Andersen Date: Fri, 12 Oct 2012 20:26:47 +0200 Subject: sd-journal: check if the pointers passed are the same --- src/journal/sd-journal.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index c21712b7c4..779af62b51 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -2217,6 +2217,8 @@ _public_ int sd_journal_get_cutoff_realtime_usec(sd_journal *j, uint64_t *from, return -EINVAL; if (!from && !to) return -EINVAL; + if (from == to) + return -EINVAL; HASHMAP_FOREACH(f, j->files, i) { usec_t fr, t; @@ -2256,6 +2258,8 @@ _public_ int sd_journal_get_cutoff_monotonic_usec(sd_journal *j, sd_id128_t boot return -EINVAL; if (!from && !to) return -EINVAL; + if (from == to) + return -EINVAL; HASHMAP_FOREACH(f, j->files, i) { usec_t fr, t; -- cgit v1.2.1 From 6581f00f7eabdaccf587a4b6af60ed4696dd2791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 14 May 2013 22:10:44 -0400 Subject: build-sys: properly report missing gtk-doc This brings the check for ENABLE_GTK_DOC in line with HAVE_INTROSPECTION and other similar checks. Only the status line that is printed with uninstalled gtk-doc is changed. https://bugs.freedesktop.org/show_bug.cgi?id=63108 --- configure.ac | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index e1278e8504..781ea5a85f 100644 --- a/configure.ac +++ b/configure.ac @@ -72,9 +72,10 @@ AC_PATH_PROG([SETCAP], [setcap], [/usr/sbin/setcap]) AC_PATH_PROG([KILL], [kill], [/usr/bin/kill]) # gtkdocize greps for '^GTK_DOC_CHECK', so it needs to be on its own line -m4_ifdef([GTK_DOC_CHECK], [ -GTK_DOC_CHECK([1.18],[--flavour no-tmpl]) -], [AM_CONDITIONAL([ENABLE_GTK_DOC], [false])]) +m4_ifdef([GTK_DOC_CHECK], + [GTK_DOC_CHECK([1.18],[--flavour no-tmpl])], + [AM_CONDITIONAL([ENABLE_GTK_DOC], [false]) + enable_gtk_doc=no]) AS_IF([test "x$enable_gtk_doc" = "xyes" -a "x$XSLTPROC" = x], [ AC_MSG_ERROR([*** GTK doc requested but xsltproc not found]) -- cgit v1.2.1 From b37250d661ed67d07c734630617d73e64f6d7e49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 14 May 2013 22:23:00 -0400 Subject: build-sys: fix gtkdocize check gtkdocize: GTK_DOC_CHECK not called in configure.ac Fixup for 6581f00f7ea. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 781ea5a85f..65186a45ab 100644 --- a/configure.ac +++ b/configure.ac @@ -72,8 +72,8 @@ AC_PATH_PROG([SETCAP], [setcap], [/usr/sbin/setcap]) AC_PATH_PROG([KILL], [kill], [/usr/bin/kill]) # gtkdocize greps for '^GTK_DOC_CHECK', so it needs to be on its own line -m4_ifdef([GTK_DOC_CHECK], - [GTK_DOC_CHECK([1.18],[--flavour no-tmpl])], +m4_ifdef([GTK_DOC_CHECK], [ +GTK_DOC_CHECK([1.18],[--flavour no-tmpl])], [AM_CONDITIONAL([ENABLE_GTK_DOC], [false]) enable_gtk_doc=no]) -- cgit v1.2.1 From 99271804172f6ac51be9556b2bdf37d6a7e952bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 14 May 2013 23:08:00 -0400 Subject: journalctl: add -k/--dmesg --- TODO | 2 -- src/journal/journalctl.c | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index 62016e1e43..3dd63372e5 100644 --- a/TODO +++ b/TODO @@ -36,8 +36,6 @@ Features: makes the audit userspace to think auditing is not available in the kernel. -* maybe add "journalctl -k" as shortcut for "-b _TRANSPORT=kernel" - * Introduce a way how we can kill the main process of a service with KillSignal, but all processes with SIGKILL later on https://bugzilla.redhat.com/show_bug.cgi?id=952634 diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 409f082276..2e672fa096 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -71,6 +71,7 @@ static bool arg_no_tail = false; static bool arg_quiet = false; static bool arg_merge = false; static bool arg_this_boot = false; +static bool arg_dmesg = false; static const char *arg_cursor = NULL; static const char *arg_directory = NULL; static int arg_priorities = 0xFF; @@ -108,6 +109,7 @@ static int help(void) { " --until=DATE Stop showing entries older or of the specified date\n" " -c --cursor=CURSOR Start showing entries from specified cursor\n" " -b --this-boot Show data only from current boot\n" + " -k --dmesg Show kmsg log from current boot\n" " -u --unit=UNIT Show data only from the specified unit\n" " --user-unit=UNIT Show data only from the specified user session unit\n" " -p --priority=RANGE Show only messages within the specified priority range\n" @@ -187,6 +189,7 @@ static int parse_argv(int argc, char *argv[]) { { "quiet", no_argument, NULL, 'q' }, { "merge", no_argument, NULL, 'm' }, { "this-boot", no_argument, NULL, 'b' }, + { "dmesg", no_argument, NULL, 'k' }, { "directory", required_argument, NULL, 'D' }, { "root", required_argument, NULL, ARG_ROOT }, { "header", no_argument, NULL, ARG_HEADER }, @@ -215,7 +218,7 @@ static int parse_argv(int argc, char *argv[]) { assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "hefo:an::qmbD:p:c:u:F:xr", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "hefo:an::qmbkD:p:c:u:F:xr", options, NULL)) >= 0) { switch (c) { @@ -317,6 +320,10 @@ static int parse_argv(int argc, char *argv[]) { arg_this_boot = true; break; + case 'k': + arg_this_boot = arg_dmesg = true; + break; + case 'D': arg_directory = optarg; break; @@ -613,6 +620,26 @@ static int add_this_boot(sd_journal *j) { return 0; } +static int add_dmesg(sd_journal *j) { + int r; + assert(j); + + if (!arg_dmesg) + return 0; + + r = sd_journal_add_match(j, "_TRANSPORT=kernel", strlen("_TRANSPORT=kernel")); + if (r < 0) { + log_error("Failed to add match: %s", strerror(-r)); + return r; + } + + r = sd_journal_add_conjunction(j); + if (r < 0) + return r; + + return 0; +} + static int add_units(sd_journal *j) { _cleanup_free_ char *u = NULL; int r; @@ -1129,6 +1156,10 @@ int main(int argc, char *argv[]) { if (r < 0) return EXIT_FAILURE; + r = add_dmesg(j); + if (r < 0) + return EXIT_FAILURE; + r = add_units(j); strv_free(arg_system_units); strv_free(arg_user_units); -- cgit v1.2.1 From 453a0c2946da620f99825d39db335e9ea9861829 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 15 May 2013 19:45:05 +0200 Subject: bus: add support for adding memfds into message payload --- .gitignore | 1 + Makefile.am | 13 ++- src/libsystemd-bus/bus-kernel.c | 3 +- src/libsystemd-bus/bus-message.c | 150 +++++++++++++++++++++++++++++--- src/libsystemd-bus/bus-message.h | 7 +- src/libsystemd-bus/sd-memfd.c | 24 +++++ src/libsystemd-bus/test-bus-zero-copy.c | 112 ++++++++++++++++++++++++ src/systemd/sd-bus.h | 3 + src/systemd/sd-memfd.h | 2 + 9 files changed, 298 insertions(+), 17 deletions(-) create mode 100644 src/libsystemd-bus/test-bus-zero-copy.c diff --git a/.gitignore b/.gitignore index d53e75a43e..2dd1d715dd 100644 --- a/.gitignore +++ b/.gitignore @@ -88,6 +88,7 @@ /test-bus-memfd /test-bus-signature /test-bus-server +/test-bus-zero-copy /test-calendarspec /test-catalog /test-cgroup diff --git a/Makefile.am b/Makefile.am index eb85c8dada..fa626c5a2f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1758,7 +1758,8 @@ tests += \ test-bus-server \ test-bus-match \ test-bus-kernel \ - test-bus-memfd + test-bus-memfd \ + test-bus-zero-copy noinst_PROGRAMS += \ busctl @@ -1840,6 +1841,16 @@ test_bus_memfd_LDADD = \ libsystemd-shared.la \ libsystemd-bus.la +test_bus_zero_copy_SOURCES = \ + src/libsystemd-bus/test-bus-zero-copy.c + +test_bus_zero_copy_CFLAGS = \ + $(AM_CFLAGS) + +test_bus_zero_copy_LDADD = \ + libsystemd-shared.la \ + libsystemd-bus.la + busctl_SOURCES = \ src/libsystemd-bus/busctl.c diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index 81469365f0..54a5e1691c 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -486,10 +486,11 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess part->data = UINT64_TO_PTR(d->vec.address); part->size = d->vec.size; } else { - part->data = (uint8_t*) UINT64_TO_PTR(d->vec.address) + (begin_body - idx); + part->data = d->vec.address != 0 ? (uint8_t*) UINT64_TO_PTR(d->vec.address) + (begin_body - idx) : NULL; part->size = d->vec.size - (begin_body - idx); } + part->is_zero = d->vec.address == 0; part->sealed = true; } diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c index c1e1c468b8..747b44ac94 100644 --- a/src/libsystemd-bus/bus-message.c +++ b/src/libsystemd-bus/bus-message.c @@ -69,7 +69,9 @@ static void message_free_part(sd_bus_message *m, struct bus_body_part *part) { close_nointr_nofail(part->memfd); } - } else if (part->free_this) + } else if (part->munmap_this) + munmap(part->data, part->mapped); + else if (part->free_this) free(part->data); if (part != &m->body) @@ -1119,8 +1121,13 @@ static void part_zero(struct bus_body_part *part, size_t sz) { assert(sz > 0); assert(sz < 8); - part->data = NULL; + /* All other fields can be left in their defaults */ + assert(!part->data); + assert(part->memfd < 0); + part->size = sz; + part->is_zero = true; + part->sealed = true; } static int part_make_space( @@ -1151,8 +1158,8 @@ static int part_make_space( return -errno; } - if (sz > part->mapped) { - size_t psz = PAGE_ALIGN(sz); + if (!part->data || sz > part->mapped) { + size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1); if (part->mapped <= 0) n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0); @@ -1166,6 +1173,7 @@ static int part_make_space( part->mapped = psz; part->data = n; + part->munmap_this = true; } } else { n = realloc(part->data, sz); @@ -1185,8 +1193,22 @@ static int part_make_space( return 0; } -static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) { +static void message_extend_containers(sd_bus_message *m, size_t expand) { struct bus_container *c; + + assert(m); + + if (expand <= 0) + return; + + /* Update counters */ + for (c = m->containers; c < m->containers + m->n_containers; c++) + if (c->array_size) + *c->array_size += expand; + +} + +static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) { struct bus_body_part *part = NULL; size_t start_body, end_body, padding, start_part, end_part, added; bool add_new_part; @@ -1234,6 +1256,7 @@ static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) { if (r < 0) return NULL; } else { + struct bus_container *c; void *op; size_t os; @@ -1260,12 +1283,8 @@ static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) { m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data); } - /* Update counters */ - for (c = m->containers; c < m->containers + m->n_containers; c++) - if (c->array_size) - *c->array_size += added; - m->header->body_size = end_body; + message_extend_containers(m, added); return p; } @@ -2099,6 +2118,101 @@ int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, s return 0; } +int sd_bus_message_append_array_memfd(sd_bus_message *m, char type, sd_memfd *memfd) { + _cleanup_close_ int copy_fd = -1; + struct bus_body_part *part; + ssize_t align, sz; + uint64_t size; + void *a; + int r; + + if (!m) + return -EINVAL; + if (!memfd) + return -EINVAL; + if (m->sealed) + return -EPERM; + if (!bus_type_is_trivial(type)) + return -EINVAL; + if (m->poisoned) + return -ESTALE; + + r = sd_memfd_set_sealed(memfd, true); + if (r < 0) + return r; + + copy_fd = sd_memfd_dup_fd(memfd); + if (copy_fd < 0) + return copy_fd; + + r = sd_memfd_get_size(memfd, &size); + if (r < 0) + return r; + + align = bus_type_get_alignment(type); + sz = bus_type_get_size(type); + + assert_se(align > 0); + assert_se(sz > 0); + + if (size % sz != 0) + return -EINVAL; + + if (size > (size_t) (uint32_t) -1) + return -EINVAL; + + r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type)); + if (r < 0) + return r; + + a = message_extend_body(m, align, 0); + if (!a) + return -ENOMEM; + + part = message_append_part(m); + if (!part) + return -ENOMEM; + + part->memfd = copy_fd; + part->sealed = true; + part->size = size; + copy_fd = -1; + + message_extend_containers(m, size); + m->header->body_size += size; + + return sd_bus_message_close_container(m); +} + +static int body_part_map_for_read(struct bus_body_part *part) { + void *p; + size_t psz; + + assert_se(part); + + if (part->data) + return 0; + + if (part->size <= 0) + return 0; + + psz = PAGE_ALIGN(part->size); + + if (part->memfd >= 0) + p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0); + else if (part->is_zero) + p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + else + return -EINVAL; + + if (p == MAP_FAILED) + return -errno; + + part->mapped = psz; + part->data = p; + return 0; +} + static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) { size_t k, start, end; @@ -2139,6 +2253,8 @@ static bool message_end_of_array(sd_bus_message *m, size_t index) { static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) { struct bus_body_part *part; size_t begin; + int r; + assert(m); if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) { @@ -2154,8 +2270,13 @@ static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t s return NULL; if (index + sz <= begin + part->size) { + + r = body_part_map_for_read(part); + if (r < 0) + return NULL; + if (p) - *p = part->data ? (uint8_t*) part->data + index - begin : NULL; + *p = (uint8_t*) part->data + index - begin; m->cached_rindex_part = part; m->cached_rindex_part_begin = begin; @@ -2163,6 +2284,7 @@ static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t s return part; } + begin += part->size; part = part->next; } @@ -3638,7 +3760,8 @@ int bus_message_dump(sd_bus_message *m) { "\treply_serial=%u\n" "\terror.name=%s\n" "\terror.message=%s\n" - "\tsealed=%s\n", + "\tsealed=%s\n" + "\tn_body_parts=%u\n", m, m->n_ref, m->header->endian, @@ -3657,7 +3780,8 @@ int bus_message_dump(sd_bus_message *m) { m->reply_serial, strna(m->error.name), strna(m->error.message), - yes_no(m->sealed)); + yes_no(m->sealed), + m->n_body_parts); if (m->pid != 0) printf("\tpid=%lu\n", (unsigned long) m->pid); diff --git a/src/libsystemd-bus/bus-message.h b/src/libsystemd-bus/bus-message.h index 2517514bac..f9c8fc9c08 100644 --- a/src/libsystemd-bus/bus-message.h +++ b/src/libsystemd-bus/bus-message.h @@ -33,9 +33,10 @@ struct bus_container { char enclosing; - char *signature; unsigned index, saved_index; + char *signature; + uint32_t *array_size; size_t before, begin; }; @@ -51,13 +52,15 @@ struct bus_header { } _packed_; struct bus_body_part { + struct bus_body_part *next; void *data; size_t size; size_t mapped; int memfd; bool free_this:1; + bool munmap_this:1; bool sealed:1; - struct bus_body_part *next; + bool is_zero:1; }; struct sd_bus_message { diff --git a/src/libsystemd-bus/sd-memfd.c b/src/libsystemd-bus/sd-memfd.c index 2712a26f66..bd14da3a70 100644 --- a/src/libsystemd-bus/sd-memfd.c +++ b/src/libsystemd-bus/sd-memfd.c @@ -205,3 +205,27 @@ int sd_memfd_set_size(sd_memfd *m, uint64_t sz) { return r; } + +int sd_memfd_new_and_map(sd_memfd **m, size_t sz, void **p) { + sd_memfd *n; + int r; + + r = sd_memfd_new(&n); + if (r < 0) + return r; + + r = sd_memfd_set_size(n, sz); + if (r < 0) { + sd_memfd_free(n); + return r; + } + + r = sd_memfd_map(n, 0, sz, p); + if (r < 0) { + sd_memfd_free(n); + return r; + } + + *m = n; + return 0; +} diff --git a/src/libsystemd-bus/test-bus-zero-copy.c b/src/libsystemd-bus/test-bus-zero-copy.c new file mode 100644 index 0000000000..024a0bfddf --- /dev/null +++ b/src/libsystemd-bus/test-bus-zero-copy.c @@ -0,0 +1,112 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include "util.h" +#include "log.h" + +#include "sd-bus.h" +#include "sd-memfd.h" +#include "bus-message.h" +#include "bus-error.h" +#include "bus-kernel.h" + +int main(int argc, char *argv[]) { + _cleanup_free_ char *bus_name = NULL, *address = NULL; + void *p; + sd_bus *a, *b; + int r, bus_ref; + sd_bus_message *m; + sd_memfd *f; + + log_set_max_level(LOG_DEBUG); + + bus_ref = bus_kernel_create("deine-mutter", &bus_name); + if (bus_ref == -ENOENT) + return EXIT_TEST_SKIP; + + assert_se(bus_ref >= 0); + + address = strappend("kernel:path=", bus_name); + assert_se(address); + + r = sd_bus_new(&a); + assert_se(r >= 0); + + r = sd_bus_new(&b); + assert_se(r >= 0); + + r = sd_bus_set_address(a, address); + assert_se(r >= 0); + + r = sd_bus_set_address(b, address); + assert_se(r >= 0); + + r = sd_bus_start(a); + assert_se(r >= 0); + + r = sd_bus_start(b); + assert_se(r >= 0); + + r = sd_bus_message_new_method_call(b, ":1.1", "/a/path", "an.inter.face", "AMethod", &m); + assert_se(r >= 0); + + r = sd_bus_message_open_container(m, 'r', "ayay"); + assert_se(r >= 0); + + r = sd_bus_message_append_array_space(m, 'y', 32, &p); + assert_se(r >= 0); + + memset(p, 'L', 32); + + r = sd_memfd_new_and_map(&f, 32, &p); + assert_se(r >= 0); + + memset(p, 'P', 32); + munmap(p, 32); + + r = sd_memfd_set_size(f, 32); + assert_se(r >= 0); + + r = sd_bus_message_append_array_memfd(m, 'y', f); + assert_se(r >= 0); + + r = sd_bus_message_close_container(m); + assert_se(r >= 0); + + r = bus_message_seal(m, 55); + assert_se(r >= 0); + + bus_message_dump(m); + + r = sd_bus_send(b, m, NULL); + assert_se(r >= 0); + + sd_bus_message_unref(m); + + sd_bus_unref(a); + sd_bus_unref(b); + sd_memfd_free(f); + + return 0; +} diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h index 28c8536992..4c3c26d611 100644 --- a/src/systemd/sd-bus.h +++ b/src/systemd/sd-bus.h @@ -27,6 +27,7 @@ #include #include "sd-bus-protocol.h" +#include "sd-memfd.h" #ifdef __cplusplus extern "C" { @@ -160,7 +161,9 @@ int sd_bus_message_append(sd_bus_message *m, const char *types, ...); int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p); int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size); int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr); +int sd_bus_message_append_array_memfd(sd_bus_message *m, char type, sd_memfd *memfd); int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s); +int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd* memfd); int sd_bus_message_open_container(sd_bus_message *m, char type, const char *contents); int sd_bus_message_close_container(sd_bus_message *m); diff --git a/src/systemd/sd-memfd.h b/src/systemd/sd-memfd.h index 8594a3b61f..ee140e48d3 100644 --- a/src/systemd/sd-memfd.h +++ b/src/systemd/sd-memfd.h @@ -35,6 +35,8 @@ typedef struct sd_memfd sd_memfd; int sd_memfd_new(sd_memfd **m); int sd_memfd_make(int fd, sd_memfd **m); +int sd_memfd_new_and_map(sd_memfd **m, size_t sz, void **p); + void sd_memfd_free(sd_memfd *m); int sd_memfd_get_fd(sd_memfd *m); -- cgit v1.2.1 From c35b956d34bbb8bb208e49e45de2c103ca11911c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 15 May 2013 22:38:51 +0200 Subject: units: rework systemd-random-seed-{load,save}.service to be a single service That way ordering it with MountsRequiredFor= works properly, as this no longer results in mount units start requests to be added to the shutdown transaction that conflict with stop requests for the same unit. --- Makefile-man.am | 11 ++--- Makefile.am | 10 ++-- man/systemd-random-seed-load.service.xml | 80 ------------------------------- man/systemd-random-seed.service.xml | 75 +++++++++++++++++++++++++++++ units/.gitignore | 3 +- units/systemd-random-seed-load.service.in | 18 ------- units/systemd-random-seed-save.service.in | 18 ------- units/systemd-random-seed.service.in | 21 ++++++++ units/systemd-tmpfiles-setup.service.in | 1 + 9 files changed, 104 insertions(+), 133 deletions(-) delete mode 100644 man/systemd-random-seed-load.service.xml create mode 100644 man/systemd-random-seed.service.xml delete mode 100644 units/systemd-random-seed-load.service.in delete mode 100644 units/systemd-random-seed-save.service.in create mode 100644 units/systemd-random-seed.service.in diff --git a/Makefile-man.am b/Makefile-man.am index 481423a963..7d620943a2 100644 --- a/Makefile-man.am +++ b/Makefile-man.am @@ -667,16 +667,11 @@ endif if ENABLE_RANDOMSEED MANPAGES += \ - man/systemd-random-seed-load.service.8 + man/systemd-random-seed.service.8 MANPAGES_ALIAS += \ - man/systemd-random-seed-save.service.8 \ man/systemd-random-seed.8 -man/systemd-random-seed-save.service.8: man/systemd-random-seed-load.service.8 -man/systemd-random-seed.8: man/systemd-random-seed-load.service.8 -man/systemd-random-seed-save.service.html: man/systemd-random-seed-load.service.html - $(html-alias) - -man/systemd-random-seed.html: man/systemd-random-seed-load.service.html +man/systemd-random-seed.8: man/systemd-random-seed.service.8 +man/systemd-random-seed.html: man/systemd-random-seed.service.html $(html-alias) endif diff --git a/Makefile.am b/Makefile.am index fa626c5a2f..8d8139c134 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3162,8 +3162,7 @@ rootlibexec_PROGRAMS += \ systemd-random-seed nodist_systemunit_DATA += \ - units/systemd-random-seed-save.service \ - units/systemd-random-seed-load.service + units/systemd-random-seed.service systemd_random_seed_SOURCES = \ src/random-seed/random-seed.c @@ -3172,16 +3171,13 @@ systemd_random_seed_LDADD = \ libsystemd-label.la \ libsystemd-shared.la -SHUTDOWN_TARGET_WANTS += \ - systemd-random-seed-save.service SYSINIT_TARGET_WANTS += \ - systemd-random-seed-load.service + systemd-random-seed.service endif EXTRA_DIST += \ - units/systemd-random-seed-save.service.in \ - units/systemd-random-seed-load.service.in + units/systemd-random-seed.service.in # ------------------------------------------------------------------------------ if HAVE_LIBCRYPTSETUP diff --git a/man/systemd-random-seed-load.service.xml b/man/systemd-random-seed-load.service.xml deleted file mode 100644 index 693c008a2d..0000000000 --- a/man/systemd-random-seed-load.service.xml +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - - systemd-random-seed-load.service - systemd - - - - Developer - Lennart - Poettering - lennart@poettering.net - - - - - - systemd-random-seed-load.service - 8 - - - - systemd-random-seed-load.service - systemd-random-seed-save.service - systemd-random-seed - Load and save the system random seed at boot and shutdown - - - - systemd-random-seed-load.service - systemd-random-seed-save.service - /usr/lib/systemd/systemd-random-seed - - - - Description - - systemd-random-seed-load.service - is an early-boot service that restores the random seed - of the - system. systemd-random-seed-save.service - is a late-shutdown service that saves the random seed - of the system. See - random4 - for details. Saving/restoring the random seed across - boots increases the amount of available entropy early - at boot. On disk the random seed is stored in - /var/lib/random-seed. - - - - See Also - - systemd1, - random4 - - - - diff --git a/man/systemd-random-seed.service.xml b/man/systemd-random-seed.service.xml new file mode 100644 index 0000000000..8cd14b74cb --- /dev/null +++ b/man/systemd-random-seed.service.xml @@ -0,0 +1,75 @@ + + + + + + + + systemd-random-seed.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-random-seed.service + 8 + + + + systemd-random-seed.service + systemd-random-seed + Load and save the system random seed at boot and shutdown + + + + systemd-random-seed.service + /usr/lib/systemd/systemd-random-seed + + + + Description + + systemd-random-seed.service + is a service that restores the random seed of the + system at early-boot and saves it at shutdown. See + random4 + for details. Saving/restoring the random seed across + boots increases the amount of available entropy early + at boot. On disk the random seed is stored in + /var/lib/random-seed. + + + + See Also + + systemd1, + random4 + + + + diff --git a/units/.gitignore b/units/.gitignore index 606d947634..307e09d249 100644 --- a/units/.gitignore +++ b/units/.gitignore @@ -41,8 +41,7 @@ /systemd-remount-fs.service /systemd-vconsole-setup.service /systemd-shutdownd.service -/systemd-random-seed-load.service -/systemd-random-seed-save.service +/systemd-random-seed.service /systemd-initctl.service /getty@.service /systemd-update-utmp-runlevel.service diff --git a/units/systemd-random-seed-load.service.in b/units/systemd-random-seed-load.service.in deleted file mode 100644 index e9156ef086..0000000000 --- a/units/systemd-random-seed-load.service.in +++ /dev/null @@ -1,18 +0,0 @@ -# This file is part of systemd. -# -# systemd is free software; you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or -# (at your option) any later version. - -[Unit] -Description=Load Random Seed -Documentation=man:systemd-random-seed-load.service(8) man:random(4) -DefaultDependencies=no -RequiresMountsFor=@RANDOM_SEED@ -After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service -Before=sysinit.target final.target - -[Service] -Type=oneshot -ExecStart=@rootlibexecdir@/systemd-random-seed load diff --git a/units/systemd-random-seed-save.service.in b/units/systemd-random-seed-save.service.in deleted file mode 100644 index 3444d4ce70..0000000000 --- a/units/systemd-random-seed-save.service.in +++ /dev/null @@ -1,18 +0,0 @@ -# This file is part of systemd. -# -# systemd is free software; you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or -# (at your option) any later version. - -[Unit] -Description=Save Random Seed -Documentation=man:systemd-random-seed-load.service(8) man:random(4) -DefaultDependencies=no -RequiresMountsFor=@RANDOM_SEED@ -After=systemd-remount-fs.service systemd-random-seed-load.service -Before=final.target - -[Service] -Type=oneshot -ExecStart=@rootlibexecdir@/systemd-random-seed save diff --git a/units/systemd-random-seed.service.in b/units/systemd-random-seed.service.in new file mode 100644 index 0000000000..0c21a04842 --- /dev/null +++ b/units/systemd-random-seed.service.in @@ -0,0 +1,21 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Load/Save Random Seed +Documentation=man:systemd-random-seed-load.service(8) man:random(4) +DefaultDependencies=no +RequiresMountsFor=@RANDOM_SEED@ +Conflicts=shutdown.target +After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service +Before=sysinit.target shutdown.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=@rootlibexecdir@/systemd-random-seed load +ExecStop=@rootlibexecdir@/systemd-random-seed save diff --git a/units/systemd-tmpfiles-setup.service.in b/units/systemd-tmpfiles-setup.service.in index 4a3441c3ac..67c7d4af43 100644 --- a/units/systemd-tmpfiles-setup.service.in +++ b/units/systemd-tmpfiles-setup.service.in @@ -10,6 +10,7 @@ Description=Recreate Volatile Files and Directories Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8) DefaultDependencies=no Wants=local-fs.target +Conflicts=shutdown.target After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target Before=sysinit.target shutdown.target ConditionDirectoryNotEmpty=|/usr/lib/tmpfiles.d -- cgit v1.2.1 From 154ff088d371bee5651eaa2bc9bde8a34c185656 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 15 May 2013 22:40:36 +0200 Subject: update TODO --- TODO | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/TODO b/TODO index 3dd63372e5..d862dfb504 100644 --- a/TODO +++ b/TODO @@ -28,6 +28,11 @@ Fedora 19: - localectl: support new converted x11→console keymaps Features: + +* in the final killing spree, detect processes from the root directory, and + complain loudly if they have argv[0][0] == '@' set. + https://bugzilla.redhat.com/show_bug.cgi?id=961044 + * read the kernel's console "debug" keyword like we read "quiet" and adjust: systemd.log_level=debug and maybe systemd.log_target=kmsg -- cgit v1.2.1 From 3f92e4b4b61042391bd44de4dceb18177df0dd57 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 16 May 2013 00:19:03 +0200 Subject: utmp: turn systemd-update-utmp-shutdown.service into a normal runtime service With this change systemd-update-utmp-shutdown.service is replaced by systemd-update-utmp.service which is started at boot and stays around until shutdown. This allows us to properly order the unit against both /var/log and auditd. https://bugzilla.redhat.com/show_bug.cgi?id=853104 https://bugs.freedesktop.org/show_bug.cgi?id=64365 --- Makefile-man.am | 12 ++--- Makefile.am | 8 +-- man/systemd-update-utmp-runlevel.service.xml | 76 --------------------------- man/systemd-update-utmp.service.xml | 76 +++++++++++++++++++++++++++ src/update-utmp/update-utmp.c | 2 +- units/.gitignore | 2 +- units/systemd-update-utmp-runlevel.service.in | 8 +-- units/systemd-update-utmp-shutdown.service.in | 19 ------- units/systemd-update-utmp.service.in | 21 ++++++++ 9 files changed, 114 insertions(+), 110 deletions(-) delete mode 100644 man/systemd-update-utmp-runlevel.service.xml create mode 100644 man/systemd-update-utmp.service.xml delete mode 100644 units/systemd-update-utmp-shutdown.service.in create mode 100644 units/systemd-update-utmp.service.in diff --git a/Makefile-man.am b/Makefile-man.am index 7d620943a2..58881586cf 100644 --- a/Makefile-man.am +++ b/Makefile-man.am @@ -72,7 +72,7 @@ MANPAGES += \ man/systemd-tmpfiles.8 \ man/systemd-tty-ask-password-agent.1 \ man/systemd-udevd.service.8 \ - man/systemd-update-utmp-runlevel.service.8 \ + man/systemd-update-utmp.service.8 \ man/systemd.1 \ man/systemd.automount.5 \ man/systemd.device.5 \ @@ -191,7 +191,7 @@ MANPAGES_ALIAS += \ man/systemd-udevd-control.socket.8 \ man/systemd-udevd-kernel.socket.8 \ man/systemd-udevd.8 \ - man/systemd-update-utmp-shutdown.service.8 \ + man/systemd-update-utmp-runlevel.service.8 \ man/systemd-update-utmp.8 \ man/systemd-user.conf.5 man/SD_ALERT.3: man/sd-daemon.3 @@ -289,8 +289,8 @@ man/systemd-tmpfiles-setup.service.8: man/systemd-tmpfiles.8 man/systemd-udevd-control.socket.8: man/systemd-udevd.service.8 man/systemd-udevd-kernel.socket.8: man/systemd-udevd.service.8 man/systemd-udevd.8: man/systemd-udevd.service.8 -man/systemd-update-utmp-shutdown.service.8: man/systemd-update-utmp-runlevel.service.8 -man/systemd-update-utmp.8: man/systemd-update-utmp-runlevel.service.8 +man/systemd-update-utmp-runlevel.service.8: man/systemd-update-utmp.service.8 +man/systemd-update-utmp.8: man/systemd-update-utmp.service.8 man/systemd-user.conf.5: man/systemd-system.conf.5 man/SD_ALERT.html: man/sd-daemon.html $(html-alias) @@ -577,10 +577,10 @@ man/systemd-udevd-kernel.socket.html: man/systemd-udevd.service.html man/systemd-udevd.html: man/systemd-udevd.service.html $(html-alias) -man/systemd-update-utmp-shutdown.service.html: man/systemd-update-utmp-runlevel.service.html +man/systemd-update-utmp-runlevel.service.html: man/systemd-update-utmp.service.html $(html-alias) -man/systemd-update-utmp.html: man/systemd-update-utmp-runlevel.service.html +man/systemd-update-utmp.html: man/systemd-update-utmp.service.html $(html-alias) man/systemd-user.conf.html: man/systemd-system.conf.html diff --git a/Makefile.am b/Makefile.am index 8d8139c134..4c5e6fcdf1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -417,8 +417,8 @@ nodist_systemunit_DATA = \ units/systemd-initctl.service \ units/systemd-shutdownd.service \ units/systemd-remount-fs.service \ + units/systemd-update-utmp.service \ units/systemd-update-utmp-runlevel.service \ - units/systemd-update-utmp-shutdown.service \ units/systemd-tmpfiles-setup-dev.service \ units/systemd-tmpfiles-setup.service \ units/systemd-tmpfiles-clean.service \ @@ -463,8 +463,8 @@ EXTRA_DIST += \ units/systemd-initctl.service.in \ units/systemd-shutdownd.service.in \ units/systemd-remount-fs.service.in \ + units/systemd-update-utmp.service.in \ units/systemd-update-utmp-runlevel.service.in \ - units/systemd-update-utmp-shutdown.service.in \ units/systemd-tmpfiles-setup-dev.service.in \ units/systemd-tmpfiles-setup.service.in \ units/systemd-tmpfiles-clean.service.in \ @@ -4070,8 +4070,8 @@ RUNLEVEL4_TARGET_WANTS += \ RUNLEVEL5_TARGET_WANTS += \ systemd-update-utmp-runlevel.service endif -SHUTDOWN_TARGET_WANTS += \ - systemd-update-utmp-shutdown.service +SYSINIT_TARGET_WANTS += \ + systemd-update-utmp.service LOCAL_FS_TARGET_WANTS += \ systemd-remount-fs.service \ systemd-fsck-root.service \ diff --git a/man/systemd-update-utmp-runlevel.service.xml b/man/systemd-update-utmp-runlevel.service.xml deleted file mode 100644 index 867b958d30..0000000000 --- a/man/systemd-update-utmp-runlevel.service.xml +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - systemd-update-utmp-runlevel.service - systemd - - - - Developer - Lennart - Poettering - lennart@poettering.net - - - - - - systemd-update-utmp-runlevel.service - 8 - - - - systemd-update-utmp-runlevel.service - systemd-update-utmp-shutdown.service - systemd-update-utmp - Write audit and utmp updates at runlevel - changes and shutdown - - - - systemd-update-utmp-runlevel.service - systemd-update-utmp-shutdown.service - /usr/lib/systemd/systemd-update-utmp - - - - Description - - systemd-update-utmp-runlevel.service - is a service that writes SysV runlevel changes to utmp - and wtmp, as well as the audit logs, as they - occur. systemd-update-utmp-shutdown.service - does the same for shut-down requests. - - - - See Also - - systemd1, - utmp5, - auditd8 - - - - diff --git a/man/systemd-update-utmp.service.xml b/man/systemd-update-utmp.service.xml new file mode 100644 index 0000000000..846fc959d0 --- /dev/null +++ b/man/systemd-update-utmp.service.xml @@ -0,0 +1,76 @@ + + + + + + + + systemd-update-utmp.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-update-utmp.service + 8 + + + + systemd-update-utmp.service + systemd-update-utmp-runlevel.service + systemd-update-utmp + Write audit and utmp updates at bootup, runlevel + changes and shutdown + + + + systemd-update-utmp.service + systemd-update-utmp-runlevel.service + /usr/lib/systemd/systemd-update-utmp + + + + Description + + systemd-update-utmp-runlevel.service + is a service that writes SysV runlevel changes to utmp + and wtmp, as well as the audit logs, as they + occur. systemd-update-utmp.service + does the same for system reboots and shut-down requests. + + + + See Also + + systemd1, + utmp5, + auditd8 + + + + diff --git a/src/update-utmp/update-utmp.c b/src/update-utmp/update-utmp.c index 9184025554..202aa98767 100644 --- a/src/update-utmp/update-utmp.c +++ b/src/update-utmp/update-utmp.c @@ -104,7 +104,7 @@ static int get_current_runlevel(Context *c) { { '3', SPECIAL_RUNLEVEL3_TARGET }, { '4', SPECIAL_RUNLEVEL4_TARGET }, { '2', SPECIAL_RUNLEVEL2_TARGET }, - { 'S', SPECIAL_RESCUE_TARGET }, + { '1', SPECIAL_RESCUE_TARGET }, }; const char *interface = "org.freedesktop.systemd1.Unit", diff --git a/units/.gitignore b/units/.gitignore index 307e09d249..878cf2ce4c 100644 --- a/units/.gitignore +++ b/units/.gitignore @@ -44,8 +44,8 @@ /systemd-random-seed.service /systemd-initctl.service /getty@.service +/systemd-update-utmp.service /systemd-update-utmp-runlevel.service -/systemd-update-utmp-shutdown.service /systemd-binfmt.service /emergency.service /systemd-udev-settle.service diff --git a/units/systemd-update-utmp-runlevel.service.in b/units/systemd-update-utmp-runlevel.service.in index 27fae2cd02..99783e2e69 100644 --- a/units/systemd-update-utmp-runlevel.service.in +++ b/units/systemd-update-utmp-runlevel.service.in @@ -7,12 +7,14 @@ [Unit] Description=Update UTMP about System Runlevel Changes -Documentation=man:systemd-update-utmp-runlevel.service(8) man:utmp(5) +Documentation=man:systemd-update-utmp.service(8) man:utmp(5) DefaultDependencies=no RequiresMountsFor=/var/log/wtmp -After=systemd-remount-fs.service systemd-tmpfiles-setup.service auditd.service +Conflicts=shutdown.target +Requisite=systemd-update-utmp.service +After=systemd-update-utmp.service After=runlevel1.target runlevel2.target runlevel3.target runlevel4.target runlevel5.target -Before=final.target +Before=shutdown.target [Service] Type=oneshot diff --git a/units/systemd-update-utmp-shutdown.service.in b/units/systemd-update-utmp-shutdown.service.in deleted file mode 100644 index aa93562f02..0000000000 --- a/units/systemd-update-utmp-shutdown.service.in +++ /dev/null @@ -1,19 +0,0 @@ -# This file is part of systemd. -# -# systemd is free software; you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or -# (at your option) any later version. - -[Unit] -Description=Update UTMP about System Shutdown -Documentation=man:systemd-update-utmp-runlevel.service(8) man:utmp(5) -DefaultDependencies=no -RequiresMountsFor=/var/log/wtmp -After=systemd-remount-fs.service systemd-tmpfiles-setup.service auditd.service -After=systemd-update-utmp-runlevel.service -Before=final.target - -[Service] -Type=oneshot -ExecStart=@rootlibexecdir@/systemd-update-utmp shutdown diff --git a/units/systemd-update-utmp.service.in b/units/systemd-update-utmp.service.in new file mode 100644 index 0000000000..e7c20a5ead --- /dev/null +++ b/units/systemd-update-utmp.service.in @@ -0,0 +1,21 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Update UTMP about System Reboot/Shutdown +Documentation=man:systemd-update-utmp.service(8) man:utmp(5) +DefaultDependencies=no +RequiresMountsFor=/var/log/wtmp +Conflicts=shutdown.target +After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service systemd-tmpfiles-setup.service auditd.service +Before=sysinit.target shutdown.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=@rootlibexecdir@/systemd-update-utmp reboot +ExecStop=@rootlibexecdir@/systemd-update-utmp shutdown -- cgit v1.2.1 From a392d36195f92eaa2d5b7c1d588ff8e52025a43a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 16 May 2013 02:04:13 +0200 Subject: bus: put together messages with memfd payload correctly --- src/libsystemd-bus/bus-kernel.c | 56 ++++++++++++++++++++++++++++----- src/libsystemd-bus/bus-message.c | 37 +++++++++++++++++++--- src/libsystemd-bus/bus-message.h | 3 ++ src/libsystemd-bus/test-bus-zero-copy.c | 16 +++++++--- 4 files changed, 95 insertions(+), 17 deletions(-) diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index 54a5e1691c..a0e892a49f 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -65,19 +65,32 @@ static int parse_unique_name(const char *s, uint64_t *id) { static void append_payload_vec(struct kdbus_item **d, const void *p, size_t sz) { assert(d); - assert(p); assert(sz > 0); *d = ALIGN8_PTR(*d); (*d)->size = offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec); (*d)->type = KDBUS_MSG_PAYLOAD_VEC; - (*d)->vec.address = (uint64_t) p; + (*d)->vec.address = PTR_TO_UINT64(p); (*d)->vec.size = sz; *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size); } +static void append_payload_memfd(struct kdbus_item **d, int memfd, size_t sz) { + assert(d); + assert(memfd >= 0); + assert(sz > 0); + + *d = ALIGN8_PTR(*d); + (*d)->size = offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd); + (*d)->type = KDBUS_MSG_PAYLOAD_MEMFD; + (*d)->memfd.fd = memfd; + (*d)->memfd.size = sz; + + *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size); +} + static void append_destination(struct kdbus_item **d, const char *s, size_t length) { assert(d); assert(s); @@ -210,6 +223,9 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) { sz = offsetof(struct kdbus_msg, items); + assert_cc(ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec)) == + ALIGN8(offsetof(struct kdbus_item, memfd) + sizeof(struct kdbus_memfd))); + /* Add in fixed header, fields header and payload */ sz += (1 + m->n_body_parts) * ALIGN8(offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec)); @@ -250,19 +266,38 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) { append_destination(&d, m->destination, dl); append_payload_vec(&d, m->header, BUS_MESSAGE_BODY_BEGIN(m)); - MESSAGE_FOREACH_PART(part, i, m) + + MESSAGE_FOREACH_PART(part, i, m) { + if (part->is_zero) { + append_payload_vec(&d, NULL, part->size); + continue; + } + + if (part->memfd >= 0 && part->sealed) { + bus_body_part_unmap(part); + + if (!part->data) { + append_payload_memfd(&d, part->memfd, part->size); + continue; + } + } + + if (part->memfd >= 0) { + r = bus_body_part_map(part); + if (r < 0) + goto fail; + } + append_payload_vec(&d, part->data, part->size); + } if (m->kdbus->dst_id == KDBUS_DST_ID_BROADCAST) { void *p; p = append_bloom(&d, BLOOM_SIZE); r = bus_message_setup_bloom(m, p); - if (r < 0) { - free(m->kdbus); - m->kdbus = NULL; - return -r; - } + if (r < 0) + goto fail; } if (m->n_fds > 0) @@ -274,6 +309,11 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) { m->free_kdbus = true; return 0; + +fail: + free(m->kdbus); + m->kdbus = NULL; + return r; } int bus_kernel_take_fd(sd_bus *b) { diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c index 747b44ac94..b5a311530b 100644 --- a/src/libsystemd-bus/bus-message.c +++ b/src/libsystemd-bus/bus-message.c @@ -2184,7 +2184,7 @@ int sd_bus_message_append_array_memfd(sd_bus_message *m, char type, sd_memfd *me return sd_bus_message_close_container(m); } -static int body_part_map_for_read(struct bus_body_part *part) { +int bus_body_part_map(struct bus_body_part *part) { void *p; size_t psz; @@ -2210,9 +2210,36 @@ static int body_part_map_for_read(struct bus_body_part *part) { part->mapped = psz; part->data = p; + part->munmap_this = true; + return 0; } +void bus_body_part_unmap(struct bus_body_part *part) { + + assert_se(part); + + if (part->memfd < 0) + return; + + if (!part->sealed) + return; + + if (!part->data) + return; + + if (!part->munmap_this) + return; + + assert_se(munmap(part->data, part->mapped) == 0); + + part->data = NULL; + part->mapped = 0; + part->munmap_this = false; + + return; +} + static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) { size_t k, start, end; @@ -2271,7 +2298,7 @@ static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t s if (index + sz <= begin + part->size) { - r = body_part_map_for_read(part); + r = bus_body_part_map(part); if (r < 0) return NULL; @@ -3709,8 +3736,10 @@ int bus_message_seal(sd_bus_message *m, uint64_t serial) { MESSAGE_FOREACH_PART(part, i, m) if (part->memfd >= 0 && !part->sealed) { - ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1); - part->sealed = true; + bus_body_part_unmap(part); + + if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0) + part->sealed = true; } m->header->serial = serial; diff --git a/src/libsystemd-bus/bus-message.h b/src/libsystemd-bus/bus-message.h index f9c8fc9c08..44390c6b50 100644 --- a/src/libsystemd-bus/bus-message.h +++ b/src/libsystemd-bus/bus-message.h @@ -232,3 +232,6 @@ struct bus_body_part *message_append_part(sd_bus_message *m); #define MESSAGE_FOREACH_PART(part, i, m) \ for ((i) = 0, (part) = &(m)->body; (i) < (m)->n_body_parts; (i)++, (part) = (part)->next) + +int bus_body_part_map(struct bus_body_part *part); +void bus_body_part_unmap(struct bus_body_part *part); diff --git a/src/libsystemd-bus/test-bus-zero-copy.c b/src/libsystemd-bus/test-bus-zero-copy.c index 024a0bfddf..0d8435ec1e 100644 --- a/src/libsystemd-bus/test-bus-zero-copy.c +++ b/src/libsystemd-bus/test-bus-zero-copy.c @@ -38,6 +38,7 @@ int main(int argc, char *argv[]) { int r, bus_ref; sd_bus_message *m; sd_memfd *f; + uint64_t sz; log_set_max_level(LOG_DEBUG); @@ -79,21 +80,27 @@ int main(int argc, char *argv[]) { memset(p, 'L', 32); - r = sd_memfd_new_and_map(&f, 32, &p); + r = sd_memfd_new_and_map(&f, 17, &p); assert_se(r >= 0); - memset(p, 'P', 32); - munmap(p, 32); + memset(p, 'P', 17); + munmap(p, 17); - r = sd_memfd_set_size(f, 32); + r = sd_memfd_get_size(f, &sz); assert_se(r >= 0); + assert_se(sz == 17); r = sd_bus_message_append_array_memfd(m, 'y', f); assert_se(r >= 0); + sd_memfd_free(f); + r = sd_bus_message_close_container(m); assert_se(r >= 0); + r = sd_bus_message_append(m, "u", 4711); + assert_se(r >= 0); + r = bus_message_seal(m, 55); assert_se(r >= 0); @@ -106,7 +113,6 @@ int main(int argc, char *argv[]) { sd_bus_unref(a); sd_bus_unref(b); - sd_memfd_free(f); return 0; } -- cgit v1.2.1 From 1307c3ff9aa9d96fff6f9f42bb760887fa9aa240 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 16 May 2013 02:37:42 +0200 Subject: bus: implement receiving side of memfd hookup --- src/libsystemd-bus/bus-kernel.c | 80 ++++++++++++++++++++++----------- src/libsystemd-bus/bus-message.c | 10 +++-- src/libsystemd-bus/test-bus-zero-copy.c | 6 +++ 3 files changed, 67 insertions(+), 29 deletions(-) diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index a0e892a49f..f7759b6fb4 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -427,17 +427,17 @@ static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) { KDBUS_ITEM_FOREACH(d, k) { - if (d->type != KDBUS_MSG_FDS) - continue; - - close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int)); + if (d->type == KDBUS_MSG_FDS) + close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int)); + else if (d->type == KDBUS_MSG_PAYLOAD_MEMFD) + close_nointr_nofail(d->memfd.fd); } } static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_message **ret) { sd_bus_message *m = NULL; struct kdbus_item *d; - unsigned n_payload = 0, n_fds = 0; + unsigned n_fds = 0; _cleanup_free_ int *fds = NULL; struct bus_header *h = NULL; size_t total, n_bytes = 0, idx = 0; @@ -465,9 +465,15 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess return -EBADMSG; } - n_payload++; n_bytes += d->vec.size; + } else if (d->type == KDBUS_MSG_PAYLOAD_MEMFD) { + + if (!h) + return -EBADMSG; + + n_bytes += d->memfd.size; + } else if (d->type == KDBUS_MSG_FDS) { int *f; unsigned j; @@ -481,9 +487,7 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess memcpy(fds + n_fds, d->fds, sizeof(int) * j); n_fds += j; - } else if (d->type == KDBUS_MSG_DST_NAME) - destination = d->str; - else if (d->type == KDBUS_MSG_SRC_SECLABEL) + } else if (d->type == KDBUS_MSG_SRC_SECLABEL) seclabel = d->str; } @@ -518,8 +522,8 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess part = message_append_part(m); if (!part) { - sd_bus_message_unref(m); - return -ENOMEM; + r = -ENOMEM; + goto fail; } if (idx >= begin_body) { @@ -535,6 +539,25 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess } idx += d->vec.size; + } else if (d->type == KDBUS_MSG_PAYLOAD_MEMFD) { + struct bus_body_part *part; + + if (idx < BUS_MESSAGE_BODY_BEGIN(m)) { + r = -EBADMSG; + goto fail; + } + + part = message_append_part(m); + if (!part) { + r = -ENOMEM; + goto fail; + } + + part->memfd = d->memfd.fd; + part->size = d->memfd.size; + part->sealed = true; + + idx += d->memfd.size; } else if (d->type == KDBUS_MSG_SRC_CREDS) { m->pid_starttime = d->creds.starttime / NSEC_PER_USEC; @@ -562,17 +585,16 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess else if (d->type == KDBUS_MSG_SRC_CAPS) { m->capability = d->data; m->capability_size = l; - } else if (d->type != KDBUS_MSG_FDS && - d->type != KDBUS_MSG_DST_NAME && + } else if (d->type == KDBUS_MSG_DST_NAME) + destination = d->str; + else if (d->type != KDBUS_MSG_FDS && d->type != KDBUS_MSG_SRC_SECLABEL) log_debug("Got unknown field from kernel %llu", d->type); } r = bus_message_parse_fields(m); - if (r < 0) { - sd_bus_message_unref(m); - return r; - } + if (r < 0) + goto fail; if (k->src_id == KDBUS_SRC_ID_KERNEL) m->sender = "org.freedesktop.DBus"; @@ -601,6 +623,21 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess *ret = m; return 1; + +fail: + if (m) { + struct bus_body_part *part; + unsigned i; + + /* Make sure the memfds are not freed twice */ + MESSAGE_FOREACH_PART(part, i, m) + if (part->memfd >= 0) + part->memfd = -1; + + sd_bus_message_unref(m); + } + + return r; } int bus_kernel_read_message(sd_bus *bus, sd_bus_message **m) { @@ -618,15 +655,6 @@ int bus_kernel_read_message(sd_bus *bus, sd_bus_message **m) { return -errno; } - -/* /\* Let's tell valgrind that there's really no need to */ -/* * initialize this fully. This should be removed again */ -/* * when valgrind learned the kdbus ioctls natively. *\/ */ -/* #ifdef HAVE_VALGRIND_MEMCHECK_H */ -/* VALGRIND_MAKE_MEM_DEFINED(k, sz); */ -/* #endif */ - - r = bus_kernel_make_message(bus, k, m); if (r <= 0) close_kdbus_msg(bus, k); diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c index b5a311530b..209fd71c13 100644 --- a/src/libsystemd-bus/bus-message.c +++ b/src/libsystemd-bus/bus-message.c @@ -2196,6 +2196,13 @@ int bus_body_part_map(struct bus_body_part *part) { if (part->size <= 0) return 0; + /* For smaller zero parts (as used for padding) we don't need to map anything... */ + if (part->memfd < 0 && part->is_zero && part->size < 8) { + static const uint8_t zeroes[7] = { }; + part->data = (void*) zeroes; + return 0; + } + psz = PAGE_ALIGN(part->size); if (part->memfd >= 0) @@ -2222,9 +2229,6 @@ void bus_body_part_unmap(struct bus_body_part *part) { if (part->memfd < 0) return; - if (!part->sealed) - return; - if (!part->data) return; diff --git a/src/libsystemd-bus/test-bus-zero-copy.c b/src/libsystemd-bus/test-bus-zero-copy.c index 0d8435ec1e..5a9f45489e 100644 --- a/src/libsystemd-bus/test-bus-zero-copy.c +++ b/src/libsystemd-bus/test-bus-zero-copy.c @@ -111,6 +111,12 @@ int main(int argc, char *argv[]) { sd_bus_message_unref(m); + r = sd_bus_process(a, &m); + assert_se(r > 0); + + bus_message_dump(m); + sd_bus_message_unref(m); + sd_bus_unref(a); sd_bus_unref(b); -- cgit v1.2.1 From ca2670162464b98f44d3f30a1d8b47b02609784c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Bartoszkiewicz?= Date: Wed, 15 May 2013 11:28:58 +0200 Subject: journal: correctly convert usec_t to timespec. Use timespec_store instead of (incorrectly) doing it inline. --- src/journal/journald-server.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index cc52b8a5c9..b717b92ffb 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -1332,10 +1332,9 @@ int server_schedule_sync(Server *s) { return 0; if (s->sync_interval_usec) { - struct itimerspec sync_timer_enable = { - .it_value.tv_sec = s->sync_interval_usec / USEC_PER_SEC, - .it_value.tv_nsec = s->sync_interval_usec % MSEC_PER_SEC, - }; + struct itimerspec sync_timer_enable = {}; + + timespec_store(&sync_timer_enable.it_value, s->sync_interval_usec); r = timerfd_settime(s->sync_timer_fd, 0, &sync_timer_enable, NULL); if (r < 0) -- cgit v1.2.1 From 28f30cf274398ab80c71ea0c2afec4b94f8ba76e Mon Sep 17 00:00:00 2001 From: Chengwei Yang Date: Tue, 14 May 2013 09:03:04 +0800 Subject: Fix syscall(__NR_fanotify_mark, ...) on arm --- src/shared/missing.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/shared/missing.h b/src/shared/missing.h index d4ba0d3dcf..96e6d63101 100644 --- a/src/shared/missing.h +++ b/src/shared/missing.h @@ -138,7 +138,8 @@ static inline int fanotify_init(unsigned int flags, unsigned int event_f_flags) #ifndef HAVE_FANOTIFY_MARK static inline int fanotify_mark(int fanotify_fd, unsigned int flags, uint64_t mask, int dfd, const char *pathname) { -#if defined _MIPS_SIM && _MIPS_SIM == _MIPS_SIM_ABI32 || defined __powerpc__ && !defined __powerpc64__ +#if defined _MIPS_SIM && _MIPS_SIM == _MIPS_SIM_ABI32 || defined __powerpc__ && !defined __powerpc64__ \ + || defined __arm__ && !defined __aarch64__ union { uint64_t _64; uint32_t _32[2]; -- cgit v1.2.1 From 0a0c35d151570cca5ccd30befaa19c87b9c8c92d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 16 May 2013 00:38:39 -0400 Subject: systemd-python: do not attempt to convert str to bytes Bug-spotted-by: Steven Hiscocks --- src/python-systemd/journal.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/python-systemd/journal.py b/src/python-systemd/journal.py index 9ef1ede229..8fd1bb357c 100644 --- a/src/python-systemd/journal.py +++ b/src/python-systemd/journal.py @@ -55,6 +55,9 @@ def _convert_realtime(t): def _convert_timestamp(s): return _datetime.datetime.fromtimestamp(int(s) / 1000000) +def _convert_trivial(x): + return x + if _sys.version_info >= (3,): def _convert_uuid(s): return _uuid.UUID(s.decode()) @@ -87,6 +90,7 @@ DEFAULT_CONVERTERS = { '__REALTIME_TIMESTAMP': _convert_realtime, '_SOURCE_MONOTONIC_TIMESTAMP': _convert_source_monotonic, '__MONOTONIC_TIMESTAMP': _convert_monotonic, + '__CURSOR': _convert_trivial, 'COREDUMP': bytes, 'COREDUMP_PID': int, 'COREDUMP_UID': int, -- cgit v1.2.1 From 66b26c5c9b02e787bc46db24daff04ad41e05ec5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 16 May 2013 16:26:35 +0200 Subject: bus: send memfds as payload only on directed messages and for large parts --- src/libsystemd-bus/bus-kernel.c | 42 +++++++++++++++++------------- src/libsystemd-bus/bus-kernel.h | 9 ++++++- src/libsystemd-bus/bus-message.c | 28 ++++++++++++-------- src/libsystemd-bus/bus-socket.c | 18 ++++++++++--- src/libsystemd-bus/test-bus-zero-copy.c | 45 ++++++++++++++++++++++++++++----- 5 files changed, 103 insertions(+), 39 deletions(-) diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index f7759b6fb4..8ef5752b31 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -69,6 +69,10 @@ static void append_payload_vec(struct kdbus_item **d, const void *p, size_t sz) *d = ALIGN8_PTR(*d); + /* Note that p can be NULL, which encodes a region full of + * zeroes, which is useful to optimize certain padding + * conditions */ + (*d)->size = offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec); (*d)->type = KDBUS_MSG_PAYLOAD_VEC; (*d)->vec.address = PTR_TO_UINT64(p); @@ -244,9 +248,12 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) { sz += ALIGN8(offsetof(struct kdbus_item, fds) + sizeof(int)*m->n_fds); m->kdbus = memalign(8, sz); - if (!m->kdbus) - return -ENOMEM; + if (!m->kdbus) { + r = -ENOMEM; + goto fail; + } + m->free_kdbus = true; memset(m->kdbus, 0, sz); m->kdbus->flags = @@ -269,24 +276,28 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) { MESSAGE_FOREACH_PART(part, i, m) { if (part->is_zero) { + /* If this is padding then simply send a + * vector with a NULL data pointer which the + * kernel will just pass through. This is the + * most efficient way to encode zeroes */ + append_payload_vec(&d, NULL, part->size); continue; } - if (part->memfd >= 0 && part->sealed) { - bus_body_part_unmap(part); + if (part->memfd >= 0 && part->sealed && m->destination) { + /* Try to send a memfd, if the part is + * sealed and this is not a broadcast. Since we can only */ - if (!part->data) { - append_payload_memfd(&d, part->memfd, part->size); - continue; - } + append_payload_memfd(&d, part->memfd, part->size); + continue; } - if (part->memfd >= 0) { - r = bus_body_part_map(part); - if (r < 0) - goto fail; - } + /* Otherwise let's send a vector to the actual data, + * for that we need to map it first. */ + r = bus_body_part_map(part); + if (r < 0) + goto fail; append_payload_vec(&d, part->data, part->size); } @@ -306,13 +317,10 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) { m->kdbus->size = (uint8_t*) d - (uint8_t*) m->kdbus; assert(m->kdbus->size <= sz); - m->free_kdbus = true; - return 0; fail: - free(m->kdbus); - m->kdbus = NULL; + m->poisoned = true; return r; } diff --git a/src/libsystemd-bus/bus-kernel.h b/src/libsystemd-bus/bus-kernel.h index ed3f987ccd..1651c1e41d 100644 --- a/src/libsystemd-bus/bus-kernel.h +++ b/src/libsystemd-bus/bus-kernel.h @@ -24,7 +24,14 @@ #include "sd-bus.h" #define MEMFD_CACHE_MAX 32 -#define MEMFD_CACHE_ITEM_SIZE_MAX (128*1024) + +/* When we cache a memfd block for reuse, we will truncate blocks + * longer than this in order not to keep too much data around. */ +#define MEMFD_CACHE_ITEM_SIZE_MAX (32*1024) + +/* This determines at which minimum size we prefer sending memfds over + * sending vectors */ +#define MEMFD_MIN_SIZE (32*1024) struct memfd_cache { int fd; diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c index 209fd71c13..ceac15601e 100644 --- a/src/libsystemd-bus/bus-message.c +++ b/src/libsystemd-bus/bus-message.c @@ -59,6 +59,8 @@ static void message_free_part(sd_bus_message *m, struct bus_body_part *part) { assert(part); if (part->memfd >= 0) { + /* If we can reuse the memfd, try that. For that it + * can't be sealed yet. */ if (!part->sealed) bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped); @@ -3239,7 +3241,7 @@ int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, si return align; r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type)); - if (r < 0) + if (r <= 0) return r; c = message_get_container(m); @@ -3730,21 +3732,27 @@ int bus_message_seal(sd_bus_message *m, uint64_t serial) { return r; } - /* Add padding at the end, since we know the body - * needs to start at an 8 byte alignment. */ - + /* Add padding at the end of the fields part, since we know + * the body needs to start at an 8 byte alignment. We made + * sure we allocated enough space for this, so all we need to + * do here is to zero it out. */ l = BUS_MESSAGE_FIELDS_SIZE(m); a = ALIGN8(l) - l; if (a > 0) memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a); - MESSAGE_FOREACH_PART(part, i, m) - if (part->memfd >= 0 && !part->sealed) { - bus_body_part_unmap(part); + /* If this is something we can send as memfd, then let's seal + the memfd now. Note that we can send memfds as payload only + for directed messages, and not for broadcasts. */ + if (m->destination) { + MESSAGE_FOREACH_PART(part, i, m) + if (part->memfd >= 0 && !part->sealed && part->size > MEMFD_MIN_SIZE) { + bus_body_part_unmap(part); - if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0) - part->sealed = true; - } + if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0) + part->sealed = true; + } + } m->header->serial = serial; m->sealed = true; diff --git a/src/libsystemd-bus/bus-socket.c b/src/libsystemd-bus/bus-socket.c index 4635da4b9e..befded7079 100644 --- a/src/libsystemd-bus/bus-socket.c +++ b/src/libsystemd-bus/bus-socket.c @@ -88,23 +88,33 @@ static int bus_message_setup_iovec(sd_bus_message *m) { m->iovec = m->iovec_fixed; else { m->iovec = new(struct iovec, n); - if (!m->iovec) - return -ENOMEM; + if (!m->iovec) { + r = -ENOMEM; + goto fail; + } } r = append_iovec(m, m->header, BUS_MESSAGE_BODY_BEGIN(m)); if (r < 0) - return r; + goto fail; MESSAGE_FOREACH_PART(part, i, m) { + r = bus_body_part_map(part); + if (r < 0) + goto fail; + r = append_iovec(m, part->data, part->size); if (r < 0) - return r; + goto fail; } assert(n == m->n_iovec); return 0; + +fail: + m->poisoned = true; + return r; } bool bus_socket_auth_needs_write(sd_bus *b) { diff --git a/src/libsystemd-bus/test-bus-zero-copy.c b/src/libsystemd-bus/test-bus-zero-copy.c index 5a9f45489e..63bb921456 100644 --- a/src/libsystemd-bus/test-bus-zero-copy.c +++ b/src/libsystemd-bus/test-bus-zero-copy.c @@ -31,14 +31,19 @@ #include "bus-error.h" #include "bus-kernel.h" +#define FIRST_ARRAY 17 +#define SECOND_ARRAY 33 + int main(int argc, char *argv[]) { _cleanup_free_ char *bus_name = NULL, *address = NULL; - void *p; + uint8_t *p; sd_bus *a, *b; int r, bus_ref; sd_bus_message *m; sd_memfd *f; uint64_t sz; + uint32_t u32; + size_t i, l; log_set_max_level(LOG_DEBUG); @@ -75,20 +80,20 @@ int main(int argc, char *argv[]) { r = sd_bus_message_open_container(m, 'r', "ayay"); assert_se(r >= 0); - r = sd_bus_message_append_array_space(m, 'y', 32, &p); + r = sd_bus_message_append_array_space(m, 'y', FIRST_ARRAY, (void**) &p); assert_se(r >= 0); - memset(p, 'L', 32); + memset(p, 'L', FIRST_ARRAY); - r = sd_memfd_new_and_map(&f, 17, &p); + r = sd_memfd_new_and_map(&f, SECOND_ARRAY, (void**) &p); assert_se(r >= 0); - memset(p, 'P', 17); - munmap(p, 17); + memset(p, 'P', SECOND_ARRAY); + munmap(p, SECOND_ARRAY); r = sd_memfd_get_size(f, &sz); assert_se(r >= 0); - assert_se(sz == 17); + assert_se(sz == SECOND_ARRAY); r = sd_bus_message_append_array_memfd(m, 'y', f); assert_se(r >= 0); @@ -115,6 +120,32 @@ int main(int argc, char *argv[]) { assert_se(r > 0); bus_message_dump(m); + sd_bus_message_rewind(m, true); + + r = sd_bus_message_enter_container(m, 'r', "ayay"); + assert_se(r > 0); + + r = sd_bus_message_read_array(m, 'y', (const void**) &p, &l); + assert_se(r > 0); + assert_se(l == FIRST_ARRAY); + + for (i = 0; i < l; i++) + assert_se(p[i] == 'L'); + + r = sd_bus_message_read_array(m, 'y', (const void**) &p, &l); + assert_se(r > 0); + assert_se(l == SECOND_ARRAY); + + for (i = 0; i < l; i++) + assert_se(p[i] == 'P'); + + r = sd_bus_message_exit_container(m); + assert_se(r > 0); + + r = sd_bus_message_read(m, "u", &u32); + assert_se(r > 0); + assert_se(u32 == 4711); + sd_bus_message_unref(m); sd_bus_unref(a); -- cgit v1.2.1 From 5cbe749238f62546f70d81173a2778f3982adb03 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 16 May 2013 16:53:03 +0200 Subject: bus: implement sd_bus_message_append_string_memfd() --- src/libsystemd-bus/bus-message.c | 98 ++++++++++++++++++++++++++++++--- src/libsystemd-bus/test-bus-zero-copy.c | 32 ++++++++++- 2 files changed, 121 insertions(+), 9 deletions(-) diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c index ceac15601e..dbb3337619 100644 --- a/src/libsystemd-bus/bus-message.c +++ b/src/libsystemd-bus/bus-message.c @@ -1296,7 +1296,6 @@ int message_append_basic(sd_bus_message *m, char type, const void *p, const void ssize_t align, sz; uint32_t k; void *a; - char *e = NULL; int fd = -1; uint32_t fdi = 0; int r; @@ -1320,6 +1319,8 @@ int message_append_basic(sd_bus_message *m, char type, const void *p, const void if (c->signature[c->index] != type) return -ENXIO; } else { + char *e; + /* Maybe we can append to the signature? But only if this is the top-level container*/ if (c->enclosing != 0) return -ENXIO; @@ -1452,7 +1453,6 @@ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) { int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) { struct bus_container *c; - char *e; void *a; if (!m) @@ -1472,6 +1472,8 @@ int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) if (c->signature[c->index] != SD_BUS_TYPE_STRING) return -ENXIO; } else { + char *e; + /* Maybe we can append to the signature? But only if this is the top-level container*/ if (c->enclosing != 0) return -ENXIO; @@ -1483,7 +1485,6 @@ int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) } } - a = message_extend_body(m, 4, 4 + size + 1); if (!a) return -ENOMEM; @@ -1506,7 +1507,6 @@ static int bus_message_open_array( uint32_t **array_size) { unsigned nindex; - char *e = NULL; void *a, *op; int alignment; size_t os; @@ -1536,6 +1536,8 @@ static int bus_message_open_array( nindex = c->index + 1 + strlen(contents); } else { + char *e; + if (c->enclosing != 0) return -ENXIO; @@ -1579,7 +1581,6 @@ static int bus_message_open_variant( struct bus_container *c, const char *contents) { - char *e = NULL; size_t l; void *a; @@ -1599,6 +1600,8 @@ static int bus_message_open_variant( return -ENXIO; } else { + char *e; + if (c->enclosing != 0) return -ENXIO; @@ -1629,7 +1632,6 @@ static int bus_message_open_struct( const char *contents) { size_t nindex; - char *e = NULL; assert(m); assert(c); @@ -1650,6 +1652,8 @@ static int bus_message_open_struct( nindex = c->index + 1 + l + 1; } else { + char *e; + if (c->enclosing != 0) return -ENXIO; @@ -2160,7 +2164,7 @@ int sd_bus_message_append_array_memfd(sd_bus_message *m, char type, sd_memfd *me if (size % sz != 0) return -EINVAL; - if (size > (size_t) (uint32_t) -1) + if (size > (uint64_t) (uint32_t) -1) return -EINVAL; r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type)); @@ -2186,6 +2190,86 @@ int sd_bus_message_append_array_memfd(sd_bus_message *m, char type, sd_memfd *me return sd_bus_message_close_container(m); } +int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) { + _cleanup_close_ int copy_fd = -1; + struct bus_body_part *part; + struct bus_container *c; + uint64_t size; + void *a; + int r; + + if (!m) + return -EINVAL; + if (!memfd) + return -EINVAL; + if (m->sealed) + return -EPERM; + if (m->poisoned) + return -ESTALE; + + r = sd_memfd_set_sealed(memfd, true); + if (r < 0) + return r; + + copy_fd = sd_memfd_dup_fd(memfd); + if (copy_fd < 0) + return copy_fd; + + r = sd_memfd_get_size(memfd, &size); + if (r < 0) + return r; + + /* We require this to be NUL terminated */ + if (size == 0) + return -EINVAL; + + if (size > (uint64_t) (uint32_t) -1) + return -EINVAL; + + c = message_get_container(m); + if (c->signature && c->signature[c->index]) { + /* Container signature is already set */ + + if (c->signature[c->index] != SD_BUS_TYPE_STRING) + return -ENXIO; + } else { + char *e; + + /* Maybe we can append to the signature? But only if this is the top-level container*/ + if (c->enclosing != 0) + return -ENXIO; + + e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL); + if (!e) { + m->poisoned = true; + return -ENOMEM; + } + } + + a = message_extend_body(m, 4, 4); + if (!a) + return -ENOMEM; + + *(uint32_t*) a = size - 1; + + part = message_append_part(m); + if (!part) + return -ENOMEM; + + part->memfd = copy_fd; + part->sealed = true; + part->size = size; + copy_fd = -1; + + message_extend_containers(m, size); + m->header->body_size += size; + + if (c->enclosing != SD_BUS_TYPE_ARRAY) + c->index++; + + return 0; +} + int bus_body_part_map(struct bus_body_part *part) { void *p; size_t psz; diff --git a/src/libsystemd-bus/test-bus-zero-copy.c b/src/libsystemd-bus/test-bus-zero-copy.c index 63bb921456..db3906e274 100644 --- a/src/libsystemd-bus/test-bus-zero-copy.c +++ b/src/libsystemd-bus/test-bus-zero-copy.c @@ -34,6 +34,8 @@ #define FIRST_ARRAY 17 #define SECOND_ARRAY 33 +#define STRING_SIZE 123 + int main(int argc, char *argv[]) { _cleanup_free_ char *bus_name = NULL, *address = NULL; uint8_t *p; @@ -44,6 +46,7 @@ int main(int argc, char *argv[]) { uint64_t sz; uint32_t u32; size_t i, l; + char *s; log_set_max_level(LOG_DEBUG); @@ -77,7 +80,7 @@ int main(int argc, char *argv[]) { r = sd_bus_message_new_method_call(b, ":1.1", "/a/path", "an.inter.face", "AMethod", &m); assert_se(r >= 0); - r = sd_bus_message_open_container(m, 'r', "ayay"); + r = sd_bus_message_open_container(m, 'r', "aysay"); assert_se(r >= 0); r = sd_bus_message_append_array_space(m, 'y', FIRST_ARRAY, (void**) &p); @@ -85,6 +88,24 @@ int main(int argc, char *argv[]) { memset(p, 'L', FIRST_ARRAY); + r = sd_memfd_new_and_map(&f, STRING_SIZE, (void**) &s); + assert_se(r >= 0); + + for (i = 0; i < STRING_SIZE-1; i++) + s[i] = '0' + (i % 10); + + s[STRING_SIZE-1] = 0; + munmap(s, STRING_SIZE); + + r = sd_memfd_get_size(f, &sz); + assert_se(r >= 0); + assert_se(sz == STRING_SIZE); + + r = sd_bus_message_append_string_memfd(m, f); + assert_se(r >= 0); + + sd_memfd_free(f); + r = sd_memfd_new_and_map(&f, SECOND_ARRAY, (void**) &p); assert_se(r >= 0); @@ -122,7 +143,7 @@ int main(int argc, char *argv[]) { bus_message_dump(m); sd_bus_message_rewind(m, true); - r = sd_bus_message_enter_container(m, 'r', "ayay"); + r = sd_bus_message_enter_container(m, 'r', "aysay"); assert_se(r > 0); r = sd_bus_message_read_array(m, 'y', (const void**) &p, &l); @@ -132,6 +153,13 @@ int main(int argc, char *argv[]) { for (i = 0; i < l; i++) assert_se(p[i] == 'L'); + r = sd_bus_message_read(m, "s", &s); + assert_se(r > 0); + + for (i = 0; i < STRING_SIZE-1; i++) + assert_se(s[i] == (char) ('0' + (i % 10))); + assert_se(s[STRING_SIZE-1] == 0); + r = sd_bus_message_read_array(m, 'y', (const void**) &p, &l); assert_se(r > 0); assert_se(l == SECOND_ARRAY); -- cgit v1.2.1 From eb01ba5de14859d7a94835ab9299de40132d549a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 16 May 2013 21:14:56 +0200 Subject: bus: synthesize timeout message errors instead of returning error codes --- TODO | 16 ++++++++ src/libsystemd-bus/bus-error.c | 80 ++++++++++++++++++++++++++++++++++--- src/libsystemd-bus/bus-match.c | 15 ++++--- src/libsystemd-bus/bus-match.h | 2 +- src/libsystemd-bus/bus-message.c | 46 +++++++++++++++++++++ src/libsystemd-bus/bus-message.h | 4 ++ src/libsystemd-bus/sd-bus.c | 31 +++++++++----- src/libsystemd-bus/test-bus-chat.c | 10 ++--- src/libsystemd-bus/test-bus-match.c | 6 +-- src/systemd/sd-bus.h | 9 +---- 10 files changed, 177 insertions(+), 42 deletions(-) diff --git a/TODO b/TODO index d862dfb504..14ed4b43ca 100644 --- a/TODO +++ b/TODO @@ -29,6 +29,22 @@ Fedora 19: Features: +* libsystemd-bus: + - default policy (allow uid == 0 and our own uid) + - enforce alignment of pointers passed in + - negotiation for attach attributes + - verify that the PID doesn't change for existing busses + - when kdbus doesn't take our message without memfds, try again with memfds + - kdbus: generate correct bloom filter for matches + - implement translator service + - port systemd to new library + - implement busname unit type in systemd + - move to gvariant + - minimal locking around the memfd cache + - keep the connection fds around as long as the bus is open + - make ref counting atomic + - merge busctl into systemctl or so? + * in the final killing spree, detect processes from the root directory, and complain loudly if they have argv[0][0] == '@' set. https://bugzilla.redhat.com/show_bug.cgi?id=961044 diff --git a/src/libsystemd-bus/bus-error.c b/src/libsystemd-bus/bus-error.c index 5faa17384e..4696a88f76 100644 --- a/src/libsystemd-bus/bus-error.c +++ b/src/libsystemd-bus/bus-error.c @@ -142,6 +142,9 @@ int bus_error_to_errno(const sd_bus_error* e) { /* Better replce this with a gperf table */ + if (!e) + return -EIO; + if (!e->name) return -EIO; @@ -152,6 +155,30 @@ int bus_error_to_errno(const sd_bus_error* e) { streq(e->name, "org.freedesktop.DBus.Error.AccessDenied")) return -EPERM; + if (streq(e->name, "org.freedesktop.DBus.Error.InvalidArgs")) + return -EINVAL; + + if (streq(e->name, "org.freedesktop.DBus.Error.UnixProcessIdUnknown")) + return -ESRCH; + + if (streq(e->name, "org.freedesktop.DBus.Error.FileNotFound")) + return -ENOENT; + + if (streq(e->name, "org.freedesktop.DBus.Error.FileExists")) + return -EEXIST; + + if (streq(e->name, "org.freedesktop.DBus.Error.Timeout")) + return -ETIMEDOUT; + + if (streq(e->name, "org.freedesktop.DBus.Error.IOError")) + return -EIO; + + if (streq(e->name, "org.freedesktop.DBus.Error.Disconnected")) + return -ECONNRESET; + + if (streq(e->name, "org.freedesktop.DBus.Error.NotSupported")) + return -ENOTSUP; + return -EIO; } @@ -159,13 +186,54 @@ int bus_error_from_errno(sd_bus_error *e, int error) { if (!e) return error; - if (error == -ENOMEM) - sd_bus_error_set_const(e, "org.freedesktop.DBus.Error.NoMemory", strerror(-error)); - else if (error == -EPERM || error == -EACCES) - sd_bus_error_set_const(e, "org.freedesktop.DBus.Error.AccessDenied", strerror(-error)); - else - sd_bus_error_set_const(e, "org.freedesktop.DBus.Error.Failed", "Operation failed"); + switch (error) { + + case -ENOMEM: + sd_bus_error_set_const(e, "org.freedesktop.DBus.Error.NoMemory", "Out of memory"); + break; + + case -EPERM: + case -EACCES: + sd_bus_error_set_const(e, "org.freedesktop.DBus.Error.AccessDenied", "Access denied"); + break; + + case -EINVAL: + sd_bus_error_set_const(e, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid argument"); + break; + + case -ESRCH: + sd_bus_error_set_const(e, "org.freedesktop.DBus.Error.UnixProcessIdUnknown", "No such process"); + break; + + case -ENOENT: + sd_bus_error_set_const(e, "org.freedesktop.DBus.Error.FileNotFound", "File not found"); + break; + + case -EEXIST: + sd_bus_error_set_const(e, "org.freedesktop.DBus.Error.FileExists", "File exists"); + break; + + case -ETIMEDOUT: + case -ETIME: + sd_bus_error_set_const(e, "org.freedesktop.DBus.Error.Timeout", "Timed out"); + break; + + case -EIO: + sd_bus_error_set_const(e, "org.freedesktop.DBus.Error.IOError", "Input/output error"); + break; + + case -ENETRESET: + case -ECONNABORTED: + case -ECONNRESET: + sd_bus_error_set_const(e, "org.freedesktop.DBus.Error.Disconnected", "Disconnected"); + break; + + case -ENOTSUP: + sd_bus_error_set_const(e, "org.freedesktop.DBus.Error.NotSupported", "Not supported"); + break; + } + sd_bus_error_set_const(e, "org.freedesktop.DBus.Error.Failed", "Operation failed"); return error; } diff --git a/src/libsystemd-bus/bus-match.c b/src/libsystemd-bus/bus-match.c index 501a38df70..ed871d9d77 100644 --- a/src/libsystemd-bus/bus-match.c +++ b/src/libsystemd-bus/bus-match.c @@ -199,7 +199,6 @@ static bool value_node_same( int bus_match_run( sd_bus *bus, struct bus_match_node *node, - int ret, sd_bus_message *m) { @@ -230,7 +229,7 @@ int bus_match_run( * we won't call any. The children of the root node * are compares or leaves, they will automatically * call their siblings. */ - return bus_match_run(bus, node->child, ret, m); + return bus_match_run(bus, node->child, m); case BUS_MATCH_VALUE: @@ -240,7 +239,7 @@ int bus_match_run( * automatically call their siblings */ assert(node->child); - return bus_match_run(bus, node->child, ret, m); + return bus_match_run(bus, node->child, m); case BUS_MATCH_LEAF: @@ -257,11 +256,11 @@ int bus_match_run( /* Run the callback. And then invoke siblings. */ assert(node->leaf.callback); - r = node->leaf.callback(bus, ret, m, node->leaf.userdata); + r = node->leaf.callback(bus, m, node->leaf.userdata); if (r != 0) return r; - return bus_match_run(bus, node->next, ret, m); + return bus_match_run(bus, node->next, m); case BUS_MATCH_MESSAGE_TYPE: test_u8 = m->header->type; @@ -318,7 +317,7 @@ int bus_match_run( found = NULL; if (found) { - r = bus_match_run(bus, found, ret, m); + r = bus_match_run(bus, found, m); if (r != 0) return r; } @@ -331,7 +330,7 @@ int bus_match_run( if (!value_node_test(c, node->type, test_u8, test_str)) continue; - r = bus_match_run(bus, c, ret, m); + r = bus_match_run(bus, c, m); if (r != 0) return r; } @@ -341,7 +340,7 @@ int bus_match_run( return 0; /* And now, let's invoke our siblings */ - return bus_match_run(bus, node->next, ret, m); + return bus_match_run(bus, node->next, m); } static int bus_match_add_compare_value( diff --git a/src/libsystemd-bus/bus-match.h b/src/libsystemd-bus/bus-match.h index 075f1a9e3a..4d46cf9aff 100644 --- a/src/libsystemd-bus/bus-match.h +++ b/src/libsystemd-bus/bus-match.h @@ -69,7 +69,7 @@ struct bus_match_node { }; }; -int bus_match_run(sd_bus *bus, struct bus_match_node *root, int ret, sd_bus_message *m); +int bus_match_run(sd_bus *bus, struct bus_match_node *root, sd_bus_message *m); int bus_match_add(struct bus_match_node *root, const char *match, sd_bus_message_handler_t callback, void *userdata, struct bus_match_node **ret); int bus_match_remove(struct bus_match_node *root, const char *match, sd_bus_message_handler_t callback, void *userdata); diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c index dbb3337619..c72b52d546 100644 --- a/src/libsystemd-bus/bus-message.c +++ b/src/libsystemd-bus/bus-message.c @@ -623,6 +623,43 @@ fail: return r; } +int bus_message_new_synthetic_error( + sd_bus *bus, + uint64_t serial, + const sd_bus_error *e, + sd_bus_message **m) { + + sd_bus_message *t; + int r; + + assert(sd_bus_error_is_set(e)); + assert(m); + + t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_ERROR); + if (!t) + return -ENOMEM; + + t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED; + t->reply_serial = serial; + + r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial); + if (r < 0) + goto fail; + + if (bus && bus->unique_name) { + r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination); + if (r < 0) + goto fail; + } + + *m = t; + return 0; + +fail: + message_free(t); + return r; +} + sd_bus_message* sd_bus_message_ref(sd_bus_message *m) { if (!m) return NULL; @@ -4240,3 +4277,12 @@ int bus_header_message_size(struct bus_header *h, size_t *sum) { *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs; return 0; } + +int bus_message_to_errno(sd_bus_message *m) { + assert(m); + + if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR) + return 0; + + return bus_error_to_errno(&m->error); +} diff --git a/src/libsystemd-bus/bus-message.h b/src/libsystemd-bus/bus-message.h index 44390c6b50..2fb11ea3b1 100644 --- a/src/libsystemd-bus/bus-message.h +++ b/src/libsystemd-bus/bus-message.h @@ -235,3 +235,7 @@ struct bus_body_part *message_append_part(sd_bus_message *m); int bus_body_part_map(struct bus_body_part *part); void bus_body_part_unmap(struct bus_body_part *part); + +int bus_message_to_errno(sd_bus_message *m); + +int bus_message_new_synthetic_error(sd_bus *bus, uint64_t serial, const sd_bus_error *e, sd_bus_message **m); diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c index 2537ba52d5..7b937d9999 100644 --- a/src/libsystemd-bus/sd-bus.c +++ b/src/libsystemd-bus/sd-bus.c @@ -229,18 +229,18 @@ int sd_bus_set_anonymous(sd_bus *bus, int b) { return 0; } -static int hello_callback(sd_bus *bus, int error, sd_bus_message *reply, void *userdata) { +static int hello_callback(sd_bus *bus, sd_bus_message *reply, void *userdata) { const char *s; int r; assert(bus); assert(bus->state == BUS_HELLO); - - if (error != 0) - return -error; - assert(reply); + r = bus_message_to_errno(reply); + if (r < 0) + return r; + r = sd_bus_message_read(reply, "s", &s); if (r < 0) return r; @@ -1523,6 +1523,7 @@ int sd_bus_get_timeout(sd_bus *bus, uint64_t *timeout_usec) { } static int process_timeout(sd_bus *bus) { + _cleanup_bus_message_unref_ sd_bus_message* m = NULL; struct reply_callback *c; usec_t n; int r; @@ -1537,10 +1538,18 @@ static int process_timeout(sd_bus *bus) { if (c->timeout > n) return 0; + r = bus_message_new_synthetic_error( + bus, + c->serial, + &SD_BUS_ERROR_MAKE("org.freedesktop.DBus.Error.Timeout", "Timed out"), + &m); + if (r < 0) + return r; + assert_se(prioq_pop(bus->reply_callbacks_prioq) == c); hashmap_remove(bus->reply_callbacks, &c->serial); - r = c->callback(bus, ETIMEDOUT, NULL, c->userdata); + r = c->callback(bus, m, c->userdata); free(c); return r < 0 ? r : 1; @@ -1590,7 +1599,7 @@ static int process_reply(sd_bus *bus, sd_bus_message *m) { if (r < 0) return r; - r = c->callback(bus, 0, m, c->userdata); + r = c->callback(bus, m, c->userdata); free(c); return r; @@ -1621,7 +1630,7 @@ static int process_filter(sd_bus *bus, sd_bus_message *m) { if (r < 0) return r; - r = l->callback(bus, 0, m, l->userdata); + r = l->callback(bus, m, l->userdata); if (r != 0) return r; @@ -1641,7 +1650,7 @@ static int process_match(sd_bus *bus, sd_bus_message *m) { do { bus->match_callbacks_modified = false; - r = bus_match_run(bus, &bus->match_callbacks, 0, m); + r = bus_match_run(bus, &bus->match_callbacks, m); if (r != 0) return r; @@ -1734,7 +1743,7 @@ static int process_object(sd_bus *bus, sd_bus_message *m) { if (r < 0) return r; - r = c->callback(bus, 0, m, c->userdata); + r = c->callback(bus, m, c->userdata); if (r != 0) return r; @@ -1764,7 +1773,7 @@ static int process_object(sd_bus *bus, sd_bus_message *m) { if (r < 0) return r; - r = c->callback(bus, 0, m, c->userdata); + r = c->callback(bus, m, c->userdata); if (r != 0) return r; diff --git a/src/libsystemd-bus/test-bus-chat.c b/src/libsystemd-bus/test-bus-chat.c index f457c8f88a..f308eddbb0 100644 --- a/src/libsystemd-bus/test-bus-chat.c +++ b/src/libsystemd-bus/test-bus-chat.c @@ -35,17 +35,17 @@ #include "bus-match.h" #include "bus-internal.h" -static int match_callback(sd_bus *bus, int error, sd_bus_message *m, void *userdata) { +static int match_callback(sd_bus *bus, sd_bus_message *m, void *userdata) { log_info("Match triggered! interface=%s member=%s", strna(sd_bus_message_get_interface(m)), strna(sd_bus_message_get_member(m))); return 0; } -static int object_callback(sd_bus *bus, int error, sd_bus_message *m, void *userdata) { +static int object_callback(sd_bus *bus, sd_bus_message *m, void *userdata) { int r; assert(bus); - if (error != 0) + if (sd_bus_message_is_method_error(m, NULL)) return 0; if (sd_bus_message_is_method_call(m, "org.object.test", "Foobar")) { @@ -356,10 +356,10 @@ finish: return INT_TO_PTR(r); } -static int quit_callback(sd_bus *b, int ret, sd_bus_message *m, void *userdata) { +static int quit_callback(sd_bus *b, sd_bus_message *m, void *userdata) { bool *x = userdata; - log_error("Quit callback: %s", strerror(ret)); + log_error("Quit callback: %s", strerror(bus_message_to_errno(m))); *x = 1; return 1; diff --git a/src/libsystemd-bus/test-bus-match.c b/src/libsystemd-bus/test-bus-match.c index 9cf994009d..605d86a85c 100644 --- a/src/libsystemd-bus/test-bus-match.c +++ b/src/libsystemd-bus/test-bus-match.c @@ -30,7 +30,7 @@ static bool mask[32]; -static int filter(sd_bus *b, int ret, sd_bus_message *m, void *userdata) { +static int filter(sd_bus *b, sd_bus_message *m, void *userdata) { log_info("Ran %i", PTR_TO_INT(userdata)); mask[PTR_TO_INT(userdata)] = true; return 0; @@ -85,7 +85,7 @@ int main(int argc, char *argv[]) { assert_se(bus_message_seal(m, 1) >= 0); zero(mask); - assert_se(bus_match_run(NULL, &root, 0, m) == 0); + assert_se(bus_match_run(NULL, &root, m) == 0); assert_se(mask_contains((unsigned[]) { 9, 8, 7, 5, 10, 12, 13, 14 }, 8)); assert_se(bus_match_remove(&root, "member='waldo',path='/foo/bar'", filter, INT_TO_PTR(8)) > 0); @@ -95,7 +95,7 @@ int main(int argc, char *argv[]) { bus_match_dump(&root, 0); zero(mask); - assert_se(bus_match_run(NULL, &root, 0, m) == 0); + assert_se(bus_match_run(NULL, &root, m) == 0); assert_se(mask_contains((unsigned[]) { 9, 5, 10, 12, 14, 7 }, 6)); for (i = 0; i < _BUS_MATCH_NODE_TYPE_MAX; i++) { diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h index 4c3c26d611..85deacf63f 100644 --- a/src/systemd/sd-bus.h +++ b/src/systemd/sd-bus.h @@ -41,13 +41,6 @@ extern "C" { # endif #endif -/* TODO: - * - merge busctl into systemctl or so? - * - default policy (allow uid == 0 and our own uid) - * - enforce alignment of pointers passed in - * - negotiation for attach attributes - */ - typedef struct sd_bus sd_bus; typedef struct sd_bus_message sd_bus_message; @@ -57,7 +50,7 @@ typedef struct { int need_free; } sd_bus_error; -typedef int (*sd_bus_message_handler_t)(sd_bus *bus, int ret, sd_bus_message *m, void *userdata); +typedef int (*sd_bus_message_handler_t)(sd_bus *bus, sd_bus_message *m, void *userdata); /* Connections */ -- cgit v1.2.1 From e4ee6e5cc3e8e23e1ecc0d9fa756d9cc2534d218 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 16 May 2013 21:52:35 +0200 Subject: bus: make bus ref counting atomic This is preparation to allow sd_bus_message obejcts to be processed in a different thread from their originating sd_bus object. --- Makefile.am | 3 ++- TODO | 2 +- src/libsystemd-bus/bus-internal.h | 12 +++++++++++- src/libsystemd-bus/sd-bus.c | 10 +++------- src/shared/refcnt.h | 34 ++++++++++++++++++++++++++++++++++ 5 files changed, 51 insertions(+), 10 deletions(-) create mode 100644 src/shared/refcnt.h diff --git a/Makefile.am b/Makefile.am index 4c5e6fcdf1..526598277a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -695,7 +695,8 @@ libsystemd_shared_la_SOURCES = \ src/shared/fileio.h \ src/shared/output-mode.h \ src/shared/MurmurHash3.c \ - src/shared/MurmurHash3.h + src/shared/MurmurHash3.h \ + src/shared/refcnt.h #------------------------------------------------------------------------------- noinst_LTLIBRARIES += \ diff --git a/TODO b/TODO index 14ed4b43ca..19e53fe658 100644 --- a/TODO +++ b/TODO @@ -42,8 +42,8 @@ Features: - move to gvariant - minimal locking around the memfd cache - keep the connection fds around as long as the bus is open - - make ref counting atomic - merge busctl into systemctl or so? + - synthesize sd_bus_message objects from kernel messages * in the final killing spree, detect processes from the root directory, and complain loudly if they have argv[0][0] == '@' set. diff --git a/src/libsystemd-bus/bus-internal.h b/src/libsystemd-bus/bus-internal.h index 504dac7f09..0edb09764a 100644 --- a/src/libsystemd-bus/bus-internal.h +++ b/src/libsystemd-bus/bus-internal.h @@ -29,6 +29,7 @@ #include "prioq.h" #include "list.h" #include "util.h" +#include "refcnt.h" #include "sd-bus.h" #include "bus-error.h" @@ -77,7 +78,16 @@ enum bus_auth { }; struct sd_bus { - unsigned n_ref; + /* We use atomic ref counting here since sd_bus_message + objects retain references to their originating sd_bus but + we want to allow them to be processed in a different + thread. We won't provide full thread safety, but only the + bare minimum that makes it possible to use sd_bus and + sd_bus_message objects independently and on different + threads as long as each object is used only once at the + same time. */ + RefCount n_ref; + enum bus_state state; int input_fd, output_fd; int message_version; diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c index 7b937d9999..4a081778ac 100644 --- a/src/libsystemd-bus/sd-bus.c +++ b/src/libsystemd-bus/sd-bus.c @@ -103,7 +103,7 @@ int sd_bus_new(sd_bus **ret) { if (!r) return -ENOMEM; - r->n_ref = 1; + r->n_ref = REFCNT_INIT; r->input_fd = r->output_fd = -1; r->message_version = 1; r->negotiate_fds = true; @@ -934,9 +934,8 @@ sd_bus *sd_bus_ref(sd_bus *bus) { if (!bus) return NULL; - assert(bus->n_ref > 0); + assert_se(REFCNT_INC(bus->n_ref) >= 2); - bus->n_ref++; return bus; } @@ -944,10 +943,7 @@ sd_bus *sd_bus_unref(sd_bus *bus) { if (!bus) return NULL; - assert(bus->n_ref > 0); - bus->n_ref--; - - if (bus->n_ref <= 0) + if (REFCNT_DEC(bus->n_ref) <= 0) bus_free(bus); return NULL; diff --git a/src/shared/refcnt.h b/src/shared/refcnt.h new file mode 100644 index 0000000000..0502c20a2e --- /dev/null +++ b/src/shared/refcnt.h @@ -0,0 +1,34 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +/* A type-safe atomic refcounter */ + +typedef struct { + volatile unsigned _value; +} RefCount; + +#define REFCNT_GET(r) ((r)._value) +#define REFCNT_INC(r) (__sync_add_and_fetch(&(r)._value, 1)) +#define REFCNT_DEC(r) (__sync_sub_and_fetch(&(r)._value, 1)) + +#define REFCNT_INIT ((RefCount) { ._value = 1 }) -- cgit v1.2.1 From 0000ce05ed3e26a26552a0fc2ad82f7f7efd25a9 Mon Sep 17 00:00:00 2001 From: Lukas Nykryn Date: Thu, 16 May 2013 11:09:03 +0200 Subject: systemd-delta: add support for drop-in snippets --- TODO | 3 - man/systemd-delta.xml | 7 ++ src/delta/delta.c | 184 ++++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 170 insertions(+), 24 deletions(-) diff --git a/TODO b/TODO index 19e53fe658..6ca98a3d09 100644 --- a/TODO +++ b/TODO @@ -108,9 +108,6 @@ Features: kmod static-nodes call kmod as an early service, and drop CAP_MKNOD from udevd.service -* systemd-delta needs to be made aware of *.d/*.conf drop-in files for - units. - * seems that when we follow symlinks to units we prefer the symlink destination path over /etc and /usr. We shouldn't do that. Instead /etc should always override /run+/usr and also any symlink diff --git a/man/systemd-delta.xml b/man/systemd-delta.xml index 9293c9b462..0c7a54a09b 100644 --- a/man/systemd-delta.xml +++ b/man/systemd-delta.xml @@ -140,6 +140,13 @@ and changed files. + + extended + + Show *.conf files in drop-in + directories for units. + + unchanged diff --git a/src/delta/delta.c b/src/delta/delta.c index aec3dc8995..fa284bc274 100644 --- a/src/delta/delta.c +++ b/src/delta/delta.c @@ -31,6 +31,7 @@ #include "log.h" #include "pager.h" #include "build.h" +#include "strv.h" static bool arg_no_pager = false; static int arg_diff = -1; @@ -41,9 +42,10 @@ static enum { SHOW_REDIRECTED = 1 << 2, SHOW_OVERRIDDEN = 1 << 3, SHOW_UNCHANGED = 1 << 4, + SHOW_EXTENDED = 1 << 5, SHOW_DEFAULTS = - (SHOW_MASKED | SHOW_EQUIVALENT | SHOW_REDIRECTED | SHOW_OVERRIDDEN) + (SHOW_MASKED | SHOW_EQUIVALENT | SHOW_REDIRECTED | SHOW_OVERRIDDEN | SHOW_EXTENDED) } arg_flags = 0; static int equivalent(const char *a, const char *b) { @@ -92,6 +94,14 @@ static int notify_override_overridden(const char *top, const char *bottom) { return 1; } +static int notify_override_extended(const char *top, const char *bottom) { + if (!(arg_flags & SHOW_EXTENDED)) + return 0; + + printf(ANSI_HIGHLIGHT_ON "[EXTENDED]" ANSI_HIGHLIGHT_OFF " %s → %s\n", top, bottom); + return 1; +} + static int notify_override_unchanged(const char *f) { if (!(arg_flags & SHOW_UNCHANGED)) return 0; @@ -148,11 +158,114 @@ static int found_override(const char *top, const char *bottom) { return 0; } -static int enumerate_dir(Hashmap *top, Hashmap *bottom, const char *path) { +static int enumerate_dir_d(Hashmap *top, Hashmap *bottom, Hashmap *drops, const char *toppath, const char *drop) { + _cleanup_free_ char *conf = NULL; + _cleanup_free_ char *path = NULL; + _cleanup_strv_free_ char **list = NULL; + char **file; + char *c; + int r; + + path = strjoin(toppath, "/", drop, NULL); + if (!path) + return -ENOMEM; + + path_kill_slashes(path); + + conf = strdup(drop); + if (!conf) + return -ENOMEM; + + c = strrchr(conf, '.'); + if (!c) + return -EINVAL; + *c = 0; + + r = get_files_in_directory(path, &list); + if (r < 0){ + log_error("Failed to enumerate %s: %s", path, strerror(-r)); + return r; + } + + STRV_FOREACH(file, list) { + Hashmap *h; + int k; + char *p; + char *d; + + if (!endswith(*file, ".conf")) + continue; + + p = strjoin(path, "/", *file, NULL); + if (!p) + return -ENOMEM; + + path_kill_slashes(p); + + d = strrchr(p, '/'); + if (!d || d == p) { + free(p); + return -EINVAL; + } + d--; + d = strrchr(p, '/'); + + if (!d || d == p) { + free(p); + return -EINVAL; + } + + k = hashmap_put(top, d, p); + if (k >= 0) { + p = strdup(p); + if (!p) + return -ENOMEM; + d = strrchr(p, '/'); + d--; + d = strrchr(p, '/'); + } else if (k != -EEXIST) { + free(p); + return k; + } + + free(hashmap_remove(bottom, d)); + k = hashmap_put(bottom, d, p); + if (k < 0) { + free(p); + return k; + } + + h = hashmap_get(drops, conf); + if (!h) { + h = hashmap_new(string_hash_func, string_compare_func); + if (!h) + return -ENOMEM; + hashmap_put(drops, conf, h); + conf = strdup(conf); + if (!conf) + return -ENOMEM; + } + + p = strdup(p); + if (!p) + return -ENOMEM; + + k = hashmap_put(h, path_get_file_name(p), p); + if (k < 0) { + free(p); + if (k != -EEXIST) + return k; + } + } + return 0; +} + +static int enumerate_dir(Hashmap *top, Hashmap *bottom, Hashmap *drops, const char *path, bool dropins) { _cleanup_closedir_ DIR *d; assert(top); assert(bottom); + assert(drops); assert(path); d = opendir(path); @@ -177,6 +290,9 @@ static int enumerate_dir(Hashmap *top, Hashmap *bottom, const char *path) { if (!de) break; + if (dropins && de->d_type == DT_DIR && endswith(de->d_name, ".d")) + enumerate_dir_d(top, bottom, drops, path, de->d_name); + if (!dirent_is_file(de)) continue; @@ -207,12 +323,14 @@ static int enumerate_dir(Hashmap *top, Hashmap *bottom, const char *path) { return 0; } -static int process_suffix(const char *prefixes, const char *suffix) { +static int process_suffix(const char *prefixes, const char *suffix, bool dropins) { const char *p; char *f; - Hashmap *top, *bottom=NULL; + Hashmap *top, *bottom=NULL, *drops=NULL; + Hashmap *h; + char *key; int r = 0, k; - Iterator i; + Iterator i, j; int n_found = 0; assert(prefixes); @@ -230,6 +348,12 @@ static int process_suffix(const char *prefixes, const char *suffix) { goto finish; } + drops = hashmap_new(string_hash_func, string_compare_func); + if (!drops) { + r = -ENOMEM; + goto finish; + } + NULSTR_FOREACH(p, prefixes) { _cleanup_free_ char *t = NULL; @@ -239,29 +363,34 @@ static int process_suffix(const char *prefixes, const char *suffix) { goto finish; } - k = enumerate_dir(top, bottom, t); + k = enumerate_dir(top, bottom, drops, t, dropins); if (k < 0) r = k; log_debug("Looking at %s", t); } - HASHMAP_FOREACH(f, top, i) { + HASHMAP_FOREACH_KEY(f, key, top, i) { char *o; - o = hashmap_get(bottom, path_get_file_name(f)); + o = hashmap_get(bottom, key); assert(o); - if (path_equal(o, f)) { + if (path_equal(o, f)) notify_override_unchanged(f); - continue; + else { + k = found_override(f, o); + if (k < 0) + r = k; + n_found++; } - k = found_override(f, o); - if (k < 0) - r = k; - - n_found ++; + h = hashmap_get(drops, key); + if (h) + HASHMAP_FOREACH(o, h, j) { + notify_override_extended(f, o); + n_found++; + } } finish: @@ -269,25 +398,32 @@ finish: hashmap_free_free(top); if (bottom) hashmap_free_free(bottom); - + if (drops) { + HASHMAP_FOREACH_KEY(h, key, drops, i){ + hashmap_free_free(hashmap_remove(drops, key)); + hashmap_remove(drops, key); + free(key); + } + hashmap_free(drops); + } return r < 0 ? r : n_found; } -static int process_suffix_chop(const char *prefixes, const char *suffix) { +static int process_suffix_chop(const char *prefixes, const char *suffix, const char *have_dropins) { const char *p; assert(prefixes); assert(suffix); if (!path_is_absolute(suffix)) - return process_suffix(prefixes, suffix); + return process_suffix(prefixes, suffix, nulstr_contains(have_dropins, suffix)); /* Strip prefix from the suffix */ NULSTR_FOREACH(p, prefixes) { if (startswith(suffix, p)) { suffix += strlen(p); suffix += strspn(suffix, "/"); - return process_suffix(prefixes, suffix); + return process_suffix(prefixes, suffix, nulstr_contains(have_dropins, suffix)); } } @@ -322,6 +458,8 @@ static int parse_flags(const char *flag_str, int flags) { flags |= SHOW_OVERRIDDEN; else if (strneq("unchanged", w, l)) flags |= SHOW_UNCHANGED; + else if (strneq("extended", w, l)) + flags |= SHOW_EXTENDED; else if (strneq("default", w, l)) flags |= SHOW_DEFAULTS; else @@ -435,6 +573,10 @@ int main(int argc, char *argv[]) { "udev/rules.d\0" "modprobe.d\0"; + const char have_dropins[] = + "systemd/system\0" + "systemd/user\0"; + int r = 0, k; int n_found = 0; @@ -460,7 +602,7 @@ int main(int argc, char *argv[]) { int i; for (i = optind; i < argc; i++) { - k = process_suffix_chop(prefixes, argv[i]); + k = process_suffix_chop(prefixes, argv[i], have_dropins); if (k < 0) r = k; else @@ -471,7 +613,7 @@ int main(int argc, char *argv[]) { const char *n; NULSTR_FOREACH(n, suffixes) { - k = process_suffix(prefixes, n); + k = process_suffix(prefixes, n, nulstr_contains(have_dropins, n)); if (k < 0) r = k; else -- cgit v1.2.1 From 8fd57568e6e82aafe153ec1f34cca36c9ccee455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 15 May 2013 20:42:22 -0400 Subject: systemd-delta: count overrides only of the requested type --- src/delta/delta.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/src/delta/delta.c b/src/delta/delta.c index fa284bc274..49c2fc323a 100644 --- a/src/delta/delta.c +++ b/src/delta/delta.c @@ -118,24 +118,20 @@ static int found_override(const char *top, const char *bottom) { assert(top); assert(bottom); - if (null_or_empty_path(top) > 0) { - notify_override_masked(top, bottom); - return 0; - } + if (null_or_empty_path(top) > 0) + return notify_override_masked(top, bottom); k = readlink_malloc(top, &dest); if (k >= 0) { if (equivalent(dest, bottom) > 0) - notify_override_equivalent(top, bottom); + return notify_override_equivalent(top, bottom); else - notify_override_redirected(top, bottom); - - return 0; + return notify_override_redirected(top, bottom); } - notify_override_overridden(top, bottom); + k = notify_override_overridden(top, bottom); if (!arg_diff) - return 0; + return k; putchar('\n'); @@ -155,7 +151,7 @@ static int found_override(const char *top, const char *bottom) { putchar('\n'); - return 0; + return k; } static int enumerate_dir_d(Hashmap *top, Hashmap *bottom, Hashmap *drops, const char *toppath, const char *drop) { @@ -382,15 +378,14 @@ static int process_suffix(const char *prefixes, const char *suffix, bool dropins k = found_override(f, o); if (k < 0) r = k; - n_found++; + else + n_found += k; } h = hashmap_get(drops, key); if (h) - HASHMAP_FOREACH(o, h, j) { - notify_override_extended(f, o); - n_found++; - } + HASHMAP_FOREACH(o, h, j) + n_found += notify_override_extended(f, o); } finish: @@ -622,7 +617,8 @@ int main(int argc, char *argv[]) { } if (r >= 0) - printf("\n%i overridden configuration files found.\n", n_found); + printf("%s%i overridden configuration files found.\n", + n_found ? "\n" : "", n_found); finish: pager_close(); -- cgit v1.2.1 From f54514f3542db9b1f1a6f7546472718ce0d02aae Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 17 May 2013 02:22:37 +0200 Subject: bus: keep kernel bus fd around during entire life-time of bus We need this since we might need to invoke the release ioctl for messages. Since we don't want to add any locking for that we simply keep a reference to the bus and then rely that the fd stays valid all the time. --- src/libsystemd-bus/bus-internal.h | 7 +++- src/libsystemd-bus/bus-message.c | 6 +-- src/libsystemd-bus/sd-bus.c | 81 ++++++++++++++++++--------------------- 3 files changed, 47 insertions(+), 47 deletions(-) diff --git a/src/libsystemd-bus/bus-internal.h b/src/libsystemd-bus/bus-internal.h index 0edb09764a..5ba32ad8fd 100644 --- a/src/libsystemd-bus/bus-internal.h +++ b/src/libsystemd-bus/bus-internal.h @@ -68,9 +68,14 @@ enum bus_state { BUS_OPENING, BUS_AUTHENTICATING, BUS_HELLO, - BUS_RUNNING + BUS_RUNNING, + BUS_CLOSED }; +static inline bool BUS_IS_OPEN(enum bus_state state) { + return state > BUS_UNSET && state < BUS_CLOSED; +} + enum bus_auth { _BUS_AUTH_INVALID, BUS_AUTH_EXTERNAL, diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c index c72b52d546..e531dec5cd 100644 --- a/src/libsystemd-bus/bus-message.c +++ b/src/libsystemd-bus/bus-message.c @@ -128,14 +128,14 @@ static void message_free(sd_bus_message *m) { if (m->release_kdbus) ioctl(m->bus->input_fd, KDBUS_CMD_MSG_RELEASE, m->kdbus); + if (m->bus) + sd_bus_unref(m->bus); + if (m->free_fds) { close_many(m->fds, m->n_fds); free(m->fds); } - if (m->bus) - sd_bus_unref(m->bus); - if (m->iovec != m->iovec_fixed) free(m->iovec); diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c index 4a081778ac..08ab202baf 100644 --- a/src/libsystemd-bus/sd-bus.c +++ b/src/libsystemd-bus/sd-bus.c @@ -43,6 +43,18 @@ static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec); +static void bus_close_fds(sd_bus *b) { + assert(b); + + if (b->input_fd >= 0) + close_nointr_nofail(b->input_fd); + + if (b->output_fd >= 0 && b->output_fd != b->input_fd) + close_nointr_nofail(b->output_fd); + + b->input_fd = b->output_fd = -1; +} + static void bus_free(sd_bus *b) { struct filter_callback *f; struct object_callback *c; @@ -50,7 +62,7 @@ static void bus_free(sd_bus *b) { assert(b); - sd_bus_close(b); + bus_close_fds(b); free(b->rbuffer); free(b->unique_name); @@ -922,12 +934,19 @@ void sd_bus_close(sd_bus *bus) { if (!bus) return; - if (bus->input_fd >= 0) - close_nointr_nofail(bus->input_fd); - if (bus->output_fd >= 0 && bus->output_fd != bus->input_fd) - close_nointr_nofail(bus->output_fd); + if (bus->state != BUS_CLOSED) + return; + + bus->state = BUS_CLOSED; - bus->input_fd = bus->output_fd = -1; + if (!bus->is_kernel) + bus_close_fds(bus); + + /* We'll leave the fd open in case this is a kernel bus, since + * there might still be memblocks around that reference this + * bus, and they might need to invoke the + * KDBUS_CMD_MSG_RELEASE ioctl on the fd when they are + * freed. */ } sd_bus *sd_bus_ref(sd_bus *bus) { @@ -953,7 +972,7 @@ int sd_bus_is_open(sd_bus *bus) { if (!bus) return -EINVAL; - return bus->state != BUS_UNSET && bus->input_fd >= 0; + return BUS_IS_OPEN(bus->state); } int sd_bus_can_send(sd_bus *bus, char type) { @@ -961,7 +980,7 @@ int sd_bus_can_send(sd_bus *bus, char type) { if (!bus) return -EINVAL; - if (bus->output_fd < 0) + if (bus->state == BUS_UNSET) return -ENOTCONN; if (type == SD_BUS_TYPE_UNIX_FD) { @@ -1012,9 +1031,6 @@ static int dispatch_wqueue(sd_bus *bus) { assert(bus); assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO); - if (bus->output_fd < 0) - return -ENOTCONN; - while (bus->wqueue_size > 0) { if (bus->is_kernel) @@ -1059,9 +1075,6 @@ static int dispatch_rqueue(sd_bus *bus, sd_bus_message **m) { assert(m); assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO); - if (bus->input_fd < 0) - return -ENOTCONN; - if (bus->rqueue_size > 0) { /* Dispatch a queued message */ @@ -1097,9 +1110,7 @@ int sd_bus_send(sd_bus *bus, sd_bus_message *m, uint64_t *serial) { if (!bus) return -EINVAL; - if (bus->state == BUS_UNSET) - return -ENOTCONN; - if (bus->output_fd < 0) + if (!BUS_IS_OPEN(bus->state)) return -ENOTCONN; if (!m) return -EINVAL; @@ -1210,9 +1221,7 @@ int sd_bus_send_with_reply( if (!bus) return -EINVAL; - if (bus->state == BUS_UNSET) - return -ENOTCONN; - if (bus->output_fd < 0) + if (!BUS_IS_OPEN(bus->state)) return -ENOTCONN; if (!m) return -EINVAL; @@ -1294,11 +1303,8 @@ int bus_ensure_running(sd_bus *bus) { assert(bus); - if (bus->input_fd < 0) - return -ENOTCONN; - if (bus->state == BUS_UNSET) + if (bus->state == BUS_UNSET || bus->state == BUS_CLOSED) return -ENOTCONN; - if (bus->state == BUS_RUNNING) return 1; @@ -1331,9 +1337,7 @@ int sd_bus_send_with_reply_and_block( if (!bus) return -EINVAL; - if (bus->output_fd < 0) - return -ENOTCONN; - if (bus->state == BUS_UNSET) + if (!BUS_IS_OPEN(bus->state)) return -ENOTCONN; if (!m) return -EINVAL; @@ -1449,7 +1453,7 @@ int sd_bus_send_with_reply_and_block( int sd_bus_get_fd(sd_bus *bus) { if (!bus) return -EINVAL; - if (bus->input_fd < 0) + if (!BUS_IS_OPEN(bus->state)) return -ENOTCONN; if (bus->input_fd != bus->output_fd) return -EPERM; @@ -1462,9 +1466,7 @@ int sd_bus_get_events(sd_bus *bus) { if (!bus) return -EINVAL; - if (bus->state == BUS_UNSET) - return -ENOTCONN; - if (bus->input_fd < 0) + if (!BUS_IS_OPEN(bus->state)) return -ENOTCONN; if (bus->state == BUS_OPENING) @@ -1493,9 +1495,7 @@ int sd_bus_get_timeout(sd_bus *bus, uint64_t *timeout_usec) { return -EINVAL; if (!timeout_usec) return -EINVAL; - if (bus->state == BUS_UNSET) - return -ENOTCONN; - if (bus->input_fd < 0) + if (!BUS_IS_OPEN(bus->state)) return -ENOTCONN; if (bus->state == BUS_AUTHENTICATING) { @@ -1992,8 +1992,6 @@ int sd_bus_process(sd_bus *bus, sd_bus_message **ret) { if (!bus) return -EINVAL; - if (bus->input_fd < 0) - return -ENOTCONN; /* We don't allow recursively invoking sd_bus_process(). */ if (bus->processing) @@ -2002,6 +2000,7 @@ int sd_bus_process(sd_bus *bus, sd_bus_message **ret) { switch (bus->state) { case BUS_UNSET: + case BUS_CLOSED: return -ENOTCONN; case BUS_OPENING: @@ -2042,7 +2041,7 @@ static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec) { assert(bus); - if (bus->input_fd < 0) + if (!BUS_IS_OPEN(bus->state)) return -ENOTCONN; e = sd_bus_get_events(bus); @@ -2088,9 +2087,7 @@ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec) { if (!bus) return -EINVAL; - if (bus->state == BUS_UNSET) - return -ENOTCONN; - if (bus->input_fd < 0) + if (!BUS_IS_OPEN(bus->state)) return -ENOTCONN; if (bus->rqueue_size > 0) return 0; @@ -2103,9 +2100,7 @@ int sd_bus_flush(sd_bus *bus) { if (!bus) return -EINVAL; - if (bus->state == BUS_UNSET) - return -ENOTCONN; - if (bus->output_fd < 0) + if (!BUS_IS_OPEN(bus->state)) return -ENOTCONN; r = bus_ensure_running(bus); -- cgit v1.2.1 From 63edf05ed9c1d4cb5cf9364e734b2a96f84622d0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 17 May 2013 02:32:32 +0200 Subject: bus: actually unmap kdbus pool after use --- src/libsystemd-bus/bus-kernel.c | 2 -- src/libsystemd-bus/bus-kernel.h | 4 ++++ src/libsystemd-bus/sd-bus.c | 4 ++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index 8ef5752b31..ede78d7bef 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -45,8 +45,6 @@ #define KDBUS_ITEM_HEADER_SIZE offsetof(struct kdbus_item, data) #define KDBUS_ITEM_SIZE(s) ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE) -#define KDBUS_POOL_SIZE (4*1024*1024) - static int parse_unique_name(const char *s, uint64_t *id) { int r; diff --git a/src/libsystemd-bus/bus-kernel.h b/src/libsystemd-bus/bus-kernel.h index 1651c1e41d..8cf153ab41 100644 --- a/src/libsystemd-bus/bus-kernel.h +++ b/src/libsystemd-bus/bus-kernel.h @@ -33,6 +33,10 @@ * sending vectors */ #define MEMFD_MIN_SIZE (32*1024) +/* The size of the per-connection memory pool that we set up and where + * the kernel places our incoming messages */ +#define KDBUS_POOL_SIZE (16*1024*1024) + struct memfd_cache { int fd; void *address; diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c index 08ab202baf..b0730d4954 100644 --- a/src/libsystemd-bus/sd-bus.c +++ b/src/libsystemd-bus/sd-bus.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "util.h" #include "macro.h" @@ -64,6 +65,9 @@ static void bus_free(sd_bus *b) { bus_close_fds(b); + if (b->kdbus_buffer) + munmap(b->kdbus_buffer, KDBUS_POOL_SIZE); + free(b->rbuffer); free(b->unique_name); free(b->auth_buffer); -- cgit v1.2.1 From d5a2b9a6f455468a0f29483303657ab4fd7013d8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 17 May 2013 02:50:00 +0200 Subject: bus: return ECHILD as soon as people try to reuse a bus connection across a fork() --- TODO | 4 +- src/libsystemd-bus/bus-control.c | 30 ++++++++++++++ src/libsystemd-bus/bus-internal.h | 4 ++ src/libsystemd-bus/sd-bus.c | 86 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 121 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index 6ca98a3d09..f609b4b5a0 100644 --- a/TODO +++ b/TODO @@ -29,11 +29,13 @@ Fedora 19: Features: +* libsystemd-journal: + - return ECHILD as soon as somebody tries to reuse a journal object across a fork() + * libsystemd-bus: - default policy (allow uid == 0 and our own uid) - enforce alignment of pointers passed in - negotiation for attach attributes - - verify that the PID doesn't change for existing busses - when kdbus doesn't take our message without memfds, try again with memfds - kdbus: generate correct bloom filter for matches - implement translator service diff --git a/src/libsystemd-bus/bus-control.c b/src/libsystemd-bus/bus-control.c index a4dc9bf511..177bd882ad 100644 --- a/src/libsystemd-bus/bus-control.c +++ b/src/libsystemd-bus/bus-control.c @@ -40,6 +40,8 @@ int sd_bus_get_unique_name(sd_bus *bus, const char **unique) { return -EINVAL; if (!unique) return -EINVAL; + if (bus_pid_changed(bus)) + return -ECHILD; r = bus_ensure_running(bus); if (r < 0) @@ -60,6 +62,10 @@ int sd_bus_request_name(sd_bus *bus, const char *name, int flags) { return -EINVAL; if (!bus->bus_client) return -EINVAL; + if (!BUS_IS_OPEN(bus->state)) + return -ENOTCONN; + if (bus_pid_changed(bus)) + return -ECHILD; if (bus->is_kernel) { struct kdbus_cmd_name *n; @@ -114,6 +120,10 @@ int sd_bus_release_name(sd_bus *bus, const char *name) { return -EINVAL; if (!bus->bus_client) return -EINVAL; + if (!BUS_IS_OPEN(bus->state)) + return -ENOTCONN; + if (bus_pid_changed(bus)) + return -ECHILD; if (bus->is_kernel) { struct kdbus_cmd_name *n; @@ -163,6 +173,10 @@ int sd_bus_list_names(sd_bus *bus, char ***l) { return -EINVAL; if (!l) return -EINVAL; + if (!BUS_IS_OPEN(bus->state)) + return -ENOTCONN; + if (bus_pid_changed(bus)) + return -ECHILD; r = sd_bus_call_method( bus, @@ -213,6 +227,10 @@ int sd_bus_get_owner(sd_bus *bus, const char *name, char **owner) { return -EINVAL; if (!name) return -EINVAL; + if (!BUS_IS_OPEN(bus->state)) + return -ENOTCONN; + if (bus_pid_changed(bus)) + return -ECHILD; r = sd_bus_call_method( bus, @@ -255,6 +273,10 @@ int sd_bus_get_owner_uid(sd_bus *bus, const char *name, uid_t *uid) { return -EINVAL; if (!uid) return -EINVAL; + if (!BUS_IS_OPEN(bus->state)) + return -ENOTCONN; + if (bus_pid_changed(bus)) + return -ECHILD; r = sd_bus_call_method( bus, @@ -288,6 +310,10 @@ int sd_bus_get_owner_pid(sd_bus *bus, const char *name, pid_t *pid) { return -EINVAL; if (!pid) return -EINVAL; + if (!BUS_IS_OPEN(bus->state)) + return -ENOTCONN; + if (bus_pid_changed(bus)) + return -ECHILD; r = sd_bus_call_method( bus, @@ -354,6 +380,10 @@ int sd_bus_get_owner_machine_id(sd_bus *bus, const char *name, sd_id128_t *machi return -EINVAL; if (!name) return -EINVAL; + if (!BUS_IS_OPEN(bus->state)) + return -ENOTCONN; + if (bus_pid_changed(bus)) + return -ECHILD; if (streq_ptr(name, bus->unique_name)) return sd_id128_get_machine(machine); diff --git a/src/libsystemd-bus/bus-internal.h b/src/libsystemd-bus/bus-internal.h index 5ba32ad8fd..b6975c54a2 100644 --- a/src/libsystemd-bus/bus-internal.h +++ b/src/libsystemd-bus/bus-internal.h @@ -171,6 +171,8 @@ struct sd_bus { struct memfd_cache memfd_cache[MEMFD_CACHE_MAX]; unsigned n_memfd_cache; + + pid_t original_pid; }; static inline void bus_unrefp(sd_bus **b) { @@ -217,3 +219,5 @@ const char *bus_message_type_to_string(uint8_t u); int bus_ensure_running(sd_bus *bus); int bus_start_running(sd_bus *bus); int bus_next_address(sd_bus *bus); + +bool bus_pid_changed(sd_bus *bus); diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c index b0730d4954..fd19ff32b0 100644 --- a/src/libsystemd-bus/sd-bus.c +++ b/src/libsystemd-bus/sd-bus.c @@ -123,6 +123,7 @@ int sd_bus_new(sd_bus **ret) { r->input_fd = r->output_fd = -1; r->message_version = 1; r->negotiate_fds = true; + r->original_pid = getpid(); /* We guarantee that wqueue always has space for at least one * entry */ @@ -145,6 +146,8 @@ int sd_bus_set_address(sd_bus *bus, const char *address) { return -EPERM; if (!address) return -EINVAL; + if (bus_pid_changed(bus)) + return -ECHILD; a = strdup(address); if (!a) @@ -165,6 +168,8 @@ int sd_bus_set_fd(sd_bus *bus, int input_fd, int output_fd) { return -EINVAL; if (output_fd < 0) return -EINVAL; + if (bus_pid_changed(bus)) + return -ECHILD; bus->input_fd = input_fd; bus->output_fd = output_fd; @@ -182,6 +187,8 @@ int sd_bus_set_exec(sd_bus *bus, const char *path, char *const argv[]) { return -EINVAL; if (strv_isempty(argv)) return -EINVAL; + if (bus_pid_changed(bus)) + return -ECHILD; p = strdup(path); if (!p) @@ -207,6 +214,8 @@ int sd_bus_set_bus_client(sd_bus *bus, int b) { return -EINVAL; if (bus->state != BUS_UNSET) return -EPERM; + if (bus_pid_changed(bus)) + return -ECHILD; bus->bus_client = !!b; return 0; @@ -217,6 +226,8 @@ int sd_bus_set_negotiate_fds(sd_bus *bus, int b) { return -EINVAL; if (bus->state != BUS_UNSET) return -EPERM; + if (bus_pid_changed(bus)) + return -ECHILD; bus->negotiate_fds = !!b; return 0; @@ -229,6 +240,8 @@ int sd_bus_set_server(sd_bus *bus, int b, sd_id128_t server_id) { return -EINVAL; if (bus->state != BUS_UNSET) return -EPERM; + if (bus_pid_changed(bus)) + return -ECHILD; bus->is_server = !!b; bus->server_id = server_id; @@ -240,6 +253,8 @@ int sd_bus_set_anonymous(sd_bus *bus, int b) { return -EINVAL; if (bus->state != BUS_UNSET) return -EPERM; + if (bus_pid_changed(bus)) + return -ECHILD; bus->anonymous_auth = !!b; return 0; @@ -828,6 +843,8 @@ int sd_bus_start(sd_bus *bus) { return -EINVAL; if (bus->state != BUS_UNSET) return -EPERM; + if (bus_pid_changed(bus)) + return -ECHILD; bus->state = BUS_OPENING; @@ -937,8 +954,9 @@ fail: void sd_bus_close(sd_bus *bus) { if (!bus) return; - - if (bus->state != BUS_CLOSED) + if (bus->state == BUS_CLOSED) + return; + if (bus_pid_changed(bus)) return; bus->state = BUS_CLOSED; @@ -975,6 +993,8 @@ sd_bus *sd_bus_unref(sd_bus *bus) { int sd_bus_is_open(sd_bus *bus) { if (!bus) return -EINVAL; + if (bus_pid_changed(bus)) + return -ECHILD; return BUS_IS_OPEN(bus->state); } @@ -986,6 +1006,8 @@ int sd_bus_can_send(sd_bus *bus, char type) { return -EINVAL; if (bus->state == BUS_UNSET) return -ENOTCONN; + if (bus_pid_changed(bus)) + return -ECHILD; if (type == SD_BUS_TYPE_UNIX_FD) { if (!bus->negotiate_fds) @@ -1008,6 +1030,8 @@ int sd_bus_get_server_id(sd_bus *bus, sd_id128_t *server_id) { return -EINVAL; if (!server_id) return -EINVAL; + if (bus_pid_changed(bus)) + return -ECHILD; r = bus_ensure_running(bus); if (r < 0) @@ -1118,6 +1142,8 @@ int sd_bus_send(sd_bus *bus, sd_bus_message *m, uint64_t *serial) { return -ENOTCONN; if (!m) return -EINVAL; + if (bus_pid_changed(bus)) + return -ECHILD; if (m->n_fds > 0) { r = sd_bus_can_send(bus, SD_BUS_TYPE_UNIX_FD); @@ -1235,6 +1261,8 @@ int sd_bus_send_with_reply( return -EINVAL; if (m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) return -EINVAL; + if (bus_pid_changed(bus)) + return -ECHILD; r = hashmap_ensure_allocated(&bus->reply_callbacks, uint64_hash_func, uint64_compare_func); if (r < 0) @@ -1290,6 +1318,8 @@ int sd_bus_send_with_reply_cancel(sd_bus *bus, uint64_t serial) { return -EINVAL; if (serial == 0) return -EINVAL; + if (bus_pid_changed(bus)) + return -ECHILD; c = hashmap_remove(bus->reply_callbacks, &serial); if (!c) @@ -1351,6 +1381,8 @@ int sd_bus_send_with_reply_and_block( return -EINVAL; if (bus_error_is_dirty(error)) return -EINVAL; + if (bus_pid_changed(bus)) + return -ECHILD; r = bus_ensure_running(bus); if (r < 0) @@ -1461,6 +1493,8 @@ int sd_bus_get_fd(sd_bus *bus) { return -ENOTCONN; if (bus->input_fd != bus->output_fd) return -EPERM; + if (bus_pid_changed(bus)) + return -ECHILD; return bus->input_fd; } @@ -1472,6 +1506,8 @@ int sd_bus_get_events(sd_bus *bus) { return -EINVAL; if (!BUS_IS_OPEN(bus->state)) return -ENOTCONN; + if (bus_pid_changed(bus)) + return -ECHILD; if (bus->state == BUS_OPENING) flags |= POLLOUT; @@ -1501,6 +1537,8 @@ int sd_bus_get_timeout(sd_bus *bus, uint64_t *timeout_usec) { return -EINVAL; if (!BUS_IS_OPEN(bus->state)) return -ENOTCONN; + if (bus_pid_changed(bus)) + return -ECHILD; if (bus->state == BUS_AUTHENTICATING) { *timeout_usec = bus->auth_timeout; @@ -1996,6 +2034,8 @@ int sd_bus_process(sd_bus *bus, sd_bus_message **ret) { if (!bus) return -EINVAL; + if (bus_pid_changed(bus)) + return -ECHILD; /* We don't allow recursively invoking sd_bus_process(). */ if (bus->processing) @@ -2093,6 +2133,9 @@ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec) { return -EINVAL; if (!BUS_IS_OPEN(bus->state)) return -ENOTCONN; + if (bus_pid_changed(bus)) + return -ECHILD; + if (bus->rqueue_size > 0) return 0; @@ -2106,6 +2149,8 @@ int sd_bus_flush(sd_bus *bus) { return -EINVAL; if (!BUS_IS_OPEN(bus->state)) return -ENOTCONN; + if (bus_pid_changed(bus)) + return -ECHILD; r = bus_ensure_running(bus); if (r < 0) @@ -2135,6 +2180,8 @@ int sd_bus_add_filter(sd_bus *bus, sd_bus_message_handler_t callback, void *user return -EINVAL; if (!callback) return -EINVAL; + if (bus_pid_changed(bus)) + return -ECHILD; f = new0(struct filter_callback, 1); if (!f) @@ -2154,6 +2201,8 @@ int sd_bus_remove_filter(sd_bus *bus, sd_bus_message_handler_t callback, void *u return -EINVAL; if (!callback) return -EINVAL; + if (bus_pid_changed(bus)) + return -ECHILD; LIST_FOREACH(callbacks, f, bus->filter_callbacks) { if (f->callback == callback && f->userdata == userdata) { @@ -2183,6 +2232,8 @@ static int bus_add_object( return -EINVAL; if (!callback) return -EINVAL; + if (bus_pid_changed(bus)) + return -ECHILD; r = hashmap_ensure_allocated(&bus->object_callbacks, string_hash_func, string_compare_func); if (r < 0) @@ -2228,6 +2279,8 @@ static int bus_remove_object( return -EINVAL; if (!callback) return -EINVAL; + if (bus_pid_changed(bus)) + return -ECHILD; c = hashmap_get(bus->object_callbacks, path); if (!c) @@ -2268,6 +2321,8 @@ int sd_bus_add_match(sd_bus *bus, const char *match, sd_bus_message_handler_t ca return -EINVAL; if (!match) return -EINVAL; + if (bus_pid_changed(bus)) + return -ECHILD; if (bus->bus_client) { r = bus_add_match_internal(bus, match); @@ -2295,6 +2350,8 @@ int sd_bus_remove_match(sd_bus *bus, const char *match, sd_bus_message_handler_t return -EINVAL; if (!match) return -EINVAL; + if (bus_pid_changed(bus)) + return -ECHILD; if (bus->bus_client) r = bus_remove_match_internal(bus, match); @@ -2322,6 +2379,10 @@ int sd_bus_emit_signal( if (!bus) return -EINVAL; + if (!BUS_IS_OPEN(bus->state)) + return -ENOTCONN; + if (bus_pid_changed(bus)) + return -ECHILD; r = sd_bus_message_new_signal(bus, path, interface, member, &m); if (r < 0) @@ -2352,6 +2413,10 @@ int sd_bus_call_method( if (!bus) return -EINVAL; + if (!BUS_IS_OPEN(bus->state)) + return -ENOTCONN; + if (bus_pid_changed(bus)) + return -ECHILD; r = sd_bus_message_new_method_call(bus, destination, path, interface, member, &m); if (r < 0) @@ -2383,6 +2448,10 @@ int sd_bus_reply_method_return( return -EPERM; if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL) return -EINVAL; + if (!BUS_IS_OPEN(bus->state)) + return -ENOTCONN; + if (bus_pid_changed(bus)) + return -ECHILD; if (call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) return 0; @@ -2418,6 +2487,10 @@ int sd_bus_reply_method_error( return -EINVAL; if (!sd_bus_error_is_set(e)) return -EINVAL; + if (!BUS_IS_OPEN(bus->state)) + return -ENOTCONN; + if (bus_pid_changed(bus)) + return -ECHILD; if (call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) return 0; @@ -2428,3 +2501,12 @@ int sd_bus_reply_method_error( return sd_bus_send(bus, m, NULL); } + +bool bus_pid_changed(sd_bus *bus) { + assert(bus); + + /* We don't support people creating a bus connection and + * keeping it around over a fork(). Let's complain. */ + + return bus->original_pid != getpid(); +} -- cgit v1.2.1 From 45fbe937d7ca8d0da9ea276d57bc70ebd41c285e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 17 May 2013 03:13:58 +0200 Subject: bus: add minimal locking around the memfd cache We want to allow clients to process an sd_bus_message on a different thread than it was received on. Since unreffing a bus message might readd some of its memfds to the memfd cache add some minimal locking around the cache. --- Makefile.am | 4 ++++ TODO | 1 - src/libsystemd-bus/bus-internal.h | 8 ++++++++ src/libsystemd-bus/bus-kernel.c | 35 ++++++++++++++++++++++++++++------- src/libsystemd-bus/sd-bus.c | 5 +++++ 5 files changed, 45 insertions(+), 8 deletions(-) diff --git a/Makefile.am b/Makefile.am index 526598277a..66f12e9037 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1749,6 +1749,10 @@ libsystemd_bus_la_LIBADD = \ libsystemd-shared.la \ libsystemd-daemon.la +libsystemd_bus_la_CFLAGS = \ + $(AM_CFLAGS) \ + -pthread + noinst_LTLIBRARIES += \ libsystemd-bus.la diff --git a/TODO b/TODO index f609b4b5a0..390106aadf 100644 --- a/TODO +++ b/TODO @@ -42,7 +42,6 @@ Features: - port systemd to new library - implement busname unit type in systemd - move to gvariant - - minimal locking around the memfd cache - keep the connection fds around as long as the bus is open - merge busctl into systemctl or so? - synthesize sd_bus_message objects from kernel messages diff --git a/src/libsystemd-bus/bus-internal.h b/src/libsystemd-bus/bus-internal.h index b6975c54a2..8f87bea781 100644 --- a/src/libsystemd-bus/bus-internal.h +++ b/src/libsystemd-bus/bus-internal.h @@ -24,6 +24,7 @@ #include #include #include +#include #include "hashmap.h" #include "prioq.h" @@ -169,6 +170,13 @@ struct sd_bus { void *kdbus_buffer; + /* We do locking around the memfd cache, since we want to + * allow people to process a sd_bus_message in a different + * thread then it was generated on and free it there. Since + * adding something to the memfd cache might happen when a + * message is released, we hence need to protect this bit with + * a mutex. */ + pthread_mutex_t memfd_cache_mutex; struct memfd_cache memfd_cache[MEMFD_CACHE_MAX]; unsigned n_memfd_cache; diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index ede78d7bef..699d24185e 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -721,6 +721,7 @@ int bus_kernel_create(const char *name, char **s) { int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) { struct memfd_cache *c; + int fd; assert(address); assert(size); @@ -728,8 +729,12 @@ int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) { if (!bus || !bus->is_kernel) return -ENOTSUP; + assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) == 0); + if (bus->n_memfd_cache <= 0) { - int fd, r; + int r; + + assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) == 0); r = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, &fd); if (r < 0) @@ -747,8 +752,18 @@ int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) { *address = c->address; *size = c->size; + fd = c->fd; + + assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) == 0); - return c->fd; + return fd; +} + +static void close_and_munmap(int fd, void *address, size_t size) { + if (size > 0) + assert_se(munmap(address, PAGE_ALIGN(size)) == 0); + + close_nointr_nofail(fd); } void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) { @@ -757,13 +772,17 @@ void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) { assert(fd >= 0); assert(size == 0 || address); - if (!bus || !bus->is_kernel || - bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) { + if (!bus || !bus->is_kernel) { + close_and_munmap(fd, address, size); + return; + } + + assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) == 0); - if (size > 0) - assert_se(munmap(address, PAGE_ALIGN(size)) == 0); + if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) { + assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) == 0); - close_nointr_nofail(fd); + close_and_munmap(fd, address, size); return; } @@ -780,6 +799,8 @@ void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) { c->size = MEMFD_CACHE_ITEM_SIZE_MAX; } else c->size = size; + + assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) == 0); } void bus_kernel_flush_memfd(sd_bus *b) { diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c index fd19ff32b0..5e66a31162 100644 --- a/src/libsystemd-bus/sd-bus.c +++ b/src/libsystemd-bus/sd-bus.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "util.h" #include "macro.h" @@ -106,6 +107,8 @@ static void bus_free(sd_bus *b) { bus_kernel_flush_memfd(b); + assert_se(pthread_mutex_destroy(&b->memfd_cache_mutex) == 0); + free(b); } @@ -125,6 +128,8 @@ int sd_bus_new(sd_bus **ret) { r->negotiate_fds = true; r->original_pid = getpid(); + assert_se(pthread_mutex_init(&r->memfd_cache_mutex, NULL) == 0); + /* We guarantee that wqueue always has space for at least one * entry */ r->wqueue = new(sd_bus_message*, 1); -- cgit v1.2.1 From 264ad849a4a0acf1ca392da62b7018d4fe7b66b3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 17 May 2013 04:25:56 +0200 Subject: bus: add APIs for negotiating what is attached to messages --- TODO | 2 - src/libsystemd-bus/bus-internal.h | 3 +- src/libsystemd-bus/bus-kernel.c | 12 +---- src/libsystemd-bus/bus-socket.c | 12 +++-- src/libsystemd-bus/sd-bus.c | 92 ++++++++++++++++++++++++++++++++++-- src/libsystemd-bus/test-bus-kernel.c | 16 +++++++ src/libsystemd-bus/test-bus-server.c | 4 +- src/shared/macro.h | 3 ++ src/stdio-bridge/stdio-bridge.c | 4 +- src/systemd/sd-bus.h | 9 +++- 10 files changed, 130 insertions(+), 27 deletions(-) diff --git a/TODO b/TODO index 390106aadf..fb5f0c3813 100644 --- a/TODO +++ b/TODO @@ -35,14 +35,12 @@ Features: * libsystemd-bus: - default policy (allow uid == 0 and our own uid) - enforce alignment of pointers passed in - - negotiation for attach attributes - when kdbus doesn't take our message without memfds, try again with memfds - kdbus: generate correct bloom filter for matches - implement translator service - port systemd to new library - implement busname unit type in systemd - move to gvariant - - keep the connection fds around as long as the bus is open - merge busctl into systemctl or so? - synthesize sd_bus_message objects from kernel messages diff --git a/src/libsystemd-bus/bus-internal.h b/src/libsystemd-bus/bus-internal.h index 8f87bea781..e775b09419 100644 --- a/src/libsystemd-bus/bus-internal.h +++ b/src/libsystemd-bus/bus-internal.h @@ -99,7 +99,6 @@ struct sd_bus { int message_version; bool is_kernel:1; - bool negotiate_fds:1; bool can_fds:1; bool bus_client:1; bool ucred_valid:1; @@ -181,6 +180,8 @@ struct sd_bus { unsigned n_memfd_cache; pid_t original_pid; + + uint64_t hello_flags; }; static inline void bus_unrefp(sd_bus **b) { diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index 699d24185e..107b2bd694 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -345,15 +345,7 @@ int bus_kernel_take_fd(sd_bus *b) { } hello->size = sizeof(h); - hello->conn_flags = - KDBUS_HELLO_ACCEPT_FD| - KDBUS_HELLO_ATTACH_COMM| - KDBUS_HELLO_ATTACH_EXE| - KDBUS_HELLO_ATTACH_CMDLINE| - KDBUS_HELLO_ATTACH_CGROUP| - KDBUS_HELLO_ATTACH_CAPS| - KDBUS_HELLO_ATTACH_SECLABEL| - KDBUS_HELLO_ATTACH_AUDIT; + hello->conn_flags = b->hello_flags; hello->items[0].type = KDBUS_HELLO_POOL; hello->items[0].size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec); @@ -378,7 +370,7 @@ int bus_kernel_take_fd(sd_bus *b) { b->is_kernel = true; b->bus_client = true; - b->can_fds = true; + b->can_fds = !!(hello->conn_flags & KDBUS_HELLO_ACCEPT_FD); r = bus_start_running(b); if (r < 0) diff --git a/src/libsystemd-bus/bus-socket.c b/src/libsystemd-bus/bus-socket.c index befded7079..b60facb20f 100644 --- a/src/libsystemd-bus/bus-socket.c +++ b/src/libsystemd-bus/bus-socket.c @@ -181,7 +181,7 @@ static int bus_socket_auth_verify_client(sd_bus *b) { if (!e) return 0; - if (b->negotiate_fds) { + if (b->hello_flags & KDBUS_HELLO_ACCEPT_FD) { f = memmem(e + 2, b->rbuffer_size - (e - (char*) b->rbuffer) - 2, "\r\n", 2); if (!f) return 0; @@ -464,7 +464,7 @@ static int bus_socket_auth_verify_server(sd_bus *b) { r = bus_socket_auth_write_ok(b); } } else if (line_equals(line, l, "NEGOTIATE_UNIX_FD")) { - if (b->auth == _BUS_AUTH_INVALID || !b->negotiate_fds) + if (b->auth == _BUS_AUTH_INVALID || !(b->hello_flags & KDBUS_HELLO_ACCEPT_FD)) r = bus_socket_auth_write(b, "ERROR\r\n"); else { b->can_fds = true; @@ -610,6 +610,8 @@ static int bus_socket_setup(sd_bus *b) { * socket, just in case. */ enable = !b->bus_client; setsockopt(b->input_fd, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable)); + + enable = !b->bus_client && (b->hello_flags & KDBUS_HELLO_ATTACH_SECLABEL); setsockopt(b->input_fd, SOL_SOCKET, SO_PASSSEC, &enable, sizeof(enable)); /* Increase the buffers to a MB */ @@ -651,7 +653,7 @@ static int bus_socket_start_auth_client(sd_bus *b) { if (!b->auth_buffer) return -ENOMEM; - if (b->negotiate_fds) + if (b->hello_flags & KDBUS_HELLO_ACCEPT_FD) auth_suffix = "\r\nNEGOTIATE_UNIX_FD\r\nBEGIN\r\n"; else auth_suffix = "\r\nBEGIN\r\n"; @@ -673,11 +675,11 @@ static int bus_socket_start_auth(sd_bus *b) { b->auth_timeout = now(CLOCK_MONOTONIC) + BUS_DEFAULT_TIMEOUT; if (sd_is_socket(b->input_fd, AF_UNIX, 0, 0) <= 0) - b->negotiate_fds = false; + b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD; if (b->output_fd != b->input_fd) if (sd_is_socket(b->output_fd, AF_UNIX, 0, 0) <= 0) - b->negotiate_fds = false; + b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD; if (b->is_server) return bus_socket_read_auth(b); diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c index 5e66a31162..6033aa744f 100644 --- a/src/libsystemd-bus/sd-bus.c +++ b/src/libsystemd-bus/sd-bus.c @@ -125,7 +125,7 @@ int sd_bus_new(sd_bus **ret) { r->n_ref = REFCNT_INIT; r->input_fd = r->output_fd = -1; r->message_version = 1; - r->negotiate_fds = true; + r->hello_flags |= KDBUS_HELLO_ACCEPT_FD; r->original_pid = getpid(); assert_se(pthread_mutex_init(&r->memfd_cache_mutex, NULL) == 0); @@ -226,7 +226,7 @@ int sd_bus_set_bus_client(sd_bus *bus, int b) { return 0; } -int sd_bus_set_negotiate_fds(sd_bus *bus, int b) { +int sd_bus_negotiate_fds(sd_bus *bus, int b) { if (!bus) return -EINVAL; if (bus->state != BUS_UNSET) @@ -234,7 +234,91 @@ int sd_bus_set_negotiate_fds(sd_bus *bus, int b) { if (bus_pid_changed(bus)) return -ECHILD; - bus->negotiate_fds = !!b; + SET_FLAG(bus->hello_flags, KDBUS_HELLO_ACCEPT_FD, b); + return 0; +} + +int sd_bus_negotiate_attach_comm(sd_bus *bus, int b) { + if (!bus) + return -EINVAL; + if (bus->state != BUS_UNSET) + return -EPERM; + if (bus_pid_changed(bus)) + return -ECHILD; + + SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_COMM, b); + return 0; +} + +int sd_bus_negotiate_attach_exe(sd_bus *bus, int b) { + if (!bus) + return -EINVAL; + if (bus->state != BUS_UNSET) + return -EPERM; + if (bus_pid_changed(bus)) + return -ECHILD; + + SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_EXE, b); + return 0; +} + +int sd_bus_negotiate_attach_cmdline(sd_bus *bus, int b) { + if (!bus) + return -EINVAL; + if (bus->state != BUS_UNSET) + return -EPERM; + if (bus_pid_changed(bus)) + return -ECHILD; + + SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_CMDLINE, b); + return 0; +} + +int sd_bus_negotiate_attach_cgroup(sd_bus *bus, int b) { + if (!bus) + return -EINVAL; + if (bus->state != BUS_UNSET) + return -EPERM; + if (bus_pid_changed(bus)) + return -ECHILD; + + SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_CGROUP, b); + return 0; +} + +int sd_bus_negotiate_attach_caps(sd_bus *bus, int b) { + if (!bus) + return -EINVAL; + if (bus->state != BUS_UNSET) + return -EPERM; + if (bus_pid_changed(bus)) + return -ECHILD; + + SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_CAPS, b); + return 0; +} + +int sd_bus_negotiate_attach_selinux_context(sd_bus *bus, int b) { + if (!bus) + return -EINVAL; + if (bus->state != BUS_UNSET) + return -EPERM; + if (bus_pid_changed(bus)) + return -ECHILD; + + SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_SECLABEL, b); + return 0; +} + +int sd_bus_negotiate_attach_audit(sd_bus *bus, int b) { + if (!bus) + return -EINVAL; + if (bus->state != BUS_UNSET) + return -EPERM; + if (bus_pid_changed(bus)) + return -ECHILD; + + SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_AUDIT, b); return 0; } @@ -1015,7 +1099,7 @@ int sd_bus_can_send(sd_bus *bus, char type) { return -ECHILD; if (type == SD_BUS_TYPE_UNIX_FD) { - if (!bus->negotiate_fds) + if (!(bus->hello_flags & KDBUS_HELLO_ACCEPT_FD)) return 0; r = bus_ensure_running(bus); diff --git a/src/libsystemd-bus/test-bus-kernel.c b/src/libsystemd-bus/test-bus-kernel.c index 72514a3dee..b8e89e41bc 100644 --- a/src/libsystemd-bus/test-bus-kernel.c +++ b/src/libsystemd-bus/test-bus-kernel.c @@ -60,6 +60,22 @@ int main(int argc, char *argv[]) { r = sd_bus_set_address(b, address); assert_se(r >= 0); + assert_se(sd_bus_negotiate_attach_comm(a, 1) >= 0); + assert_se(sd_bus_negotiate_attach_exe(a, 1) >= 0); + assert_se(sd_bus_negotiate_attach_cmdline(a, 1) >= 0); + assert_se(sd_bus_negotiate_attach_cgroup(a, 1) >= 0); + assert_se(sd_bus_negotiate_attach_caps(a, 1) >= 0); + assert_se(sd_bus_negotiate_attach_selinux_context(a, 1) >= 0); + assert_se(sd_bus_negotiate_attach_audit(a, 1) >= 0); + + assert_se(sd_bus_negotiate_attach_comm(b, 1) >= 0); + assert_se(sd_bus_negotiate_attach_exe(b, 1) >= 0); + assert_se(sd_bus_negotiate_attach_cmdline(b, 1) >= 0); + assert_se(sd_bus_negotiate_attach_cgroup(b, 1) >= 0); + assert_se(sd_bus_negotiate_attach_caps(b, 1) >= 0); + assert_se(sd_bus_negotiate_attach_selinux_context(b, 1) >= 0); + assert_se(sd_bus_negotiate_attach_audit(b, 1) >= 0); + r = sd_bus_start(a); assert_se(r >= 0); diff --git a/src/libsystemd-bus/test-bus-server.c b/src/libsystemd-bus/test-bus-server.c index a9772624f2..ef26a65d87 100644 --- a/src/libsystemd-bus/test-bus-server.c +++ b/src/libsystemd-bus/test-bus-server.c @@ -55,8 +55,8 @@ static void *server(void *p) { assert_se(sd_bus_new(&bus) >= 0); assert_se(sd_bus_set_fd(bus, c->fds[0], c->fds[0]) >= 0); assert_se(sd_bus_set_server(bus, 1, id) >= 0); - assert_se(sd_bus_set_negotiate_fds(bus, c->server_negotiate_unix_fds) >= 0); assert_se(sd_bus_set_anonymous(bus, c->server_anonymous_auth) >= 0); + assert_se(sd_bus_negotiate_fds(bus, c->server_negotiate_unix_fds) >= 0); assert_se(sd_bus_start(bus) >= 0); while (!quit) { @@ -134,7 +134,7 @@ static int client(struct context *c) { assert_se(sd_bus_new(&bus) >= 0); assert_se(sd_bus_set_fd(bus, c->fds[1], c->fds[1]) >= 0); - assert_se(sd_bus_set_negotiate_fds(bus, c->client_negotiate_unix_fds) >= 0); + assert_se(sd_bus_negotiate_fds(bus, c->client_negotiate_unix_fds) >= 0); assert_se(sd_bus_set_anonymous(bus, c->client_anonymous_auth) >= 0); assert_se(sd_bus_start(bus) >= 0); diff --git a/src/shared/macro.h b/src/shared/macro.h index 2f151bcc8c..bfe03f2ae0 100644 --- a/src/shared/macro.h +++ b/src/shared/macro.h @@ -284,4 +284,7 @@ do { \ sizeof(type) <= 4 ? 10 : \ sizeof(type) <= 8 ? 20 : sizeof(int[-2*(sizeof(type) > 8)]))) +#define SET_FLAG(v, flag, b) \ + (v) = (b) ? ((v) | (flag)) : ((v) & ~(flag)) + #include "log.h" diff --git a/src/stdio-bridge/stdio-bridge.c b/src/stdio-bridge/stdio-bridge.c index a5bdb03416..ab1a43ab1a 100644 --- a/src/stdio-bridge/stdio-bridge.c +++ b/src/stdio-bridge/stdio-bridge.c @@ -68,7 +68,7 @@ int main(int argc, char *argv[]) { goto finish; } - r = sd_bus_set_negotiate_fds(a, is_unix); + r = sd_bus_negotiate_fds(a, is_unix); if (r < 0) { log_error("Failed to set FD negotiation: %s", strerror(-r)); goto finish; @@ -104,7 +104,7 @@ int main(int argc, char *argv[]) { goto finish; } - r = sd_bus_set_negotiate_fds(b, is_unix); + r = sd_bus_negotiate_fds(b, is_unix); if (r < 0) { log_error("Failed to set FD negotiation: %s", strerror(-r)); goto finish; diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h index 85deacf63f..eeca69dd1a 100644 --- a/src/systemd/sd-bus.h +++ b/src/systemd/sd-bus.h @@ -64,7 +64,14 @@ int sd_bus_set_exec(sd_bus *bus, const char *path, char *const argv[]); int sd_bus_set_bus_client(sd_bus *bus, int b); int sd_bus_set_server(sd_bus *bus, int b, sd_id128_t server_id); int sd_bus_set_anonymous(sd_bus *bus, int b); -int sd_bus_set_negotiate_fds(sd_bus *bus, int b); +int sd_bus_negotiate_fds(sd_bus *bus, int b); +int sd_bus_negotiate_attach_comm(sd_bus *bus, int b); +int sd_bus_negotiate_attach_exe(sd_bus *bus, int b); +int sd_bus_negotiate_attach_cmdline(sd_bus *bus, int b); +int sd_bus_negotiate_attach_cgroup(sd_bus *bus, int b); +int sd_bus_negotiate_attach_caps(sd_bus *bus, int b); +int sd_bus_negotiate_attach_selinux_context(sd_bus *bus, int b); +int sd_bus_negotiate_attach_audit(sd_bus *bus, int b); int sd_bus_start(sd_bus *ret); void sd_bus_close(sd_bus *bus); -- cgit v1.2.1 From 2b3e18de74ca89b374dd4f7a2c30e5731d347841 Mon Sep 17 00:00:00 2001 From: Karol Lewandowski Date: Thu, 16 May 2013 10:40:03 +0200 Subject: Make it possible to disable smack separately from xattr support Additionally, compile out rule loading if feature is disabled. --- configure.ac | 26 ++++++++++++++++++++++++++ src/core/smack-setup.c | 10 ++++++++++ src/core/socket.c | 4 ++-- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 65186a45ab..14a90c56d0 100644 --- a/configure.ac +++ b/configure.ac @@ -444,6 +444,31 @@ fi AC_SUBST(XATTR_LIBS) AM_CONDITIONAL([HAVE_XATTR], [test "x$have_xattr" != xno]) +# ------------------------------------------------------------------------------ +AC_ARG_ENABLE([smack], AS_HELP_STRING([--disable-smack],[Disable optional SMACK support]), + [case "${enableval}" in + yes) have_smack=yes ;; + no) have_smack=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --disable-smack) ;; + esac], + [have_smack=auto]) + +if test "x${have_xattr}" = xno; then + if test "x${have_smack}" = xyes; then + AC_MSG_ERROR(SMACK requires xattr support) + else + have_smack=no + fi +else + if test "x${have_smack}" = xauto; then + have_smack=yes + fi +fi + +if test "x${have_smack}" = xyes ; then + AC_DEFINE(HAVE_SMACK, 1, [Define if SMACK is available]) +fi + # ------------------------------------------------------------------------------ AC_ARG_ENABLE([gcrypt], AS_HELP_STRING([--disable-gcrypt],[Disable optional GCRYPT support]), @@ -915,6 +940,7 @@ AC_MSG_RESULT([ AUDIT: ${have_audit} IMA: ${have_ima} SELinux: ${have_selinux} + SMACK: ${have_smack} XZ: ${have_xz} ACL: ${have_acl} XATTR: ${have_xattr} diff --git a/src/core/smack-setup.c b/src/core/smack-setup.c index 73eeb04190..d67a84a583 100644 --- a/src/core/smack-setup.c +++ b/src/core/smack-setup.c @@ -42,6 +42,8 @@ #define SMACK_CONFIG "/etc/smack/accesses.d/" #define CIPSO_CONFIG "/etc/smack/cipso/" +#ifdef HAVE_SMACK + static int write_rules(const char* dstpath, const char* srcdir) { _cleanup_fclose_ FILE *dst = NULL; _cleanup_closedir_ DIR *dir = NULL; @@ -111,8 +113,12 @@ static int write_rules(const char* dstpath, const char* srcdir) { return r; } +#endif int smack_setup(void) { + +#ifdef HAVE_SMACK + int r; r = write_rules("/sys/fs/smackfs/load2", SMACK_CONFIG); @@ -148,4 +154,8 @@ int smack_setup(void) { strerror(abs(r))); return 0; } + +#endif + + return 0; } diff --git a/src/core/socket.c b/src/core/socket.c index 1b08f0a5fd..37ca228e6b 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -788,7 +788,7 @@ static void socket_apply_socket_options(Socket *s, int fd) { if (setsockopt(fd, SOL_TCP, TCP_CONGESTION, s->tcp_congestion, strlen(s->tcp_congestion)+1) < 0) log_warning_unit(UNIT(s)->id, "TCP_CONGESTION failed: %m"); -#ifdef HAVE_XATTR +#ifdef HAVE_SMACK if (s->smack_ip_in) if (fsetxattr(fd, "security.SMACK64IPIN", s->smack_ip_in, strlen(s->smack_ip_in), 0) < 0) log_error_unit(UNIT(s)->id, @@ -810,7 +810,7 @@ static void socket_apply_fifo_options(Socket *s, int fd) { log_warning_unit(UNIT(s)->id, "F_SETPIPE_SZ: %m"); -#ifdef HAVE_XATTR +#ifdef HAVE_SMACK if (s->smack) if (fsetxattr(fd, "security.SMACK64", s->smack, strlen(s->smack), 0) < 0) log_error_unit(UNIT(s)->id, -- cgit v1.2.1 From 16af1d3922e1382c26b1beba38ddb22581c49f3b Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 17 May 2013 23:25:31 +0200 Subject: bus: do not pass a pointer but a uint64_t address in RECV --- src/libsystemd-bus/bus-kernel.c | 4 +++- src/libsystemd-bus/kdbus.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index 107b2bd694..50b28e7281 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -639,19 +639,21 @@ fail: } int bus_kernel_read_message(sd_bus *bus, sd_bus_message **m) { + uint64_t addr; struct kdbus_msg *k; int r; assert(bus); assert(m); - r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &k); + r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &addr); if (r < 0) { if (errno == EAGAIN) return 0; return -errno; } + k = UINT64_TO_PTR(addr); r = bus_kernel_make_message(bus, k, m); if (r <= 0) diff --git a/src/libsystemd-bus/kdbus.h b/src/libsystemd-bus/kdbus.h index 20b804539b..214bf51197 100644 --- a/src/libsystemd-bus/kdbus.h +++ b/src/libsystemd-bus/kdbus.h @@ -405,7 +405,7 @@ enum kdbus_cmd { /* kdbus ep node commands: require connected state */ KDBUS_CMD_MSG_SEND = _IOWR(KDBUS_IOC_MAGIC, 0x40, struct kdbus_msg), - KDBUS_CMD_MSG_RECV = _IOWR(KDBUS_IOC_MAGIC, 0x41, struct kdbus_msg *), + KDBUS_CMD_MSG_RECV = _IOWR(KDBUS_IOC_MAGIC, 0x41, __u64 *), KDBUS_CMD_MSG_RELEASE = _IOWR(KDBUS_IOC_MAGIC, 0x42, struct kdbus_msg), KDBUS_CMD_NAME_ACQUIRE = _IOWR(KDBUS_IOC_MAGIC, 0x50, struct kdbus_cmd_name), -- cgit v1.2.1 From 12f25b6e741bc8394f63778598fc203e3f6d4ae6 Mon Sep 17 00:00:00 2001 From: David Strauss Date: Sat, 18 May 2013 02:28:25 -0700 Subject: Standardize on 'file system' and 'namespace' in man pages. This change is based on existing usage in systemd and online. 'File-system' may make sense in adjectival form, but man pages seem to prefer 'file system' even in those situations. --- man/daemon.xml | 2 +- man/systemd.exec.xml | 4 ++-- man/systemd.unit.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/man/daemon.xml b/man/daemon.xml index 0d29e7aa1c..1283799473 100644 --- a/man/daemon.xml +++ b/man/daemon.xml @@ -905,7 +905,7 @@ fi sd_listen_fds() returns a positive value), skip the socket creation step and use the passed sockets. Secondly, ensure - that the file-system socket nodes for local + that the file system socket nodes for local AF_UNIX sockets used in the socket-based activation are not removed when the daemon shuts down, if sockets have been diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index b3e0287d72..ab1712efeb 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -1068,10 +1068,10 @@ InaccessibleDirectories= Sets up a new - file-system name space for executed + file system namespace for executed processes. These options may be used to limit access a process might have - to the main file-system + to the main file system hierarchy. Each setting takes a space-separated list of absolute directory paths. Directories listed in diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index 5ab988178d..6a5eefb6db 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -195,7 +195,7 @@ in a both simpler and more flexible system. Some unit names reflect paths existing in the - file system name space. Example: a device unit + file system namespace. Example: a device unit dev-sda.device refers to a device with the device node /dev/sda in the file system namespace. If this applies a special -- cgit v1.2.1 From c78196699d3d805b2237896a1d2b8efeec6068d0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 19 May 2013 18:39:08 +0200 Subject: bus: calculate bloom filter for match Yay! Filtering using kernel bloom filter matches works now! Yippieh! --- TODO | 2 + src/libsystemd-bus/bus-control.c | 183 ++++++++++++++++++++++++++++++----- src/libsystemd-bus/bus-control.h | 4 +- src/libsystemd-bus/bus-internal.h | 2 + src/libsystemd-bus/bus-kernel.c | 15 +-- src/libsystemd-bus/bus-kernel.h | 13 +++ src/libsystemd-bus/bus-match.c | 77 ++++++--------- src/libsystemd-bus/bus-match.h | 14 ++- src/libsystemd-bus/sd-bus.c | 49 ++++++---- src/libsystemd-bus/test-bus-kernel.c | 15 +-- src/libsystemd-bus/test-bus-match.c | 64 ++++++++---- 11 files changed, 306 insertions(+), 132 deletions(-) diff --git a/TODO b/TODO index fb5f0c3813..561e7ceb39 100644 --- a/TODO +++ b/TODO @@ -43,6 +43,8 @@ Features: - move to gvariant - merge busctl into systemctl or so? - synthesize sd_bus_message objects from kernel messages + - properly implement name registry ioctls for kdbus + - get rid of object hash table, use decision tree instead? * in the final killing spree, detect processes from the root directory, and complain loudly if they have argv[0][0] == '@' set. diff --git a/src/libsystemd-bus/bus-control.c b/src/libsystemd-bus/bus-control.c index 177bd882ad..ae0d7f9767 100644 --- a/src/libsystemd-bus/bus-control.c +++ b/src/libsystemd-bus/bus-control.c @@ -32,6 +32,7 @@ #include "bus-internal.h" #include "bus-message.h" #include "bus-control.h" +#include "bus-bloom.h" int sd_bus_get_unique_name(sd_bus *bus, const char **unique) { int r; @@ -339,36 +340,174 @@ int sd_bus_get_owner_pid(sd_bus *bus, const char *name, pid_t *pid) { return 0; } -int bus_add_match_internal(sd_bus *bus, const char *match) { +int bus_add_match_internal( + sd_bus *bus, + const char *match, + struct bus_match_component *components, + unsigned n_components, + uint64_t cookie) { + + int r; + assert(bus); assert(match); - return sd_bus_call_method( - bus, - "org.freedesktop.DBus", - "/", - "org.freedesktop.DBus", - "AddMatch", - NULL, - NULL, - "s", - match); + if (bus->is_kernel) { + struct kdbus_cmd_match *m; + struct kdbus_item *item; + uint64_t bloom[BLOOM_SIZE/8]; + size_t sz; + const char *sender = NULL; + size_t sender_length = 0; + uint64_t src_id = KDBUS_MATCH_SRC_ID_ANY; + bool using_bloom = false; + unsigned i; + + zero(bloom); + + sz = offsetof(struct kdbus_cmd_match, items); + + for (i = 0; i < n_components; i++) { + struct bus_match_component *c = &components[i]; + + switch (c->type) { + + case BUS_MATCH_SENDER: + r = bus_kernel_parse_unique_name(c->value_str, &src_id); + if (r < 0) + return r; + + if (r > 0) { + sender = c->value_str; + sender_length = strlen(sender); + sz += ALIGN8(offsetof(struct kdbus_item, str) + sender_length + 1); + } + + break; + + case BUS_MATCH_DESTINATION: + /* The bloom filter does not include + the destination, since it is only + available for broadcast messages + which do not carry a destination + since they are undirected. */ + break; + + case BUS_MATCH_INTERFACE: + bloom_add_pair(bloom, "interface", c->value_str); + using_bloom = true; + break; + + case BUS_MATCH_MEMBER: + bloom_add_pair(bloom, "member", c->value_str); + using_bloom = true; + break; + + case BUS_MATCH_PATH: + bloom_add_pair(bloom, "path", c->value_str); + using_bloom = true; + break; + + case BUS_MATCH_PATH_NAMESPACE: + bloom_add_pair(bloom, "path-slash-prefix", c->value_str); + using_bloom = true; + break; + + case BUS_MATCH_ARG...BUS_MATCH_ARG_LAST: + case BUS_MATCH_ARG_PATH...BUS_MATCH_ARG_PATH_LAST: + case BUS_MATCH_ARG_NAMESPACE...BUS_MATCH_ARG_NAMESPACE_LAST: + case BUS_MATCH_MESSAGE_TYPE: + assert_not_reached("FIXME!"); + break; + + case BUS_MATCH_ROOT: + case BUS_MATCH_VALUE: + case BUS_MATCH_LEAF: + case _BUS_MATCH_NODE_TYPE_MAX: + case _BUS_MATCH_NODE_TYPE_INVALID: + assert_not_reached("Invalid match type?"); + } + } + + if (using_bloom) + sz += ALIGN8(offsetof(struct kdbus_item, data64) + BLOOM_SIZE); + + m = alloca0(sz); + m->size = sz; + m->cookie = cookie; + m->src_id = src_id; + + item = m->items; + + if (using_bloom) { + item->size = offsetof(struct kdbus_item, data64) + BLOOM_SIZE; + item->type = KDBUS_MATCH_BLOOM; + memcpy(item->data64, bloom, BLOOM_SIZE); + + item = KDBUS_ITEM_NEXT(item); + } + + if (sender) { + item->size = offsetof(struct kdbus_item, str) + sender_length + 1; + item->type = KDBUS_MATCH_SRC_NAME; + memcpy(item->str, sender, sender_length + 1); + } + + r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m); + if (r < 0) + return -errno; + + } else { + return sd_bus_call_method( + bus, + "org.freedesktop.DBus", + "/", + "org.freedesktop.DBus", + "AddMatch", + NULL, + NULL, + "s", + match); + } + + return 0; } -int bus_remove_match_internal(sd_bus *bus, const char *match) { +int bus_remove_match_internal( + sd_bus *bus, + const char *match, + uint64_t cookie) { + + int r; + assert(bus); assert(match); - return sd_bus_call_method( - bus, - "org.freedesktop.DBus", - "/", - "org.freedesktop.DBus", - "RemoveMatch", - NULL, - NULL, - "s", - match); + if (bus->is_kernel) { + struct kdbus_cmd_match m; + + zero(m); + m.size = offsetof(struct kdbus_cmd_match, items); + m.cookie = cookie; + + r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_REMOVE, &m); + if (r < 0) + return -errno; + + } else { + return sd_bus_call_method( + bus, + "org.freedesktop.DBus", + "/", + "org.freedesktop.DBus", + "RemoveMatch", + NULL, + NULL, + "s", + match); + } + + return 0; } int sd_bus_get_owner_machine_id(sd_bus *bus, const char *name, sd_id128_t *machine) { diff --git a/src/libsystemd-bus/bus-control.h b/src/libsystemd-bus/bus-control.h index 34ecb260c3..2cac5d83ae 100644 --- a/src/libsystemd-bus/bus-control.h +++ b/src/libsystemd-bus/bus-control.h @@ -23,5 +23,5 @@ #include "sd-bus.h" -int bus_add_match_internal(sd_bus *bus, const char *match); -int bus_remove_match_internal(sd_bus *bus, const char *match); +int bus_add_match_internal(sd_bus *bus, const char *match, struct bus_match_component *components, unsigned n_components, uint64_t cookie); +int bus_remove_match_internal(sd_bus *bus, const char *match, uint64_t cookie); diff --git a/src/libsystemd-bus/bus-internal.h b/src/libsystemd-bus/bus-internal.h index e775b09419..147a83c045 100644 --- a/src/libsystemd-bus/bus-internal.h +++ b/src/libsystemd-bus/bus-internal.h @@ -182,6 +182,8 @@ struct sd_bus { pid_t original_pid; uint64_t hello_flags; + + uint64_t match_cookie; }; static inline void bus_unrefp(sd_bus **b) { diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index 50b28e7281..33c25a4fd9 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -34,18 +34,7 @@ #include "bus-kernel.h" #include "bus-bloom.h" -#define KDBUS_ITEM_NEXT(item) \ - (typeof(item))(((uint8_t *)item) + ALIGN8((item)->size)) - -#define KDBUS_ITEM_FOREACH(item, head) \ - for (item = (head)->items; \ - (uint8_t *)(item) < (uint8_t *)(head) + (head)->size; \ - item = KDBUS_ITEM_NEXT(item)) - -#define KDBUS_ITEM_HEADER_SIZE offsetof(struct kdbus_item, data) -#define KDBUS_ITEM_SIZE(s) ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE) - -static int parse_unique_name(const char *s, uint64_t *id) { +int bus_kernel_parse_unique_name(const char *s, uint64_t *id) { int r; assert(s); @@ -215,7 +204,7 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) { return 0; if (m->destination) { - r = parse_unique_name(m->destination, &unique); + r = bus_kernel_parse_unique_name(m->destination, &unique); if (r < 0) return r; diff --git a/src/libsystemd-bus/bus-kernel.h b/src/libsystemd-bus/bus-kernel.h index 8cf153ab41..dddecfb210 100644 --- a/src/libsystemd-bus/bus-kernel.h +++ b/src/libsystemd-bus/bus-kernel.h @@ -23,6 +23,17 @@ #include "sd-bus.h" +#define KDBUS_ITEM_NEXT(item) \ + (typeof(item))(((uint8_t *)item) + ALIGN8((item)->size)) + +#define KDBUS_ITEM_FOREACH(item, head) \ + for (item = (head)->items; \ + (uint8_t *)(item) < (uint8_t *)(head) + (head)->size; \ + item = KDBUS_ITEM_NEXT(item)) + +#define KDBUS_ITEM_HEADER_SIZE offsetof(struct kdbus_item, data) +#define KDBUS_ITEM_SIZE(s) ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE) + #define MEMFD_CACHE_MAX 32 /* When we cache a memfd block for reuse, we will truncate blocks @@ -55,3 +66,5 @@ int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size); void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size); void bus_kernel_flush_memfd(sd_bus *bus); + +int bus_kernel_parse_unique_name(const char *s, uint64_t *id); diff --git a/src/libsystemd-bus/bus-match.c b/src/libsystemd-bus/bus-match.c index ed871d9d77..95e625be09 100644 --- a/src/libsystemd-bus/bus-match.c +++ b/src/libsystemd-bus/bus-match.c @@ -255,10 +255,11 @@ int bus_match_run( return r; /* Run the callback. And then invoke siblings. */ - assert(node->leaf.callback); - r = node->leaf.callback(bus, m, node->leaf.userdata); - if (r != 0) - return r; + if (node->leaf.callback) { + r = node->leaf.callback(bus, m, node->leaf.userdata); + if (r != 0) + return r; + } return bus_match_run(bus, node->next, m); @@ -499,6 +500,7 @@ static int bus_match_add_leaf( struct bus_match_node *where, sd_bus_message_handler_t callback, void *userdata, + uint64_t cookie, struct bus_match_node **ret) { struct bus_match_node *n; @@ -518,6 +520,7 @@ static int bus_match_add_leaf( n->next->prev = n; n->leaf.callback = callback; n->leaf.userdata = userdata; + n->leaf.cookie = cookie; where->child = n; @@ -648,14 +651,8 @@ enum bus_match_node_type bus_match_node_type_from_string(const char *k, size_t n return -EINVAL; } -struct match_component { - enum bus_match_node_type type; - uint8_t value_u8; - char *value_str; -}; - static int match_component_compare(const void *a, const void *b) { - const struct match_component *x = a, *y = b; + const struct bus_match_component *x = a, *y = b; if (x->type < y->type) return -1; @@ -665,7 +662,7 @@ static int match_component_compare(const void *a, const void *b) { return 0; } -static void free_components(struct match_component *components, unsigned n_components) { +void bus_match_parse_free(struct bus_match_component *components, unsigned n_components) { unsigned i; for (i = 0; i < n_components; i++) @@ -674,13 +671,13 @@ static void free_components(struct match_component *components, unsigned n_compo free(components); } -static int parse_match( +int bus_match_parse( const char *match, - struct match_component **_components, + struct bus_match_component **_components, unsigned *_n_components) { const char *p = match; - struct match_component *components = NULL; + struct bus_match_component *components = NULL; size_t components_allocated = 0; unsigned n_components = 0, i; _cleanup_free_ char *value = NULL; @@ -771,7 +768,7 @@ static int parse_match( } /* Order the whole thing, so that we always generate the same tree */ - qsort(components, n_components, sizeof(struct match_component), match_component_compare); + qsort(components, n_components, sizeof(struct bus_match_component), match_component_compare); /* Check for duplicates */ for (i = 0; i+1 < n_components; i++) @@ -786,29 +783,24 @@ static int parse_match( return 0; fail: - free_components(components, n_components); + bus_match_parse_free(components, n_components); return r; } int bus_match_add( struct bus_match_node *root, - const char *match, + struct bus_match_component *components, + unsigned n_components, sd_bus_message_handler_t callback, void *userdata, + uint64_t cookie, struct bus_match_node **ret) { - struct match_component *components = NULL; - unsigned n_components = 0, i; + unsigned i; struct bus_match_node *n; int r; assert(root); - assert(match); - assert(callback); - - r = parse_match(match, &components, &n_components); - if (r < 0) - return r; n = root; for (i = 0; i < n_components; i++) { @@ -816,38 +808,32 @@ int bus_match_add( n, components[i].type, components[i].value_u8, components[i].value_str, &n); if (r < 0) - goto finish; + return r; } - r = bus_match_add_leaf(n, callback, userdata, &n); + r = bus_match_add_leaf(n, callback, userdata, cookie, &n); if (r < 0) - goto finish; + return r; if (ret) *ret = n; -finish: - free_components(components, n_components); - return r; + return 0; } int bus_match_remove( struct bus_match_node *root, - const char *match, + struct bus_match_component *components, + unsigned n_components, sd_bus_message_handler_t callback, - void *userdata) { + void *userdata, + uint64_t *cookie) { - struct match_component *components = NULL; - unsigned n_components = 0, i; + unsigned i; struct bus_match_node *n, **gc; int r; assert(root); - assert(match); - - r = parse_match(match, &components, &n_components); - if (r < 0) - return r; gc = newa(struct bus_match_node*, n_components); @@ -858,14 +844,17 @@ int bus_match_remove( components[i].value_u8, components[i].value_str, &n); if (r <= 0) - goto finish; + return r; gc[i] = n; } r = bus_match_find_leaf(n, callback, userdata, &n); if (r <= 0) - goto finish; + return r; + + if (cookie) + *cookie = n->leaf.cookie; /* Free the leaf */ bus_match_node_free(n); @@ -881,8 +870,6 @@ int bus_match_remove( break; } -finish: - free_components(components, n_components); return r; } diff --git a/src/libsystemd-bus/bus-match.h b/src/libsystemd-bus/bus-match.h index 4d46cf9aff..d24aeec43d 100644 --- a/src/libsystemd-bus/bus-match.h +++ b/src/libsystemd-bus/bus-match.h @@ -61,6 +61,7 @@ struct bus_match_node { sd_bus_message_handler_t callback; void *userdata; unsigned last_iteration; + uint64_t cookie; } leaf; struct { /* If this is set, then the child is NULL */ @@ -69,10 +70,16 @@ struct bus_match_node { }; }; +struct bus_match_component { + enum bus_match_node_type type; + uint8_t value_u8; + char *value_str; +}; + int bus_match_run(sd_bus *bus, struct bus_match_node *root, sd_bus_message *m); -int bus_match_add(struct bus_match_node *root, const char *match, sd_bus_message_handler_t callback, void *userdata, struct bus_match_node **ret); -int bus_match_remove(struct bus_match_node *root, const char *match, sd_bus_message_handler_t callback, void *userdata); +int bus_match_add(struct bus_match_node *root, struct bus_match_component *components, unsigned n_components, sd_bus_message_handler_t callback, void *userdata, uint64_t cookie, struct bus_match_node **ret); +int bus_match_remove(struct bus_match_node *root, struct bus_match_component *components, unsigned n_components, sd_bus_message_handler_t callback, void *userdata, uint64_t *cookie); void bus_match_free(struct bus_match_node *node); @@ -80,3 +87,6 @@ void bus_match_dump(struct bus_match_node *node, unsigned level); const char* bus_match_node_type_to_string(enum bus_match_node_type t, char buf[], size_t l); enum bus_match_node_type bus_match_node_type_from_string(const char *k, size_t n); + +int bus_match_parse(const char *match, struct bus_match_component **_components, unsigned *_n_components); +void bus_match_parse_free(struct bus_match_component *components, unsigned n_components); diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c index 6033aa744f..7ae32036bd 100644 --- a/src/libsystemd-bus/sd-bus.c +++ b/src/libsystemd-bus/sd-bus.c @@ -2404,6 +2404,9 @@ int sd_bus_remove_fallback(sd_bus *bus, const char *prefix, sd_bus_message_handl } int sd_bus_add_match(sd_bus *bus, const char *match, sd_bus_message_handler_t callback, void *userdata) { + struct bus_match_component *components = NULL; + unsigned n_components = 0; + uint64_t cookie = 0; int r = 0; if (!bus) @@ -2413,27 +2416,35 @@ int sd_bus_add_match(sd_bus *bus, const char *match, sd_bus_message_handler_t ca if (bus_pid_changed(bus)) return -ECHILD; + r = bus_match_parse(match, &components, &n_components); + if (r < 0) + goto finish; + if (bus->bus_client) { - r = bus_add_match_internal(bus, match); + cookie = ++bus->match_cookie; + + r = bus_add_match_internal(bus, match, components, n_components, cookie); if (r < 0) - return r; + goto finish; } - if (callback) { - bus->match_callbacks_modified = true; - r = bus_match_add(&bus->match_callbacks, match, callback, userdata, NULL); - if (r < 0) { - - if (bus->bus_client) - bus_remove_match_internal(bus, match); - } + bus->match_callbacks_modified = true; + r = bus_match_add(&bus->match_callbacks, components, n_components, callback, userdata, cookie, NULL); + if (r < 0) { + if (bus->bus_client) + bus_remove_match_internal(bus, match, cookie); } +finish: + bus_match_parse_free(components, n_components); return r; } int sd_bus_remove_match(sd_bus *bus, const char *match, sd_bus_message_handler_t callback, void *userdata) { + struct bus_match_component *components = NULL; + unsigned n_components = 0; int r = 0, q = 0; + uint64_t cookie = 0; if (!bus) return -EINVAL; @@ -2442,17 +2453,19 @@ int sd_bus_remove_match(sd_bus *bus, const char *match, sd_bus_message_handler_t if (bus_pid_changed(bus)) return -ECHILD; + r = bus_match_parse(match, &components, &n_components); + if (r < 0) + return r; + + bus->match_callbacks_modified = true; + r = bus_match_remove(&bus->match_callbacks, components, n_components, callback, userdata, &cookie); + if (bus->bus_client) - r = bus_remove_match_internal(bus, match); + q = bus_remove_match_internal(bus, match, cookie); - if (callback) { - bus->match_callbacks_modified = true; - q = bus_match_remove(&bus->match_callbacks, match, callback, userdata); - } + bus_match_parse_free(components, n_components); - if (r < 0) - return r; - return q; + return r < 0 ? r : q; } int sd_bus_emit_signal( diff --git a/src/libsystemd-bus/test-bus-kernel.c b/src/libsystemd-bus/test-bus-kernel.c index b8e89e41bc..0a2457a6dc 100644 --- a/src/libsystemd-bus/test-bus-kernel.c +++ b/src/libsystemd-bus/test-bus-kernel.c @@ -92,19 +92,8 @@ int main(int argc, char *argv[]) { printf("unique b: %s\n", ub); - { - //FIXME: - struct kdbus_cmd_match cmd_match; - - cmd_match.size = sizeof(cmd_match); - cmd_match.src_id = KDBUS_MATCH_SRC_ID_ANY; - - r = ioctl(sd_bus_get_fd(a), KDBUS_CMD_MATCH_ADD, &cmd_match); - assert_se(r >= 0); - - r = ioctl(sd_bus_get_fd(b), KDBUS_CMD_MATCH_ADD, &cmd_match); - assert_se(r >= 0); - } + /* interface='waldo.com',member='Piep' */ + assert_se(sd_bus_add_match(b, "interface='waldo.com'", NULL, NULL) >= 0); r = sd_bus_emit_signal(a, "/foo/bar/waldo", "waldo.com", "Piep", "sss", "I am a string", "/this/is/a/path", "and.this.a.domain.name"); assert_se(r >= 0); diff --git a/src/libsystemd-bus/test-bus-match.c b/src/libsystemd-bus/test-bus-match.c index 605d86a85c..db977f726e 100644 --- a/src/libsystemd-bus/test-bus-match.c +++ b/src/libsystemd-bus/test-bus-match.c @@ -55,6 +55,36 @@ static bool mask_contains(unsigned a[], unsigned n) { return true; } +static int match_add(struct bus_match_node *root, const char *match, int value) { + struct bus_match_component *components = NULL; + unsigned n_components = 0; + int r; + + r = bus_match_parse(match, &components, &n_components); + if (r < 0) + return r; + + r = bus_match_add(root, components, n_components, filter, INT_TO_PTR(value), 0, NULL); + bus_match_parse_free(components, n_components); + + return r; +} + +static int match_remove(struct bus_match_node *root, const char *match, int value) { + struct bus_match_component *components = NULL; + unsigned n_components = 0; + int r; + + r = bus_match_parse(match, &components, &n_components); + if (r < 0) + return r; + + r = bus_match_remove(root, components, n_components, filter, INT_TO_PTR(value), 0); + bus_match_parse_free(components, n_components); + + return r; +} + int main(int argc, char *argv[]) { struct bus_match_node root; _cleanup_bus_message_unref_ sd_bus_message *m = NULL; @@ -63,20 +93,20 @@ int main(int argc, char *argv[]) { zero(root); root.type = BUS_MATCH_ROOT; - assert_se(bus_match_add(&root, "arg2='wal\\'do',sender='foo',type='signal',interface='bar',", filter, INT_TO_PTR(1), NULL) >= 0); - assert_se(bus_match_add(&root, "arg2='wal\\'do2',sender='foo',type='signal',interface='bar',", filter, INT_TO_PTR(2), NULL) >= 0); - assert_se(bus_match_add(&root, "arg3='test',sender='foo',type='signal',interface='bar',", filter, INT_TO_PTR(3), NULL) >= 0); - assert_se(bus_match_add(&root, "arg3='test',sender='foo',type='method_call',interface='bar',", filter, INT_TO_PTR(4), NULL) >= 0); - assert_se(bus_match_add(&root, "", filter, INT_TO_PTR(5), NULL) >= 0); - assert_se(bus_match_add(&root, "interface='quux'", filter, INT_TO_PTR(6), NULL) >= 0); - assert_se(bus_match_add(&root, "interface='bar'", filter, INT_TO_PTR(7), NULL) >= 0); - assert_se(bus_match_add(&root, "member='waldo',path='/foo/bar'", filter, INT_TO_PTR(8), NULL) >= 0); - assert_se(bus_match_add(&root, "path='/foo/bar'", filter, INT_TO_PTR(9), NULL) >= 0); - assert_se(bus_match_add(&root, "path_namespace='/foo'", filter, INT_TO_PTR(10), NULL) >= 0); - assert_se(bus_match_add(&root, "path_namespace='/foo/quux'", filter, INT_TO_PTR(11), NULL) >= 0); - assert_se(bus_match_add(&root, "arg1='two'", filter, INT_TO_PTR(12), NULL) >= 0); - assert_se(bus_match_add(&root, "member='waldo',arg2path='/prefix/'", filter, INT_TO_PTR(13), NULL) >= 0); - assert_se(bus_match_add(&root, "member='waldo',path='/foo/bar',arg3namespace='prefix'", filter, INT_TO_PTR(14), NULL) >= 0); + assert_se(match_add(&root, "arg2='wal\\'do',sender='foo',type='signal',interface='bar',", 1) >= 0); + assert_se(match_add(&root, "arg2='wal\\'do2',sender='foo',type='signal',interface='bar',", 2) >= 0); + assert_se(match_add(&root, "arg3='test',sender='foo',type='signal',interface='bar',", 3) >= 0); + assert_se(match_add(&root, "arg3='test',sender='foo',type='method_call',interface='bar',", 4) >= 0); + assert_se(match_add(&root, "", 5) >= 0); + assert_se(match_add(&root, "interface='quux'", 6) >= 0); + assert_se(match_add(&root, "interface='bar'", 7) >= 0); + assert_se(match_add(&root, "member='waldo',path='/foo/bar'", 8) >= 0); + assert_se(match_add(&root, "path='/foo/bar'", 9) >= 0); + assert_se(match_add(&root, "path_namespace='/foo'", 10) >= 0); + assert_se(match_add(&root, "path_namespace='/foo/quux'", 11) >= 0); + assert_se(match_add(&root, "arg1='two'", 12) >= 0); + assert_se(match_add(&root, "member='waldo',arg2path='/prefix/'", 13) >= 0); + assert_se(match_add(&root, "member='waldo',path='/foo/bar',arg3namespace='prefix'", 14) >= 0); bus_match_dump(&root, 0); @@ -88,9 +118,9 @@ int main(int argc, char *argv[]) { assert_se(bus_match_run(NULL, &root, m) == 0); assert_se(mask_contains((unsigned[]) { 9, 8, 7, 5, 10, 12, 13, 14 }, 8)); - assert_se(bus_match_remove(&root, "member='waldo',path='/foo/bar'", filter, INT_TO_PTR(8)) > 0); - assert_se(bus_match_remove(&root, "arg2path='/prefix/',member='waldo'", filter, INT_TO_PTR(13)) > 0); - assert_se(bus_match_remove(&root, "interface='barxx'", filter, INT_TO_PTR(7)) == 0); + assert_se(match_remove(&root, "member='waldo',path='/foo/bar'", 8) > 0); + assert_se(match_remove(&root, "arg2path='/prefix/',member='waldo'", 13) > 0); + assert_se(match_remove(&root, "interface='barxx'", 7) == 0); bus_match_dump(&root, 0); -- cgit v1.2.1 From 86312ab8de59c1066d6d2b456f3a9106ce3e0991 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 20 May 2013 00:21:56 +0200 Subject: bus: add a more comprehensive test for the bloom filter logic --- .gitignore | 1 + Makefile.am | 12 ++++ TODO | 8 ++- src/libsystemd-bus/bus-control.c | 47 ++++++++++---- src/libsystemd-bus/kdbus.h | 16 ++--- src/libsystemd-bus/test-bus-kernel-bloom.c | 99 ++++++++++++++++++++++++++++++ src/libsystemd-bus/test-bus-kernel.c | 4 +- 7 files changed, 165 insertions(+), 22 deletions(-) create mode 100644 src/libsystemd-bus/test-bus-kernel-bloom.c diff --git a/.gitignore b/.gitignore index 2dd1d715dd..c2e745672c 100644 --- a/.gitignore +++ b/.gitignore @@ -83,6 +83,7 @@ /tags /test-bus-chat /test-bus-kernel +/test-bus-kernel-bloom /test-bus-marshal /test-bus-match /test-bus-memfd diff --git a/Makefile.am b/Makefile.am index 66f12e9037..2b2efcc747 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1763,6 +1763,7 @@ tests += \ test-bus-server \ test-bus-match \ test-bus-kernel \ + test-bus-kernel-bloom \ test-bus-memfd \ test-bus-zero-copy @@ -1836,6 +1837,17 @@ test_bus_kernel_LDADD = \ libsystemd-bus.la \ libsystemd-id128-internal.la +test_bus_kernel_bloom_SOURCES = \ + src/libsystemd-bus/test-bus-kernel-bloom.c + +test_bus_kernel_bloom_CFLAGS = \ + $(AM_CFLAGS) + +test_bus_kernel_bloom_LDADD = \ + libsystemd-shared.la \ + libsystemd-bus.la \ + libsystemd-id128-internal.la + test_bus_memfd_SOURCES = \ src/libsystemd-bus/test-bus-memfd.c diff --git a/TODO b/TODO index 561e7ceb39..f8a1b1b578 100644 --- a/TODO +++ b/TODO @@ -44,7 +44,13 @@ Features: - merge busctl into systemctl or so? - synthesize sd_bus_message objects from kernel messages - properly implement name registry ioctls for kdbus - - get rid of object hash table, use decision tree instead? + - get rid of object hash table, use decision tree everyhwere instead? + - implement monitor logic + - object vtable logic + - longer term: + * priority queues + * worker threads + * priority inheritance * in the final killing spree, detect processes from the root directory, and complain loudly if they have argv[0][0] == '@' set. diff --git a/src/libsystemd-bus/bus-control.c b/src/libsystemd-bus/bus-control.c index ae0d7f9767..66f713082c 100644 --- a/src/libsystemd-bus/bus-control.c +++ b/src/libsystemd-bus/bus-control.c @@ -385,12 +385,9 @@ int bus_add_match_internal( break; - case BUS_MATCH_DESTINATION: - /* The bloom filter does not include - the destination, since it is only - available for broadcast messages - which do not carry a destination - since they are undirected. */ + case BUS_MATCH_MESSAGE_TYPE: + bloom_add_pair(bloom, "message-type", bus_message_type_to_string(c->value_u8)); + using_bloom = true; break; case BUS_MATCH_INTERFACE: @@ -413,11 +410,39 @@ int bus_add_match_internal( using_bloom = true; break; - case BUS_MATCH_ARG...BUS_MATCH_ARG_LAST: - case BUS_MATCH_ARG_PATH...BUS_MATCH_ARG_PATH_LAST: - case BUS_MATCH_ARG_NAMESPACE...BUS_MATCH_ARG_NAMESPACE_LAST: - case BUS_MATCH_MESSAGE_TYPE: - assert_not_reached("FIXME!"); + case BUS_MATCH_ARG...BUS_MATCH_ARG_LAST: { + char buf[sizeof("arg")-1 + 2 + 1]; + + snprintf(buf, sizeof(buf), "arg%u", c->type - BUS_MATCH_ARG); + bloom_add_pair(bloom, buf, c->value_str); + using_bloom = true; + break; + } + + case BUS_MATCH_ARG_PATH...BUS_MATCH_ARG_PATH_LAST: { + char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")]; + + snprintf(buf, sizeof(buf), "arg%u-slash-prefix", c->type - BUS_MATCH_ARG_PATH); + bloom_add_pair(bloom, buf, c->value_str); + using_bloom = true; + break; + } + + case BUS_MATCH_ARG_NAMESPACE...BUS_MATCH_ARG_NAMESPACE_LAST: { + char buf[sizeof("arg")-1 + 2 + sizeof("-dot-prefix")]; + + snprintf(buf, sizeof(buf), "arg%u-dot-prefix", c->type - BUS_MATCH_ARG_NAMESPACE); + bloom_add_pair(bloom, buf, c->value_str); + using_bloom = true; + break; + } + + case BUS_MATCH_DESTINATION: + /* The bloom filter does not include + the destination, since it is only + available for broadcast messages + which do not carry a destination + since they are undirected. */ break; case BUS_MATCH_ROOT: diff --git a/src/libsystemd-bus/kdbus.h b/src/libsystemd-bus/kdbus.h index 214bf51197..e10a1547aa 100644 --- a/src/libsystemd-bus/kdbus.h +++ b/src/libsystemd-bus/kdbus.h @@ -67,7 +67,7 @@ struct kdbus_timestamp { /* Message Item Types */ enum { - KDBUS_MSG_NULL, + _KDBUS_MSG_NULL, /* Filled in by userspace */ KDBUS_MSG_PAYLOAD_VEC, /* .data_vec, reference to memory area */ @@ -151,7 +151,7 @@ enum { }; enum { - KDBUS_PAYLOAD_NULL, + _KDBUS_PAYLOAD_NULL, KDBUS_PAYLOAD_DBUS1 = 0x4442757356657231ULL, /* 'DBusVer1' */ KDBUS_PAYLOAD_GVARIANT = 0x4756617269616e74ULL, /* 'GVariant' */ }; @@ -182,13 +182,13 @@ struct kdbus_msg { }; enum { - KDBUS_POLICY_NULL, + _KDBUS_POLICY_NULL, KDBUS_POLICY_NAME, KDBUS_POLICY_ACCESS, }; enum { - KDBUS_POLICY_ACCESS_NULL, + _KDBUS_POLICY_ACCESS_NULL, KDBUS_POLICY_ACCESS_USER, KDBUS_POLICY_ACCESS_GROUP, KDBUS_POLICY_ACCESS_WORLD, @@ -237,7 +237,7 @@ enum { /* Items to append to struct kdbus_cmd_hello */ enum { - KDBUS_HELLO_NULL, + _KDBUS_HELLO_NULL, KDBUS_HELLO_POOL, /* kdbus_vec, userspace supplied pool to * place received messages */ }; @@ -274,7 +274,7 @@ enum { /* Items to append to kdbus_cmd_{bus,ep,ns}_make */ enum { - KDBUS_MAKE_NULL, + _KDBUS_MAKE_NULL, KDBUS_MAKE_NAME, KDBUS_MAKE_CGROUP, /* the cgroup hierarchy ID for which to attach * cgroup membership paths * to messages. */ @@ -346,7 +346,7 @@ struct kdbus_cmd_names { }; enum { - KDBUS_NAME_INFO_ITEM_NULL, + _KDBUS_NAME_INFO_ITEM_NULL, KDBUS_NAME_INFO_ITEM_NAME, /* userspace → kernel */ KDBUS_NAME_INFO_ITEM_SECLABEL, /* kernel → userspace */ KDBUS_NAME_INFO_ITEM_AUDIT, /* kernel → userspace */ @@ -361,7 +361,7 @@ struct kdbus_cmd_name_info { }; enum { - KDBUS_MATCH_NULL, + _KDBUS_MATCH_NULL, KDBUS_MATCH_BLOOM, /* Matches a mask blob against KDBUS_MSG_BLOOM */ KDBUS_MATCH_SRC_NAME, /* Matches a name string against KDBUS_MSG_SRC_NAMES */ KDBUS_MATCH_NAME_ADD, /* Matches a name string against KDBUS_MSG_NAME_ADD */ diff --git a/src/libsystemd-bus/test-bus-kernel-bloom.c b/src/libsystemd-bus/test-bus-kernel-bloom.c new file mode 100644 index 0000000000..02d9a98be9 --- /dev/null +++ b/src/libsystemd-bus/test-bus-kernel-bloom.c @@ -0,0 +1,99 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include "util.h" +#include "log.h" + +#include "sd-bus.h" +#include "bus-message.h" +#include "bus-error.h" +#include "bus-kernel.h" + +static void test_one( + const char *path, + const char *interface, + const char *member, + const char *arg0, + const char *match, + bool good) { + + _cleanup_close_ int bus_ref = -1; + _cleanup_free_ char *bus_name = NULL, *address = NULL; + _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + sd_bus *a, *b; + int r; + + bus_ref = bus_kernel_create("deine-mutter", &bus_name); + if (bus_ref == -ENOENT) + exit(EXIT_TEST_SKIP); + + assert_se(bus_ref >= 0); + + address = strappend("kernel:path=", bus_name); + assert_se(address); + + r = sd_bus_new(&a); + assert_se(r >= 0); + + r = sd_bus_new(&b); + assert_se(r >= 0); + + r = sd_bus_set_address(a, address); + assert_se(r >= 0); + + r = sd_bus_set_address(b, address); + assert_se(r >= 0); + + r = sd_bus_start(a); + assert_se(r >= 0); + + r = sd_bus_start(b); + assert_se(r >= 0); + + r = sd_bus_add_match(b, match, NULL, NULL); + assert_se(r >= 0); + + r = sd_bus_emit_signal(a, path, interface, member, "s", arg0); + assert_se(r >= 0); + + r = sd_bus_process(b, &m); + assert_se(r >= 0 && (good == !!m)); + + sd_bus_unref(a); + sd_bus_unref(b); +} + +int main(int argc, char *argv[]) { + log_set_max_level(LOG_DEBUG); + + test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "", true); + test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar/waldo'", true); + test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar/waldo/tuut'", false); + test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "interface='waldo.com'", true); + test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "member='Piep'", true); + test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "member='Pi_ep'", false); + test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "arg0='foobar'", true); + test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "arg0='foo_bar'", false); + test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar/waldo',interface='waldo.com',member='Piep',arg0='foobar'", true); + test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar/waldo',interface='waldo.com',member='Piep',arg0='foobar2'", false); + + return 0; +} diff --git a/src/libsystemd-bus/test-bus-kernel.c b/src/libsystemd-bus/test-bus-kernel.c index 0a2457a6dc..680dcde5b4 100644 --- a/src/libsystemd-bus/test-bus-kernel.c +++ b/src/libsystemd-bus/test-bus-kernel.c @@ -92,8 +92,8 @@ int main(int argc, char *argv[]) { printf("unique b: %s\n", ub); - /* interface='waldo.com',member='Piep' */ - assert_se(sd_bus_add_match(b, "interface='waldo.com'", NULL, NULL) >= 0); + r = sd_bus_add_match(b, "interface='waldo.com',member='Piep'", NULL, NULL); + assert_se(r >= 0); r = sd_bus_emit_signal(a, "/foo/bar/waldo", "waldo.com", "Piep", "sss", "I am a string", "/this/is/a/path", "and.this.a.domain.name"); assert_se(r >= 0); -- cgit v1.2.1 From f11e11e3446f7959c11a60eb0c9b53ed75ef9f42 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 20 May 2013 00:36:50 +0200 Subject: bus: add test for bloom filter prefix match --- src/libsystemd-bus/bus-bloom.c | 2 ++ src/libsystemd-bus/bus-control.c | 6 ++++-- src/libsystemd-bus/bus-kernel.c | 1 + src/libsystemd-bus/test-bus-kernel-bloom.c | 13 +++++++++++++ 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/libsystemd-bus/bus-bloom.c b/src/libsystemd-bus/bus-bloom.c index cb65e47b4c..04bee8581e 100644 --- a/src/libsystemd-bus/bus-bloom.c +++ b/src/libsystemd-bus/bus-bloom.c @@ -49,6 +49,8 @@ void bloom_add_data(uint64_t filter[BLOOM_SIZE/8], const void *data, size_t n) { for (k = 0; k < ELEMENTSOF(hash); k++) set_bit(filter, hash[k] & 511); + + /* log_debug("bloom: adding <%.*s>", (int) n, (char*) data); */ } void bloom_add_pair(uint64_t filter[BLOOM_SIZE/8], const char *a, const char *b) { diff --git a/src/libsystemd-bus/bus-control.c b/src/libsystemd-bus/bus-control.c index 66f713082c..cb8618e5c5 100644 --- a/src/libsystemd-bus/bus-control.c +++ b/src/libsystemd-bus/bus-control.c @@ -406,8 +406,10 @@ int bus_add_match_internal( break; case BUS_MATCH_PATH_NAMESPACE: - bloom_add_pair(bloom, "path-slash-prefix", c->value_str); - using_bloom = true; + if (!streq(c->value_str, "/")) { + bloom_add_pair(bloom, "path-slash-prefix", c->value_str); + using_bloom = true; + } break; case BUS_MATCH_ARG...BUS_MATCH_ARG_LAST: { diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index 33c25a4fd9..19d274b662 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -141,6 +141,7 @@ static int bus_message_setup_bloom(sd_bus_message *m, void *bloom) { bloom_add_pair(bloom, "member", m->member); if (m->path) { bloom_add_pair(bloom, "path", m->path); + bloom_add_pair(bloom, "path-slash-prefix", m->path); bloom_add_prefixes(bloom, "path-slash-prefix", m->path, '/'); } diff --git a/src/libsystemd-bus/test-bus-kernel-bloom.c b/src/libsystemd-bus/test-bus-kernel-bloom.c index 02d9a98be9..5445d3488f 100644 --- a/src/libsystemd-bus/test-bus-kernel-bloom.c +++ b/src/libsystemd-bus/test-bus-kernel-bloom.c @@ -68,9 +68,11 @@ static void test_one( r = sd_bus_start(b); assert_se(r >= 0); + log_debug("match"); r = sd_bus_add_match(b, match, NULL, NULL); assert_se(r >= 0); + log_debug("signal"); r = sd_bus_emit_signal(a, path, interface, member, "s", arg0); assert_se(r >= 0); @@ -95,5 +97,16 @@ int main(int argc, char *argv[]) { test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar/waldo',interface='waldo.com',member='Piep',arg0='foobar'", true); test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar/waldo',interface='waldo.com',member='Piep',arg0='foobar2'", false); + test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar/waldo'", true); + test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar'", false); + test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo'", false); + test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/'", false); + test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar/waldo/quux'", false); + test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path_namespace='/foo/bar/waldo'", true); + test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path_namespace='/foo/bar'", true); + test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path_namespace='/foo'", true); + test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path_namespace='/'", true); + test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path_namespace='/quux'", false); + return 0; } -- cgit v1.2.1 From b69bd568155676f021e816cae48dbf03349e60d4 Mon Sep 17 00:00:00 2001 From: Michal Schmidt Date: Mon, 20 May 2013 16:17:38 +0200 Subject: core: fix DBus property ExecMainExitTimestamp Possibly due to copy&paste error it was identical to ExecMainStartTimestamp. --- src/core/dbus-service.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c index e06a5dce97..98bcdcb402 100644 --- a/src/core/dbus-service.c +++ b/src/core/dbus-service.c @@ -103,8 +103,8 @@ static DEFINE_BUS_PROPERTY_SET_ENUM(bus_service_set_start_limit_action, start_li static const BusProperty bus_exec_main_status_properties[] = { { "ExecMainStartTimestamp", bus_property_append_usec, "t", offsetof(ExecStatus, start_timestamp.realtime) }, { "ExecMainStartTimestampMonotonic",bus_property_append_usec, "t", offsetof(ExecStatus, start_timestamp.monotonic) }, - { "ExecMainExitTimestamp", bus_property_append_usec, "t", offsetof(ExecStatus, start_timestamp.realtime) }, - { "ExecMainExitTimestampMonotonic", bus_property_append_usec, "t", offsetof(ExecStatus, start_timestamp.monotonic) }, + { "ExecMainExitTimestamp", bus_property_append_usec, "t", offsetof(ExecStatus, exit_timestamp.realtime) }, + { "ExecMainExitTimestampMonotonic", bus_property_append_usec, "t", offsetof(ExecStatus, exit_timestamp.monotonic) }, { "ExecMainPID", bus_property_append_pid, "u", offsetof(ExecStatus, pid) }, { "ExecMainCode", bus_property_append_int, "i", offsetof(ExecStatus, code) }, { "ExecMainStatus", bus_property_append_int, "i", offsetof(ExecStatus, status) }, -- cgit v1.2.1 From 90fc91d0065e20562f4d014fc7b0951f9cc2d072 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Tue, 21 May 2013 09:28:29 +0200 Subject: keymap: Add Samsung 900XC3 https://launchpad.net/bugs/1012365 --- src/udev/keymap/95-keyboard-force-release.rules | 2 +- src/udev/keymap/95-keymap.rules | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/udev/keymap/95-keyboard-force-release.rules b/src/udev/keymap/95-keyboard-force-release.rules index 3e33e85535..07fa445b83 100644 --- a/src/udev/keymap/95-keyboard-force-release.rules +++ b/src/udev/keymap/95-keyboard-force-release.rules @@ -19,7 +19,7 @@ DRIVER!="atkbd", GOTO="force_release_end" ENV{DMI_VENDOR}="$attr{[dmi/id]sys_vendor}" ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", RUN+="keyboard-force-release.sh $devpath samsung-other" -ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*90X3A*|*900X3*|*900X4*", RUN+="keyboard-force-release.sh $devpath samsung-series-9" +ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*90X3A*|*900X3*|*900X4*|*900XC3*", RUN+="keyboard-force-release.sh $devpath samsung-series-9" ENV{DMI_VENDOR}=="Dell Inc.", ATTR{[dmi/id]product_name}=="Studio 1557|Studio 1558", RUN+="keyboard-force-release.sh $devpath common-volume-keys" ENV{DMI_VENDOR}=="Dell Inc.", ATTR{[dmi/id]product_name}=="Latitude E*|Latitude *U|Precision M*", RUN+="keyboard-force-release.sh $devpath dell-touchpad" diff --git a/src/udev/keymap/95-keymap.rules b/src/udev/keymap/95-keymap.rules index 2fb296c92b..df1bffefd1 100644 --- a/src/udev/keymap/95-keymap.rules +++ b/src/udev/keymap/95-keymap.rules @@ -157,7 +157,7 @@ ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="* ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="SQ1US", RUN+="keymap $name samsung-sq1us" ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*700Z*", RUN+="keymap $name 0xBA ejectcd 0x96 keyboardbrightnessup 0x97 keyboardbrightnessdown" ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*700T*", RUN+="keymap $name 0xAD leftmeta" -ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*90X3A*|*900X3*|*900X4*", RUN+="keymap $name samsung-series-9" +ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*90X3A*|*900X3*|*900X4*|*900XC3*", RUN+="keymap $name samsung-series-9" ENV{DMI_VENDOR}=="TOSHIBA", ATTR{[dmi/id]product_name}=="SATELLITE A100", RUN+="keymap $name toshiba-satellite_a100" ENV{DMI_VENDOR}=="TOSHIBA", ATTR{[dmi/id]product_name}=="Satellite A110", RUN+="keymap $name toshiba-satellite_a110" -- cgit v1.2.1 From 718cd9ddda44274049b5d1837d8c05d418f848ff Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Tue, 21 May 2013 09:40:21 +0200 Subject: keymap: Add BenQ JoyBook https://launchpad.net/bugs/727139 --- src/udev/keymap/95-keyboard-force-release.rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/udev/keymap/95-keyboard-force-release.rules b/src/udev/keymap/95-keyboard-force-release.rules index 07fa445b83..da706a0489 100644 --- a/src/udev/keymap/95-keyboard-force-release.rules +++ b/src/udev/keymap/95-keyboard-force-release.rules @@ -52,6 +52,6 @@ ENV{DMI_VENDOR}=="HANNspree", ATTR{[dmi/id]product_name}=="SN10E100", RUN+="keyb ENV{DMI_VENDOR}=="GIGABYTE", ATTR{[dmi/id]product_name}=="i1520M", RUN+="keyboard-force-release.sh $devpath common-volume-keys" -ENV{DMI_VENDOR}=="BenQ", ATTR{[dmi/id]product_name}=="*nScreen*", RUN+="keyboard-force-release.sh $devpath common-volume-keys" +ENV{DMI_VENDOR}=="BenQ", ATTR{[dmi/id]product_name}=="*nScreen*|Joybook Lite*", RUN+="keyboard-force-release.sh $devpath common-volume-keys" LABEL="force_release_end" -- cgit v1.2.1 From 1bec44f2a56c5d6fb827da9457d7470973acb8da Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Tue, 21 May 2013 09:52:33 +0200 Subject: keymap: Add DIXONSP https://launchpad.net/bugs/1157334 --- src/udev/keymap/95-keyboard-force-release.rules | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/udev/keymap/95-keyboard-force-release.rules b/src/udev/keymap/95-keyboard-force-release.rules index da706a0489..77288c792a 100644 --- a/src/udev/keymap/95-keyboard-force-release.rules +++ b/src/udev/keymap/95-keyboard-force-release.rules @@ -54,4 +54,6 @@ ENV{DMI_VENDOR}=="GIGABYTE", ATTR{[dmi/id]product_name}=="i1520M", RUN+="keyboar ENV{DMI_VENDOR}=="BenQ", ATTR{[dmi/id]product_name}=="*nScreen*|Joybook Lite*", RUN+="keyboard-force-release.sh $devpath common-volume-keys" +ENV{DMI_VENDOR}=="DIXONSP", ATTR{[dmi/id]product_name}=="DIXON*", RUN+="keyboard-force-release.sh $devpath common-volume-keys" + LABEL="force_release_end" -- cgit v1.2.1 From 571bfc6c56962dfc926e9bbc1600c511fc8565d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mantas=20Mikul=C4=97nas?= Date: Mon, 20 May 2013 11:20:15 +0300 Subject: systemctl: honor "--no-legend" in 'list-sockets' --- src/systemctl/systemctl.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 3cca861cf6..e6bd855c15 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -655,11 +655,12 @@ static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) { } if (cs) { - printf("%-*s %-*.*s%-*s %s\n", - pathlen, "LISTEN", - typelen + arg_show_types, typelen + arg_show_types, "TYPE ", - socklen, "UNIT", - "ACTIVATES"); + if (!arg_no_legend) + printf("%-*s %-*.*s%-*s %s\n", + pathlen, "LISTEN", + typelen + arg_show_types, typelen + arg_show_types, "TYPE ", + socklen, "UNIT", + "ACTIVATES"); for (s = socket_infos; s < socket_infos + cs; s++) { char **a; @@ -678,15 +679,18 @@ static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) { on = ansi_highlight(true); off = ansi_highlight(false); - printf("\n"); + if (!arg_no_legend) + printf("\n"); } else { on = ansi_highlight_red(true); off = ansi_highlight_red(false); } - printf("%s%u sockets listed.%s\n", on, cs, off); - if (!arg_all) - printf("Pass --all to see loaded but inactive sockets, too.\n"); + if (!arg_no_legend) { + printf("%s%u sockets listed.%s\n", on, cs, off); + if (!arg_all) + printf("Pass --all to see loaded but inactive sockets, too.\n"); + } return 0; } -- cgit v1.2.1 From 9e9c3abcfa6b93500960531d0d7aa64b8b2b0349 Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Sun, 19 May 2013 12:10:55 +0200 Subject: service: kill processes with SIGKILL on watchdog failure Just calling service_enter_dead() does not kill any processes. As a result, the old process may still be running when the new one is started. After a watchdog failure the service is in an undefined state. Using the normal shutdown mechanism makes no sense. Instead all processes are just killed and the service can try to restart. --- src/core/service.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/core/service.c b/src/core/service.c index 3617c24711..e110a41dae 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -235,7 +235,7 @@ static void service_stop_watchdog(Service *s) { s->watchdog_timestamp.monotonic = 0; } -static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart); +static void service_enter_signal(Service *s, ServiceState state, ServiceResult f); static void service_handle_watchdog(Service *s) { usec_t offset; @@ -249,7 +249,7 @@ static void service_handle_watchdog(Service *s) { offset = now(CLOCK_MONOTONIC) - s->watchdog_timestamp.monotonic; if (offset >= s->watchdog_usec) { log_error_unit(UNIT(s)->id, "%s watchdog timeout!", UNIT(s)->id); - service_enter_dead(s, SERVICE_FAILURE_WATCHDOG, true); + service_enter_signal(s, SERVICE_FINAL_SIGKILL, SERVICE_FAILURE_WATCHDOG); return; } @@ -1939,8 +1939,6 @@ fail: service_enter_dead(s, SERVICE_FAILURE_RESOURCES, false); } -static void service_enter_signal(Service *s, ServiceState state, ServiceResult f); - static void service_enter_stop_post(Service *s, ServiceResult f) { int r; assert(s); -- cgit v1.2.1 From 67820a0cbdc9d72a1074debf8b2bc72203c775cc Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Sun, 19 May 2013 15:45:48 +0200 Subject: systemctl: make systemctl is-enabled work for templated units Patch resolves the problem that 'systemctl is-enabled' does not work for templated units. Without this patch, systemctl is-enabled something@abc.service returned "No such file or directory", because it first checked if /usr/lib/systemd/system/something@abc.service, etc. exists. If systemctl is-enabled is called for templated units, this check should be omitted and it should search for symlinks in the .wants dirs right away. This patch fixes the broken behaviour and resolves https://bugs.freedesktop.org/show_bug.cgi?id=55318. [zj: fixed the patch to still check for broken symlinks and masked instances. Also removed untrue assumptions from the patch description.] --- src/shared/install.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/shared/install.c b/src/shared/install.c index edf4d2a9fe..8f27c6d479 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -1609,24 +1609,29 @@ UnitFileState unit_file_get_state( if (!path) return -ENOMEM; + /* + * Search for a unit file in our default paths, to + * be sure, that there are no broken symlinks. + */ if (lstat(path, &st) < 0) { r = -errno; - if (errno == ENOENT) - continue; - - return -errno; - } + if (errno != ENOENT) + return r; - if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) - return -ENOENT; + if (!unit_name_is_instance(name)) + continue; + } else { + if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) + return -ENOENT; - r = null_or_empty_path(path); - if (r < 0 && r != -ENOENT) - return r; - else if (r > 0) { - state = path_startswith(*i, "/run") ? - UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED; - return state; + r = null_or_empty_path(path); + if (r < 0 && r != -ENOENT) + return r; + else if (r > 0) { + state = path_startswith(*i, "/run") ? + UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED; + return state; + } } r = find_symlinks_in_scope(scope, root_dir, name, &state); -- cgit v1.2.1 From 2927b326ccf67236e148444679f582ea1437ef5a Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Fri, 17 May 2013 15:38:13 +0200 Subject: man: Document missing options --- man/hostnamectl.xml | 8 ++++++++ man/journalctl.xml | 10 ++++++++++ man/localectl.xml | 8 ++++++++ man/timedatectl.xml | 8 ++++++++ src/hostname/hostnamectl.c | 1 + src/journal/coredumpctl.c | 1 + src/locale/localectl.c | 1 + src/timedate/timedatectl.c | 1 + 8 files changed, 38 insertions(+) diff --git a/man/hostnamectl.xml b/man/hostnamectl.xml index 9efe220119..801ab3a7bf 100644 --- a/man/hostnamectl.xml +++ b/man/hostnamectl.xml @@ -115,6 +115,14 @@ operations. + + + + + Acquire privileges via PolicyKit + before executing the operation. + + diff --git a/man/journalctl.xml b/man/journalctl.xml index cc7d1a0533..d9ca0a6074 100644 --- a/man/journalctl.xml +++ b/man/journalctl.xml @@ -322,6 +322,16 @@ kernel. + + + + + Show kernel messages from + current boot. This implies + and adds the match _TRANSPORT=kernel. + + + diff --git a/man/localectl.xml b/man/localectl.xml index 0b13c111a5..febdeec150 100644 --- a/man/localectl.xml +++ b/man/localectl.xml @@ -108,6 +108,14 @@ operations. + + + + + Acquire privileges via PolicyKit + before executing the operation. + + diff --git a/man/timedatectl.xml b/man/timedatectl.xml index faccc5086d..e291f04e1e 100644 --- a/man/timedatectl.xml +++ b/man/timedatectl.xml @@ -97,6 +97,14 @@ operations. + + + + + Acquire privileges via PolicyKit + before executing the operation. + + diff --git a/src/hostname/hostnamectl.c b/src/hostname/hostnamectl.c index 064581a31c..7acd77295d 100644 --- a/src/hostname/hostnamectl.c +++ b/src/hostname/hostnamectl.c @@ -362,6 +362,7 @@ static int help(void) { " --transient Only set transient hostname\n" " --static Only set static hostname\n" " --pretty Only set pretty hostname\n" + " -P --privileged Acquire privileges before execution\n" " --no-ask-password Do not prompt for password\n" " -H --host=[USER@]HOST Operate on remote host\n\n" "Commands:\n" diff --git a/src/journal/coredumpctl.c b/src/journal/coredumpctl.c index 5652c2f91a..e1bd8621e3 100644 --- a/src/journal/coredumpctl.c +++ b/src/journal/coredumpctl.c @@ -84,6 +84,7 @@ static int help(void) { "Flags:\n" " -o --output=FILE Write output to FILE\n" " --no-pager Do not pipe output into a pager\n" + " --no-legend Do not print the column headers.\n\n" "Commands:\n" " -h --help Show this help\n" diff --git a/src/locale/localectl.c b/src/locale/localectl.c index 50250c4b47..3096d06084 100644 --- a/src/locale/localectl.c +++ b/src/locale/localectl.c @@ -712,6 +712,7 @@ static int help(void) { " --version Show package version\n" " --no-convert Don't convert keyboard mappings\n" " --no-pager Do not pipe output into a pager\n" + " -P --privileged Acquire privileges before execution\n" " --no-ask-password Do not prompt for password\n" " -H --host=[USER@]HOST Operate on remote host\n\n" "Commands:\n" diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c index 8d4e560b93..be3b8b4da3 100644 --- a/src/timedate/timedatectl.c +++ b/src/timedate/timedatectl.c @@ -501,6 +501,7 @@ static int help(void) { " --adjust-system-clock\n" " Adjust system clock when changing local RTC mode\n" " --no-pager Do not pipe output into a pager\n" + " -P --privileged Acquire privileges before execution\n" " --no-ask-password Do not prompt for password\n" " -H --host=[USER@]HOST Operate on remote host\n\n" "Commands:\n" -- cgit v1.2.1 From 8f155917bf5c11c8f156d7f25f242257d6086cb9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 May 2013 16:02:21 +0200 Subject: bus: add benchmark tool to determine the right threshold for copying vs. memfd --- .gitignore | 1 + Makefile.am | 12 ++ src/libsystemd-bus/bus-internal.h | 2 + src/libsystemd-bus/bus-kernel.c | 2 + src/libsystemd-bus/bus-message.c | 6 +- src/libsystemd-bus/sd-bus.c | 1 + src/libsystemd-bus/test-bus-kernel-benchmark.c | 225 +++++++++++++++++++++++++ 7 files changed, 246 insertions(+), 3 deletions(-) create mode 100644 src/libsystemd-bus/test-bus-kernel-benchmark.c diff --git a/.gitignore b/.gitignore index c2e745672c..7534ac1c07 100644 --- a/.gitignore +++ b/.gitignore @@ -84,6 +84,7 @@ /test-bus-chat /test-bus-kernel /test-bus-kernel-bloom +/test-bus-kernel-benchmark /test-bus-marshal /test-bus-match /test-bus-memfd diff --git a/Makefile.am b/Makefile.am index 2b2efcc747..b278143af2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1764,6 +1764,7 @@ tests += \ test-bus-match \ test-bus-kernel \ test-bus-kernel-bloom \ + test-bus-kernel-benchmark \ test-bus-memfd \ test-bus-zero-copy @@ -1848,6 +1849,17 @@ test_bus_kernel_bloom_LDADD = \ libsystemd-bus.la \ libsystemd-id128-internal.la +test_bus_kernel_benchmark_SOURCES = \ + src/libsystemd-bus/test-bus-kernel-benchmark.c + +test_bus_kernel_benchmark_CFLAGS = \ + $(AM_CFLAGS) + +test_bus_kernel_benchmark_LDADD = \ + libsystemd-shared.la \ + libsystemd-bus.la \ + libsystemd-id128-internal.la + test_bus_memfd_SOURCES = \ src/libsystemd-bus/test-bus-memfd.c diff --git a/src/libsystemd-bus/bus-internal.h b/src/libsystemd-bus/bus-internal.h index 147a83c045..30b8d519a0 100644 --- a/src/libsystemd-bus/bus-internal.h +++ b/src/libsystemd-bus/bus-internal.h @@ -111,6 +111,8 @@ struct sd_bus { bool filter_callbacks_modified:1; bool object_callbacks_modified:1; + int use_memfd; + void *rbuffer; size_t rbuffer_size; diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index 19d274b662..10b7a8aba4 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -326,6 +326,8 @@ int bus_kernel_take_fd(sd_bus *b) { if (b->is_server) return -EINVAL; + b->use_memfd = 1; + if (!b->kdbus_buffer) { b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); if (b->kdbus_buffer == MAP_FAILED) { diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c index e531dec5cd..55c2d62885 100644 --- a/src/libsystemd-bus/bus-message.c +++ b/src/libsystemd-bus/bus-message.c @@ -564,7 +564,7 @@ static int message_new_reply( goto fail; if (call->sender) { - r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender); + r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination); if (r < 0) goto fail; } @@ -3865,9 +3865,9 @@ int bus_message_seal(sd_bus_message *m, uint64_t serial) { /* If this is something we can send as memfd, then let's seal the memfd now. Note that we can send memfds as payload only for directed messages, and not for broadcasts. */ - if (m->destination) { + if (m->destination && m->bus && m->bus->use_memfd) { MESSAGE_FOREACH_PART(part, i, m) - if (part->memfd >= 0 && !part->sealed && part->size > MEMFD_MIN_SIZE) { + if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) { bus_body_part_unmap(part); if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0) diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c index 7ae32036bd..3f766fb519 100644 --- a/src/libsystemd-bus/sd-bus.c +++ b/src/libsystemd-bus/sd-bus.c @@ -2514,6 +2514,7 @@ int sd_bus_call_method( int r; if (!bus) + return -EINVAL; if (!BUS_IS_OPEN(bus->state)) return -ENOTCONN; diff --git a/src/libsystemd-bus/test-bus-kernel-benchmark.c b/src/libsystemd-bus/test-bus-kernel-benchmark.c new file mode 100644 index 0000000000..403af885c3 --- /dev/null +++ b/src/libsystemd-bus/test-bus-kernel-benchmark.c @@ -0,0 +1,225 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include "util.h" +#include "log.h" + +#include "sd-bus.h" +#include "bus-message.h" +#include "bus-error.h" +#include "bus-kernel.h" +#include "bus-internal.h" + +#define N_TRIES 500 +#define MAX_SIZE (5*1024*1024) + +static void server(sd_bus *b, usec_t *result) { + usec_t x = 0; + int r; + + for (;;) { + _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + + r = sd_bus_process(b, &m); + assert_se(r >= 0); + + if (r == 0) + assert_se(sd_bus_wait(b, (usec_t) -1) >= 0); + + if (!m) + continue; + + /* log_error("huhu %s from %s", sd_bus_message_get_member(m), sd_bus_message_get_sender(m)); */ + + if (sd_bus_message_is_method_call(m, "benchmark.server", "Work")) { + _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; + size_t i, sz; + char *q; + const char *p; + + assert_se(sd_bus_message_read_array(m, 'y', (const void**) &p, &sz) > 0); + assert_se(sd_bus_message_new_method_return(b, m, &reply) >= 0); + assert_se(sd_bus_message_append_array_space(reply, 'y', sz, (void**) &q) >= 0); + + x = now(CLOCK_MONOTONIC); + + for (i = 0; i < sz; i++) + q[i] = toupper(p[i]); + + x = now(CLOCK_MONOTONIC) - x; + + assert_se(sd_bus_send(b, reply, NULL) >= 0); + } else if (sd_bus_message_is_method_call(m, "benchmark.server", "Exit")) { + usec_t t; + + assert_se(sd_bus_message_read(m, "t", &t) > 0); + assert_se(t >= x); + *result = t - x; + return; + + } else if (sd_bus_message_is_method_call(m, "benchmark.server", "Ping")) { + assert_se(sd_bus_reply_method_return(b, m, "y", 1) >= 0); + } else + assert_not_reached("Unknown method"); + } +} + +static void client(sd_bus *b, size_t sz) { + _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL; + char *p; + const char *q; + usec_t t; + size_t l, i; + + assert_se(sd_bus_call_method(b, ":1.1", "/", "benchmark.server", "Ping", NULL, NULL, NULL) >= 0); + + assert_se(sd_bus_message_new_method_call(b, ":1.1", "/", "benchmark.server", "Work", &m) >= 0); + assert_se(sd_bus_message_append_array_space(m, 'y', sz, (void**) &p) >= 0); + + for (i = 0; i < sz; i++) + p[i] = 'a' + (char) (i % 26); + + t = now(CLOCK_MONOTONIC); + assert_se(sd_bus_send_with_reply_and_block(b, m, 0, NULL, &reply) >= 0); + t = now(CLOCK_MONOTONIC) - t; + + assert_se(sd_bus_message_read_array(reply, 'y', (const void**) &q, &l) > 0); + assert_se(l == sz); + + for (i = 0; i < sz; i++) { + assert_se(q[i] == 'A' + (char) (i % 26)); + } + + sd_bus_message_unref(m); + + assert_se(sd_bus_message_new_method_call(b, ":1.1", "/", "benchmark.server", "Exit", &m) >= 0); + assert_se(sd_bus_message_append(m, "t", t) >= 0); + assert_se(sd_bus_send(b, m, NULL) >= 0); +} + +static void run_benchmark(size_t sz, bool force_copy, usec_t *result) { + + _cleanup_close_ int bus_ref = -1; + _cleanup_free_ char *bus_name = NULL, *address = NULL; + sd_bus *b; + int r; + pid_t pid; + + bus_ref = bus_kernel_create("deine-mutter", &bus_name); + if (bus_ref == -ENOENT) + exit(EXIT_TEST_SKIP); + + assert_se(bus_ref >= 0); + + address = strappend("kernel:path=", bus_name); + assert_se(address); + + r = sd_bus_new(&b); + assert_se(r >= 0); + + b->use_memfd = force_copy ? 0 : -1; + + r = sd_bus_set_address(b, address); + assert_se(r >= 0); + + r = sd_bus_start(b); + assert_se(r >= 0); + + pid = fork(); + assert_se(pid >= 0); + + if (pid == 0) { + close_nointr_nofail(bus_ref); + sd_bus_unref(b); + + r = sd_bus_new(&b); + assert_se(r >= 0); + + b->use_memfd = force_copy ? 0 : -1; + + r = sd_bus_set_address(b, address); + assert_se(r >= 0); + + r = sd_bus_start(b); + assert_se(r >= 0); + + client(b, sz); + _exit(0); + } + + server(b, result); + sd_bus_unref(b); + + assert_se(waitpid(pid, NULL, 0) == pid); +} + +int main(int argc, char *argv[]) { + size_t lsize, rsize, csize; + + log_set_max_level(LOG_DEBUG); + + lsize = 1; + rsize = MAX_SIZE; + + for (;;) { + usec_t copy = 0, memfd = 0; + unsigned i; + + csize = (lsize + rsize) / 2; + + log_info("Trying size=%zu", csize); + + if (csize <= lsize) + break; + + for (i = 0; i < N_TRIES; i++) { + usec_t t; + + run_benchmark(csize, true, &t); + copy += t; + } + + for (i = 0; i < N_TRIES; i++) { + usec_t t; + + run_benchmark(csize, false, &t); + memfd += t; + } + + copy /= N_TRIES; + memfd /= N_TRIES; + + if (copy == memfd) + break; + + if (copy < memfd) + lsize = csize; + else + rsize = csize; + } + + log_info("Copying/memfd are equally fast at %zu", csize); + + return 0; +} -- cgit v1.2.1 From a057be1fcc61ca1fed96898db05dfe88f54ab2db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 22 May 2013 21:11:29 -0400 Subject: man: mention net.ifnames in kernel-command-line(3) --- man/kernel-command-line.xml | 1 + man/systemd-udevd.service.xml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml index 6d064f6373..7ff2709fbd 100644 --- a/man/kernel-command-line.xml +++ b/man/kernel-command-line.xml @@ -210,6 +210,7 @@ rd.udev.children-max= udev.exec-delay= rd.udev.exec-delay= + net.ifnames= Parameters understood by diff --git a/man/systemd-udevd.service.xml b/man/systemd-udevd.service.xml index 77b7374886..7fce3000f5 100644 --- a/man/systemd-udevd.service.xml +++ b/man/systemd-udevd.service.xml @@ -162,6 +162,8 @@ + Configuration file -- cgit v1.2.1 From 546158bc6f46f8004cc11e81d19d223e0da56730 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Fri, 17 May 2013 15:38:12 +0200 Subject: Fix --no-ask-password POSIX_ME_HARDER mode is disabled for localectl. It doesn't make much sense in case of localectl, and there's little reason for localectl to behave specially. --- src/hostname/hostnamectl.c | 6 +++--- src/locale/localectl.c | 12 ++++++++---- src/timedate/timedatectl.c | 14 +++++++++----- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/hostname/hostnamectl.c b/src/hostname/hostnamectl.c index 7acd77295d..d108a2489d 100644 --- a/src/hostname/hostnamectl.c +++ b/src/hostname/hostnamectl.c @@ -219,7 +219,7 @@ static int show_status(DBusConnection *bus, char **args, unsigned n) { static int set_hostname(DBusConnection *bus, char **args, unsigned n) { _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; - dbus_bool_t interactive = true; + dbus_bool_t interactive = arg_ask_password; _cleanup_free_ char *h = NULL; const char *hostname = args[1]; int r; @@ -311,7 +311,7 @@ static int set_hostname(DBusConnection *bus, char **args, unsigned n) { static int set_icon_name(DBusConnection *bus, char **args, unsigned n) { _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; - dbus_bool_t interactive = true; + dbus_bool_t interactive = arg_ask_password; assert(args); assert(n == 2); @@ -333,7 +333,7 @@ static int set_icon_name(DBusConnection *bus, char **args, unsigned n) { static int set_chassis(DBusConnection *bus, char **args, unsigned n) { _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; - dbus_bool_t interactive = true; + dbus_bool_t interactive = arg_ask_password; assert(args); assert(n == 2); diff --git a/src/locale/localectl.c b/src/locale/localectl.c index 3096d06084..b5cd344397 100644 --- a/src/locale/localectl.c +++ b/src/locale/localectl.c @@ -223,7 +223,7 @@ static int show_status(DBusConnection *bus, char **args, unsigned n) { static int set_locale(DBusConnection *bus, char **args, unsigned n) { _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL; - dbus_bool_t interactive = true; + dbus_bool_t interactive = arg_ask_password; DBusError error; DBusMessageIter iter; int r; @@ -459,7 +459,7 @@ static int list_locales(DBusConnection *bus, char **args, unsigned n) { static int set_vconsole_keymap(DBusConnection *bus, char **args, unsigned n) { _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; - dbus_bool_t interactive = true, b; + dbus_bool_t interactive = arg_ask_password, b; const char *map, *toggle_map; assert(bus); @@ -565,7 +565,7 @@ static int list_vconsole_keymaps(DBusConnection *bus, char **args, unsigned n) { static int set_x11_keymap(DBusConnection *bus, char **args, unsigned n) { _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; - dbus_bool_t interactive = true, b; + dbus_bool_t interactive = arg_ask_password, b; const char *layout, *model, *variant, *options; assert(bus); @@ -758,7 +758,7 @@ static int parse_argv(int argc, char *argv[]) { assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "has:H:P", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "hH:P", options, NULL)) >= 0) { switch (c) { @@ -788,6 +788,10 @@ static int parse_argv(int argc, char *argv[]) { arg_no_pager = true; break; + case ARG_NO_ASK_PASSWORD: + arg_ask_password = false; + break; + case '?': return -EINVAL; diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c index be3b8b4da3..e8bc4529f3 100644 --- a/src/timedate/timedatectl.c +++ b/src/timedate/timedatectl.c @@ -304,7 +304,7 @@ static int show_status(DBusConnection *bus, char **args, unsigned n) { static int set_time(DBusConnection *bus, char **args, unsigned n) { _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; - dbus_bool_t relative = false, interactive = true; + dbus_bool_t relative = false, interactive = arg_ask_password; usec_t t; dbus_int64_t u; int r; @@ -338,7 +338,7 @@ static int set_time(DBusConnection *bus, char **args, unsigned n) { static int set_timezone(DBusConnection *bus, char **args, unsigned n) { _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; - dbus_bool_t interactive = true; + dbus_bool_t interactive = arg_ask_password; assert(args); assert(n == 2); @@ -360,7 +360,7 @@ static int set_timezone(DBusConnection *bus, char **args, unsigned n) { static int set_local_rtc(DBusConnection *bus, char **args, unsigned n) { _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; - dbus_bool_t interactive = true, b, q; + dbus_bool_t interactive = arg_ask_password, b, q; int r; assert(args); @@ -393,7 +393,7 @@ static int set_local_rtc(DBusConnection *bus, char **args, unsigned n) { static int set_ntp(DBusConnection *bus, char **args, unsigned n) { _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; - dbus_bool_t interactive = true, b; + dbus_bool_t interactive = arg_ask_password, b; int r; assert(args); @@ -541,7 +541,7 @@ static int parse_argv(int argc, char *argv[]) { assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "+hH:P", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "hH:P", options, NULL)) >= 0) { switch (c) { @@ -563,6 +563,10 @@ static int parse_argv(int argc, char *argv[]) { arg_host = optarg; break; + case ARG_NO_ASK_PASSWORD: + arg_ask_password = false; + break; + case ARG_ADJUST_SYSTEM_CLOCK: arg_adjust_system_clock = true; break; -- cgit v1.2.1 From 3a05c0f96c88984b47ca2f77bbf67dd5048a47d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=A1clav=20Pavl=C3=ADn?= Date: Fri, 17 May 2013 16:03:36 +0200 Subject: systemctl: mangle names when avoiding dbus Unit names were mangled in function enable_unit only when dbus was used. This patch adds mangling also when the dbus is not in use. This makes it possible to say e.g.: systemctl --root=/path enable cups without spelling cups.service out in full. --- src/systemctl/systemctl.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index e6bd855c15..f8573d315c 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -4221,24 +4221,28 @@ static int enable_unit(DBusConnection *bus, char **args) { if (!args[1]) return 0; + r = mangle_names(args+1, &mangled_names); + if (r < 0) + goto finish; + if (!bus || avoid_bus()) { if (streq(verb, "enable")) { - r = unit_file_enable(arg_scope, arg_runtime, arg_root, args+1, arg_force, &changes, &n_changes); + r = unit_file_enable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes); carries_install_info = r; } else if (streq(verb, "disable")) - r = unit_file_disable(arg_scope, arg_runtime, arg_root, args+1, &changes, &n_changes); + r = unit_file_disable(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes); else if (streq(verb, "reenable")) { - r = unit_file_reenable(arg_scope, arg_runtime, arg_root, args+1, arg_force, &changes, &n_changes); + r = unit_file_reenable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes); carries_install_info = r; } else if (streq(verb, "link")) - r = unit_file_link(arg_scope, arg_runtime, arg_root, args+1, arg_force, &changes, &n_changes); + r = unit_file_link(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes); else if (streq(verb, "preset")) { - r = unit_file_preset(arg_scope, arg_runtime, arg_root, args+1, arg_force, &changes, &n_changes); + r = unit_file_preset(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes); carries_install_info = r; } else if (streq(verb, "mask")) - r = unit_file_mask(arg_scope, arg_runtime, arg_root, args+1, arg_force, &changes, &n_changes); + r = unit_file_mask(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes); else if (streq(verb, "unmask")) - r = unit_file_unmask(arg_scope, arg_runtime, arg_root, args+1, &changes, &n_changes); + r = unit_file_unmask(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes); else assert_not_reached("Unknown verb"); @@ -4297,10 +4301,6 @@ static int enable_unit(DBusConnection *bus, char **args) { dbus_message_iter_init_append(m, &iter); - r = mangle_names(args+1, &mangled_names); - if(r < 0) - goto finish; - r = bus_append_strv_iter(&iter, mangled_names); if (r < 0) { log_error("Failed to append unit files."); -- cgit v1.2.1 From 9b3848f2e2dc737bd6e7df1c765821d227d3f22f Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 24 May 2013 03:08:48 +0200 Subject: bus: update kdbus.h from upstream --- src/libsystemd-bus/bus-control.c | 6 ++-- src/libsystemd-bus/kdbus.h | 68 ++++++++++++++++++++++------------------ 2 files changed, 41 insertions(+), 33 deletions(-) diff --git a/src/libsystemd-bus/bus-control.c b/src/libsystemd-bus/bus-control.c index cb8618e5c5..0ba8585805 100644 --- a/src/libsystemd-bus/bus-control.c +++ b/src/libsystemd-bus/bus-control.c @@ -75,7 +75,7 @@ int sd_bus_request_name(sd_bus *bus, const char *name, int flags) { l = strlen(name); n = alloca0(offsetof(struct kdbus_cmd_name, name) + l + 1); n->size = offsetof(struct kdbus_cmd_name, name) + l + 1; - n->name_flags = flags; + n->flags = flags; memcpy(n->name, name, l+1); #ifdef HAVE_VALGRIND_MEMCHECK_H @@ -86,7 +86,7 @@ int sd_bus_request_name(sd_bus *bus, const char *name, int flags) { if (r < 0) return -errno; - return n->name_flags; + return n->flags; } else { r = sd_bus_call_method( bus, @@ -142,7 +142,7 @@ int sd_bus_release_name(sd_bus *bus, const char *name) { if (r < 0) return -errno; - return n->name_flags; + return n->flags; } else { r = sd_bus_call_method( bus, diff --git a/src/libsystemd-bus/kdbus.h b/src/libsystemd-bus/kdbus.h index e10a1547aa..dfc64ffe24 100644 --- a/src/libsystemd-bus/kdbus.h +++ b/src/libsystemd-bus/kdbus.h @@ -21,6 +21,18 @@ #endif #define KDBUS_IOC_MAGIC 0x95 +#define KDBUS_SRC_ID_KERNEL (0) +#define KDBUS_DST_ID_WELL_KNOWN_NAME (0) +#define KDBUS_MATCH_SRC_ID_ANY (~0ULL) +#define KDBUS_DST_ID_BROADCAST (~0ULL) + +/* Common first elements in a structure which are used to iterate over + * a list of elements. */ +#define KDBUS_PART_HEADER \ + struct { \ + __u64 size; \ + __u64 type; \ + } /* Message sent from kernel to userspace, when the owner or starter of * a well-known name changes */ @@ -60,10 +72,15 @@ struct kdbus_timestamp { __u64 realtime_ns; }; -#define KDBUS_SRC_ID_KERNEL (0) -#define KDBUS_DST_ID_WELL_KNOWN_NAME (0) -#define KDBUS_MATCH_SRC_ID_ANY (~0ULL) -#define KDBUS_DST_ID_BROADCAST (~0ULL) +struct kdbus_vec { + __u64 address; + __u64 size; +}; + +struct kdbus_memfd { + __u64 size; + int fd; +}; /* Message Item Types */ enum { @@ -100,16 +117,6 @@ enum { KDBUS_MSG_REPLY_DEAD, /* dito */ }; -struct kdbus_vec { - __u64 address; - __u64 size; -}; - -struct kdbus_memfd { - __u64 size; - int fd; -}; - /** * struct kdbus_item - chain of data blocks * @@ -117,8 +124,7 @@ struct kdbus_memfd { * type: kdbus_item type of data */ struct kdbus_item { - __u64 size; - __u64 type; + KDBUS_PART_HEADER; union { /* inline data */ __u8 data[0]; @@ -151,7 +157,7 @@ enum { }; enum { - _KDBUS_PAYLOAD_NULL, + KDBUS_PAYLOAD_KERNEL, KDBUS_PAYLOAD_DBUS1 = 0x4442757356657231ULL, /* 'DBusVer1' */ KDBUS_PAYLOAD_GVARIANT = 0x4756617269616e74ULL, /* 'GVariant' */ }; @@ -200,23 +206,24 @@ enum { KDBUS_POLICY_OWN = 1 << 0, }; +struct kdbus_policy_access { + __u64 type; /* USER, GROUP, WORLD */ + __u64 bits; /* RECV, SEND, OWN */ + __u64 id; /* uid, gid, 0 */ +}; + struct kdbus_policy { - __u64 size; - __u64 type; /* NAME or ACCESS */ + KDBUS_PART_HEADER; union { char name[0]; - struct { - __u32 type; /* USER, GROUP, WORLD */ - __u32 bits; /* RECV, SEND, OWN */ - __u64 id; /* uid, gid, 0 */ - } access; + struct kdbus_policy_access access; }; }; +/* A series of KDBUS_POLICY_NAME, plus one or more KDBUS_POLICY_ACCESS */ struct kdbus_cmd_policy { __u64 size; - __u8 data[0]; /* a series of KDBUS_POLICY_NAME plus one or - * more KDBUS_POLICY_ACCESS each. */ + struct kdbus_policy policies[0]; }; /* Flags for struct kdbus_cmd_hello */ @@ -332,10 +339,11 @@ enum { KDBUS_NAME_IN_QUEUE = 1 << 16, }; +/* We allow (de)regestration of names of other peers */ struct kdbus_cmd_name { __u64 size; - __u64 name_flags; - __u64 id; /* We allow registration/deregestration of names of other peers */ + __u64 flags; + __u64 id; __u64 conn_flags; char name[0]; }; @@ -381,7 +389,7 @@ struct kdbus_cmd_match { struct kdbus_cmd_monitor { __u64 id; /* We allow setting the monitor flag of other peers */ - unsigned int enabled; /* A boolean to enable/disable monitoring */ + unsigned int enable; /* A boolean to enable/disable monitoring */ }; /* FD states: @@ -394,7 +402,7 @@ struct kdbus_cmd_monitor { * starter (via KDBUS_CMD_HELLO with KDBUS_CMD_HELLO_STARTER) * ep owner (via KDBUS_CMD_EP_MAKE) */ -enum kdbus_cmd { +enum { /* kdbus control node commands: require unset state */ KDBUS_CMD_BUS_MAKE = _IOWR(KDBUS_IOC_MAGIC, 0x00, struct kdbus_cmd_bus_make), KDBUS_CMD_NS_MAKE = _IOWR(KDBUS_IOC_MAGIC, 0x10, struct kdbus_cmd_ns_make), -- cgit v1.2.1 From 98627dced719f047e9e47af1f855d9c032e548f9 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Fri, 24 May 2013 08:35:47 +0200 Subject: keymap: Add Logitech USB (iTouch) https://launchpad.net/bugs/1152377 --- Makefile.am | 1 + keymaps/logitech-usb | 6 ++++++ src/udev/keymap/95-keymap.rules | 1 + 3 files changed, 8 insertions(+) create mode 100644 keymaps/logitech-usb diff --git a/Makefile.am b/Makefile.am index b278143af2..e63563f87a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2505,6 +2505,7 @@ dist_udevkeymap_DATA = \ keymaps/lenovo-thinkpad_x6_tablet \ keymaps/lenovo-thinkpad_x200_tablet \ keymaps/lg-x110 \ + keymaps/logitech-usb \ keymaps/logitech-wave \ keymaps/logitech-wave-cordless \ keymaps/logitech-wave-pro-cordless \ diff --git a/keymaps/logitech-usb b/keymaps/logitech-usb new file mode 100644 index 0000000000..728f0e02b2 --- /dev/null +++ b/keymaps/logitech-usb @@ -0,0 +1,6 @@ +0x90001 shop # Shopping +0x90002 config # iTouch +0x90003 finance # Finance +0x90004 prog1 # My Sites +0x90005 prog2 # Community +0xC0183 media # Media diff --git a/src/udev/keymap/95-keymap.rules b/src/udev/keymap/95-keymap.rules index df1bffefd1..994950cbaa 100644 --- a/src/udev/keymap/95-keymap.rules +++ b/src/udev/keymap/95-keymap.rules @@ -23,6 +23,7 @@ LABEL="keyboard_usbcheck" ENV{ID_VENDOR}=="Genius", ENV{ID_MODEL_ID}=="0708", ENV{ID_USB_INTERFACE_NUM}=="01", RUN+="keymap $name genius-slimstar-320" ENV{ID_VENDOR}=="Logitech*", ATTRS{name}=="Logitech USB Multimedia Keyboard", RUN+="keymap $name logitech-wave" ENV{ID_VENDOR}=="Logitech*", ATTRS{name}=="Logitech USB Receiver", RUN+="keymap $name logitech-wave-cordless" +ENV{ID_VENDOR}=="Logitech*", ATTRS{name}=="* Logitech USB Keyboard*", RUN+="keymap $name logitech-usb" # Logitech Cordless Wave Pro looks slightly weird; some hotkeys are coming through the mouse interface ENV{ID_VENDOR_ID}=="046d", ENV{ID_MODEL_ID}=="c52[9b]", ATTRS{name}=="Logitech USB Receiver", RUN+="keymap $name logitech-wave-pro-cordless" -- cgit v1.2.1 From 89b4fc46565f2cd92a538e72a720677345525d76 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 28 May 2013 17:04:35 +0900 Subject: bus: properly unmap mapped area --- src/libsystemd-bus/bus-message.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c index 55c2d62885..6f2f3e9039 100644 --- a/src/libsystemd-bus/bus-message.c +++ b/src/libsystemd-bus/bus-message.c @@ -65,8 +65,8 @@ static void message_free_part(sd_bus_message *m, struct bus_body_part *part) { if (!part->sealed) bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped); else { - if (part->size > 0) - assert_se(munmap(part->data, PAGE_ALIGN(part->size)) == 0); + if (part->mapped > 0) + assert_se(munmap(part->data, part->mapped) == 0); close_nointr_nofail(part->memfd); } @@ -1244,7 +1244,6 @@ static void message_extend_containers(sd_bus_message *m, size_t expand) { for (c = m->containers; c < m->containers + m->n_containers; c++) if (c->array_size) *c->array_size += expand; - } static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) { -- cgit v1.2.1 From 76b7742c135ad6dac789ee7d27ebf90d188f578b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 29 May 2013 16:58:31 +0900 Subject: bus: when adding memfds to cache and we shorten them, make sure to unmap the remainder --- src/libsystemd-bus/bus-kernel.c | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index 10b7a8aba4..0ece1f014d 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -715,12 +715,12 @@ int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) { if (!bus || !bus->is_kernel) return -ENOTSUP; - assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) == 0); + assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0); if (bus->n_memfd_cache <= 0) { int r; - assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) == 0); + assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0); r = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, &fd); if (r < 0) @@ -740,20 +740,21 @@ int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) { *size = c->size; fd = c->fd; - assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) == 0); + assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0); return fd; } static void close_and_munmap(int fd, void *address, size_t size) { if (size > 0) - assert_se(munmap(address, PAGE_ALIGN(size)) == 0); + assert_se(munmap(address, PAGE_ALIGN(size)) >= 0); close_nointr_nofail(fd); } void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) { struct memfd_cache *c; + uint64_t max_sz = PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX); assert(fd >= 0); assert(size == 0 || address); @@ -763,10 +764,10 @@ void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) { return; } - assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) == 0); + assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0); if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) { - assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) == 0); + assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0); close_and_munmap(fd, address, size); return; @@ -777,16 +778,14 @@ void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) { c->address = address; /* If overly long, let's return a bit to the OS */ - if (size > MEMFD_CACHE_ITEM_SIZE_MAX) { - uint64_t sz = MEMFD_CACHE_ITEM_SIZE_MAX; - - ioctl(bus->input_fd, KDBUS_CMD_MEMFD_SIZE_SET, &sz); - - c->size = MEMFD_CACHE_ITEM_SIZE_MAX; + if (size > max_sz) { + assert_se(ioctl(fd, KDBUS_CMD_MEMFD_SIZE_SET, &max_sz) >= 0); + assert_se(munmap((uint8_t*) address + max_sz, PAGE_ALIGN(size - max_sz)) >= 0); + c->size = max_sz; } else c->size = size; - assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) == 0); + assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0); } void bus_kernel_flush_memfd(sd_bus *b) { @@ -794,10 +793,6 @@ void bus_kernel_flush_memfd(sd_bus *b) { assert(b); - for (i = 0; i < b->n_memfd_cache; i++) { - if (b->memfd_cache[i].size > 0) - assert_se(munmap(b->memfd_cache[i].address, PAGE_ALIGN(b->memfd_cache[i].size)) == 0); - - close_nointr_nofail(b->memfd_cache[i].fd); - } + for (i = 0; i < b->n_memfd_cache; i++) + close_and_munmap(b->memfd_cache[i].fd, b->memfd_cache[i].address, b->memfd_cache[i].size); } -- cgit v1.2.1 From 832d16a616597f8b29645445f8be4284ee7ae1c0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 29 May 2013 16:59:10 +0900 Subject: bus: rework benchmark test to actually yield useful results --- src/libsystemd-bus/bus-kernel.h | 4 +- src/libsystemd-bus/test-bus-kernel-benchmark.c | 218 ++++++++++++------------- 2 files changed, 106 insertions(+), 116 deletions(-) diff --git a/src/libsystemd-bus/bus-kernel.h b/src/libsystemd-bus/bus-kernel.h index dddecfb210..9515e8f05f 100644 --- a/src/libsystemd-bus/bus-kernel.h +++ b/src/libsystemd-bus/bus-kernel.h @@ -38,11 +38,11 @@ /* When we cache a memfd block for reuse, we will truncate blocks * longer than this in order not to keep too much data around. */ -#define MEMFD_CACHE_ITEM_SIZE_MAX (32*1024) +#define MEMFD_CACHE_ITEM_SIZE_MAX (128*1024) /* This determines at which minimum size we prefer sending memfds over * sending vectors */ -#define MEMFD_MIN_SIZE (32*1024) +#define MEMFD_MIN_SIZE (96*1024) /* The size of the per-connection memory pool that we set up and where * the kernel places our incoming messages */ diff --git a/src/libsystemd-bus/test-bus-kernel-benchmark.c b/src/libsystemd-bus/test-bus-kernel-benchmark.c index 403af885c3..0cf685e6de 100644 --- a/src/libsystemd-bus/test-bus-kernel-benchmark.c +++ b/src/libsystemd-bus/test-bus-kernel-benchmark.c @@ -31,11 +31,10 @@ #include "bus-kernel.h" #include "bus-internal.h" -#define N_TRIES 500 -#define MAX_SIZE (5*1024*1024) +#define N_TRIES 10000 +#define MAX_SIZE (1*1024*1024) -static void server(sd_bus *b, usec_t *result) { - usec_t x = 0; +static void server(sd_bus *b, size_t *result) { int r; for (;;) { @@ -46,85 +45,123 @@ static void server(sd_bus *b, usec_t *result) { if (r == 0) assert_se(sd_bus_wait(b, (usec_t) -1) >= 0); - if (!m) continue; - /* log_error("huhu %s from %s", sd_bus_message_get_member(m), sd_bus_message_get_sender(m)); */ - - if (sd_bus_message_is_method_call(m, "benchmark.server", "Work")) { - _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; - size_t i, sz; - char *q; - const char *p; - - assert_se(sd_bus_message_read_array(m, 'y', (const void**) &p, &sz) > 0); - assert_se(sd_bus_message_new_method_return(b, m, &reply) >= 0); - assert_se(sd_bus_message_append_array_space(reply, 'y', sz, (void**) &q) >= 0); - - x = now(CLOCK_MONOTONIC); + if (sd_bus_message_is_method_call(m, "benchmark.server", "Ping")) + assert_se(sd_bus_reply_method_return(b, m, NULL) >= 0); + else if (sd_bus_message_is_method_call(m, "benchmark.server", "Work")) { + const void *p; + size_t sz; - for (i = 0; i < sz; i++) - q[i] = toupper(p[i]); + /* Make sure the mmap is mapped */ + assert_se(sd_bus_message_read_array(m, 'y', &p, &sz) > 0); - x = now(CLOCK_MONOTONIC) - x; - - assert_se(sd_bus_send(b, reply, NULL) >= 0); + assert_se(sd_bus_reply_method_return(b, m, NULL) >= 0); } else if (sd_bus_message_is_method_call(m, "benchmark.server", "Exit")) { - usec_t t; + uint64_t res; + assert_se(sd_bus_message_read(m, "t", &res) > 0); - assert_se(sd_bus_message_read(m, "t", &t) > 0); - assert_se(t >= x); - *result = t - x; + *result = res; return; - } else if (sd_bus_message_is_method_call(m, "benchmark.server", "Ping")) { - assert_se(sd_bus_reply_method_return(b, m, "y", 1) >= 0); } else assert_not_reached("Unknown method"); } } -static void client(sd_bus *b, size_t sz) { +static void transaction(sd_bus *b, size_t sz) { _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL; - char *p; - const char *q; - usec_t t; - size_t l, i; - - assert_se(sd_bus_call_method(b, ":1.1", "/", "benchmark.server", "Ping", NULL, NULL, NULL) >= 0); + /* size_t psz, i; */ + uint8_t *p; assert_se(sd_bus_message_new_method_call(b, ":1.1", "/", "benchmark.server", "Work", &m) >= 0); assert_se(sd_bus_message_append_array_space(m, 'y', sz, (void**) &p) >= 0); - for (i = 0; i < sz; i++) - p[i] = 'a' + (char) (i % 26); + /* Touch every page */ + /* psz = page_size(); */ + /* for (i = 0; i < sz; i += psz) */ + /* p[i] = 'X'; */ - t = now(CLOCK_MONOTONIC); assert_se(sd_bus_send_with_reply_and_block(b, m, 0, NULL, &reply) >= 0); - t = now(CLOCK_MONOTONIC) - t; +} + +static void client(const char *address) { + _cleanup_bus_message_unref_ sd_bus_message *x = NULL; + size_t lsize, rsize, csize; + sd_bus *b; + int r; + + r = sd_bus_new(&b); + assert_se(r >= 0); + + r = sd_bus_set_address(b, address); + assert_se(r >= 0); + + r = sd_bus_start(b); + assert_se(r >= 0); + + assert_se(sd_bus_call_method(b, ":1.1", "/", "benchmark.server", "Ping", NULL, NULL, NULL) >= 0); + + lsize = 1; + rsize = MAX_SIZE; + + for (;;) { + usec_t copy, memfd, t; + unsigned i; + + csize = (lsize + rsize) / 2; + + log_info("Trying size=%zu", csize); + + if (csize <= lsize) + break; + + if (csize <= 0) + break; - assert_se(sd_bus_message_read_array(reply, 'y', (const void**) &q, &l) > 0); - assert_se(l == sz); + log_info("copying..."); + b->use_memfd = 0; + t = now(CLOCK_MONOTONIC); + for (i = 0; i < N_TRIES; i++) + transaction(b, csize); + copy = (now(CLOCK_MONOTONIC) - t); + log_info("%llu usec per copy transaction", (unsigned long long) (copy / N_TRIES)); + + log_info("sending memfd..."); + b->use_memfd = -1; + t = now(CLOCK_MONOTONIC); + for (i = 0; i < N_TRIES; i++) + transaction(b, csize); + memfd = (now(CLOCK_MONOTONIC) - t); + log_info("%llu usec per memfd transaction", (unsigned long long) (memfd / N_TRIES)); - for (i = 0; i < sz; i++) { - assert_se(q[i] == 'A' + (char) (i % 26)); + if (copy == memfd) + break; + + if (copy < memfd) + lsize = csize; + else + rsize = csize; } - sd_bus_message_unref(m); + assert_se(sd_bus_message_new_method_call(b, ":1.1", "/", "benchmark.server", "Exit", &x) >= 0); + assert_se(sd_bus_message_append(x, "t", csize) >= 0); + assert_se(sd_bus_send(b, x, NULL) >= 0); - assert_se(sd_bus_message_new_method_call(b, ":1.1", "/", "benchmark.server", "Exit", &m) >= 0); - assert_se(sd_bus_message_append(m, "t", t) >= 0); - assert_se(sd_bus_send(b, m, NULL) >= 0); + sd_bus_unref(b); } -static void run_benchmark(size_t sz, bool force_copy, usec_t *result) { - - _cleanup_close_ int bus_ref = -1; +int main(int argc, char *argv[]) { _cleanup_free_ char *bus_name = NULL, *address = NULL; + _cleanup_close_ int bus_ref = -1; + cpu_set_t cpuset; + size_t result; sd_bus *b; - int r; pid_t pid; + int r; + + log_set_max_level(LOG_DEBUG); bus_ref = bus_kernel_create("deine-mutter", &bus_name); if (bus_ref == -ENOENT) @@ -138,88 +175,41 @@ static void run_benchmark(size_t sz, bool force_copy, usec_t *result) { r = sd_bus_new(&b); assert_se(r >= 0); - b->use_memfd = force_copy ? 0 : -1; - r = sd_bus_set_address(b, address); assert_se(r >= 0); r = sd_bus_start(b); assert_se(r >= 0); + sync(); + setpriority(PRIO_PROCESS, 0, -19); + pid = fork(); assert_se(pid >= 0); if (pid == 0) { + CPU_ZERO(&cpuset); + CPU_SET(0, &cpuset); + pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + close_nointr_nofail(bus_ref); sd_bus_unref(b); - r = sd_bus_new(&b); - assert_se(r >= 0); - - b->use_memfd = force_copy ? 0 : -1; - - r = sd_bus_set_address(b, address); - assert_se(r >= 0); - - r = sd_bus_start(b); - assert_se(r >= 0); - - client(b, sz); + client(address); _exit(0); } - server(b, result); - sd_bus_unref(b); - - assert_se(waitpid(pid, NULL, 0) == pid); -} - -int main(int argc, char *argv[]) { - size_t lsize, rsize, csize; + CPU_ZERO(&cpuset); + CPU_SET(1, &cpuset); + pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - log_set_max_level(LOG_DEBUG); + server(b, &result); - lsize = 1; - rsize = MAX_SIZE; + log_info("Copying/memfd are equally fast at %zu", result); - for (;;) { - usec_t copy = 0, memfd = 0; - unsigned i; - - csize = (lsize + rsize) / 2; - - log_info("Trying size=%zu", csize); - - if (csize <= lsize) - break; - - for (i = 0; i < N_TRIES; i++) { - usec_t t; - - run_benchmark(csize, true, &t); - copy += t; - } - - for (i = 0; i < N_TRIES; i++) { - usec_t t; - - run_benchmark(csize, false, &t); - memfd += t; - } - - copy /= N_TRIES; - memfd /= N_TRIES; - - if (copy == memfd) - break; - - if (copy < memfd) - lsize = csize; - else - rsize = csize; - } + assert_se(waitpid(pid, NULL, 0) == pid); - log_info("Copying/memfd are equally fast at %zu", csize); + sd_bus_unref(b); return 0; } -- cgit v1.2.1 From 4f8d551ff0177df87fae6cb970471186a422d064 Mon Sep 17 00:00:00 2001 From: Zachary Cook Date: Mon, 13 May 2013 18:00:37 -0400 Subject: systemd: record efi timestamps after /sys is mounted This partially reverts commit c3a170f3, which moved efi_get_boot_timestamps too early in main(), before /sys is assured to be mounted Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=64371 [tomegun: in particular /sys/firmware/efi/efivars needs to be mounted, which is not a problem if a systemd-initramfs containing the correct module is being used. But not everyone uses an initramfs...] --- src/core/main.c | 9 +-------- src/core/manager.c | 6 ++++++ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index 7fc06bea05..bf1e3e8ffa 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -69,7 +69,6 @@ #include "ima-setup.h" #include "fileio.h" #include "smack-setup.h" -#include "efivars.h" static enum { ACTION_RUN, @@ -1239,8 +1238,6 @@ int main(int argc, char *argv[]) { dual_timestamp initrd_timestamp = { 0ULL, 0ULL }; dual_timestamp userspace_timestamp = { 0ULL, 0ULL }; dual_timestamp kernel_timestamp = { 0ULL, 0ULL }; - dual_timestamp firmware_timestamp = { 0ULL, 0ULL }; - dual_timestamp loader_timestamp = { 0ULL, 0ULL }; static char systemd[] = "systemd"; bool skip_setup = false; int j; @@ -1289,9 +1286,7 @@ int main(int argc, char *argv[]) { log_show_color(isatty(STDERR_FILENO) > 0); if (getpid() == 1 && detect_container(NULL) <= 0) { -#ifdef ENABLE_EFI - efi_get_boot_timestamps(&userspace_timestamp, &firmware_timestamp, &loader_timestamp); -#endif + /* Running outside of a container as PID 1 */ arg_running_as = SYSTEMD_SYSTEM; make_null_stdio(); @@ -1627,8 +1622,6 @@ int main(int argc, char *argv[]) { m->shutdown_watchdog = arg_shutdown_watchdog; m->userspace_timestamp = userspace_timestamp; m->kernel_timestamp = kernel_timestamp; - m->firmware_timestamp = firmware_timestamp; - m->loader_timestamp = loader_timestamp; m->initrd_timestamp = initrd_timestamp; manager_set_default_rlimits(m, arg_default_rlimit); diff --git a/src/core/manager.c b/src/core/manager.c index 0508628b21..a7cfe57038 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -70,6 +70,7 @@ #include "cgroup-util.h" #include "path-util.h" #include "audit-fd.h" +#include "efivars.h" #include "env-util.h" /* As soon as 16 units are in our GC queue, make sure to run a gc sweep */ @@ -439,6 +440,11 @@ int manager_new(SystemdRunningAs running_as, Manager **_m) { if (!m) return -ENOMEM; +#ifdef ENABLE_EFI + if (detect_container(NULL) <= 0) + efi_get_boot_timestamps(&m->userspace_timestamp, &m->firmware_timestamp, &m->loader_timestamp); +#endif + m->running_as = running_as; m->name_data_slot = m->conn_data_slot = m->subscribed_data_slot = -1; m->exit_code = _MANAGER_EXIT_CODE_INVALID; -- cgit v1.2.1 From 62b3e928de2818a03b2dd04868815c888ee28c24 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 30 May 2013 05:35:42 +0200 Subject: bus: update for kdbus changes --- src/libsystemd-bus/bus-kernel.c | 66 +++++++++++++++++++--------------------- src/libsystemd-bus/bus-message.c | 8 +++-- src/libsystemd-bus/kdbus.h | 21 ++++++------- 3 files changed, 48 insertions(+), 47 deletions(-) diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index 0ece1f014d..ad0d573149 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -313,12 +313,7 @@ fail: } int bus_kernel_take_fd(sd_bus *b) { - uint8_t h[ALIGN8(sizeof(struct kdbus_cmd_hello)) + - ALIGN8(KDBUS_ITEM_HEADER_SIZE) + - ALIGN8(sizeof(struct kdbus_vec))] = {}; - - struct kdbus_cmd_hello *hello = (struct kdbus_cmd_hello*) h; - + struct kdbus_cmd_hello hello; int r; assert(b); @@ -328,41 +323,38 @@ int bus_kernel_take_fd(sd_bus *b) { b->use_memfd = 1; + zero(hello); + hello.size = sizeof(hello); + hello.conn_flags = b->hello_flags; + hello.pool_size = KDBUS_POOL_SIZE; + + r = ioctl(b->input_fd, KDBUS_CMD_HELLO, &hello); + if (r < 0) + return -errno; + if (!b->kdbus_buffer) { - b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); + b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, b->input_fd, 0); if (b->kdbus_buffer == MAP_FAILED) { b->kdbus_buffer = NULL; return -errno; } } - hello->size = sizeof(h); - hello->conn_flags = b->hello_flags; - - hello->items[0].type = KDBUS_HELLO_POOL; - hello->items[0].size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec); - hello->items[0].vec.address = (uint64_t) b->kdbus_buffer; - hello->items[0].vec.size = KDBUS_POOL_SIZE; - - r = ioctl(b->input_fd, KDBUS_CMD_HELLO, hello); - if (r < 0) - return -errno; - /* The higher 32bit of both flags fields are considered * 'incompatible flags'. Refuse them all for now. */ - if (hello->bus_flags > 0xFFFFFFFFULL || - hello->conn_flags > 0xFFFFFFFFULL) + if (hello.bus_flags > 0xFFFFFFFFULL || + hello.conn_flags > 0xFFFFFFFFULL) return -ENOTSUP; - if (hello->bloom_size != BLOOM_SIZE) + if (hello.bloom_size != BLOOM_SIZE) return -ENOTSUP; - if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello->id) < 0) + if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello.id) < 0) return -ENOMEM; b->is_kernel = true; b->bus_client = true; - b->can_fds = !!(hello->conn_flags & KDBUS_HELLO_ACCEPT_FD); + b->can_fds = !!(hello.conn_flags & KDBUS_HELLO_ACCEPT_FD); r = bus_start_running(b); if (r < 0) @@ -408,12 +400,14 @@ int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m) { } static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) { + uint64_t off; struct kdbus_item *d; assert(bus); assert(k); - ioctl(bus->input_fd, KDBUS_CMD_MSG_RELEASE, k); + off = (uint8_t *)k - (uint8_t *)bus->kdbus_buffer; + ioctl(bus->input_fd, KDBUS_CMD_MSG_RELEASE, &off); KDBUS_ITEM_FOREACH(d, k) { @@ -446,10 +440,10 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess l = d->size - offsetof(struct kdbus_item, data); - if (d->type == KDBUS_MSG_PAYLOAD_VEC) { + if (d->type == KDBUS_MSG_PAYLOAD_OFF) { if (!h) { - h = UINT64_TO_PTR(d->vec.address); + h = (struct bus_header *)((uint8_t *)bus->kdbus_buffer + d->vec.offset); if (!bus_header_is_complete(h, d->vec.size)) return -EBADMSG; @@ -500,7 +494,7 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess l = d->size - offsetof(struct kdbus_item, data); - if (d->type == KDBUS_MSG_PAYLOAD_VEC) { + if (d->type == KDBUS_MSG_PAYLOAD_OFF) { size_t begin_body; begin_body = BUS_MESSAGE_BODY_BEGIN(m); @@ -516,15 +510,19 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess goto fail; } + /* A -1 offset is NUL padding. */ + part->is_zero = d->vec.offset == ~0ULL; + if (idx >= begin_body) { - part->data = UINT64_TO_PTR(d->vec.address); + if (!part->is_zero) + part->data = (uint8_t *)bus->kdbus_buffer + d->vec.offset; part->size = d->vec.size; } else { - part->data = d->vec.address != 0 ? (uint8_t*) UINT64_TO_PTR(d->vec.address) + (begin_body - idx) : NULL; + if (!part->is_zero) + part->data = (uint8_t *)bus->kdbus_buffer + d->vec.offset + (begin_body - idx); part->size = d->vec.size - (begin_body - idx); } - part->is_zero = d->vec.address == 0; part->sealed = true; } @@ -631,21 +629,21 @@ fail: } int bus_kernel_read_message(sd_bus *bus, sd_bus_message **m) { - uint64_t addr; + uint64_t off; struct kdbus_msg *k; int r; assert(bus); assert(m); - r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &addr); + r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &off); if (r < 0) { if (errno == EAGAIN) return 0; return -errno; } - k = UINT64_TO_PTR(addr); + k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + off); r = bus_kernel_make_message(bus, k, m); if (r <= 0) diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c index 6f2f3e9039..e6bf9db99a 100644 --- a/src/libsystemd-bus/bus-message.c +++ b/src/libsystemd-bus/bus-message.c @@ -125,8 +125,12 @@ static void message_free(sd_bus_message *m) { if (m->free_kdbus) free(m->kdbus); - if (m->release_kdbus) - ioctl(m->bus->input_fd, KDBUS_CMD_MSG_RELEASE, m->kdbus); + if (m->release_kdbus) { + uint64_t off; + + off = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer; + ioctl(m->bus->input_fd, KDBUS_CMD_MSG_RELEASE, &off); + } if (m->bus) sd_bus_unref(m->bus); diff --git a/src/libsystemd-bus/kdbus.h b/src/libsystemd-bus/kdbus.h index dfc64ffe24..3b7783e1b1 100644 --- a/src/libsystemd-bus/kdbus.h +++ b/src/libsystemd-bus/kdbus.h @@ -73,8 +73,11 @@ struct kdbus_timestamp { }; struct kdbus_vec { - __u64 address; __u64 size; + union { + __u64 address; + __u64 offset; + }; }; struct kdbus_memfd { @@ -88,6 +91,7 @@ enum { /* Filled in by userspace */ KDBUS_MSG_PAYLOAD_VEC, /* .data_vec, reference to memory area */ + KDBUS_MSG_PAYLOAD_OFF, /* .data_vec, reference to memory area */ KDBUS_MSG_PAYLOAD_MEMFD, /* file descriptor of a special data file */ KDBUS_MSG_FDS, /* .data_fds of file descriptors */ KDBUS_MSG_BLOOM, /* for broadcasts, carries bloom filter blob in .data */ @@ -212,6 +216,7 @@ struct kdbus_policy_access { __u64 id; /* uid, gid, 0 */ }; +//FIXME: convert access to access[] struct kdbus_policy { KDBUS_PART_HEADER; union { @@ -242,13 +247,6 @@ enum { KDBUS_HELLO_ATTACH_AUDIT = 1 << 16, }; -/* Items to append to struct kdbus_cmd_hello */ -enum { - _KDBUS_HELLO_NULL, - KDBUS_HELLO_POOL, /* kdbus_vec, userspace supplied pool to - * place received messages */ -}; - struct kdbus_cmd_hello { __u64 size; @@ -269,6 +267,7 @@ struct kdbus_cmd_hello { __u64 id; /* id assigned to this connection */ __u64 bloom_size; /* The bloom filter size chosen by the * bus owner */ + __u64 pool_size; /* maximum size of pool buffer */ struct kdbus_item items[0]; }; @@ -284,7 +283,8 @@ enum { _KDBUS_MAKE_NULL, KDBUS_MAKE_NAME, KDBUS_MAKE_CGROUP, /* the cgroup hierarchy ID for which to attach - * cgroup membership paths * to messages. */ + * cgroup membership paths to messages. + * FIXME: remove, use *the* hierarchy */ KDBUS_MAKE_CRED, /* allow translator services which connect * to the bus on behalf of somebody else, * allow specifiying the credentials of the @@ -304,7 +304,6 @@ struct kdbus_cmd_bus_make { * KDBUS_CMD_HELLO, later */ __u64 bloom_size; /* size of the bloom filter for this bus */ struct kdbus_item items[0]; - }; struct kdbus_cmd_ep_make { @@ -414,7 +413,7 @@ enum { /* kdbus ep node commands: require connected state */ KDBUS_CMD_MSG_SEND = _IOWR(KDBUS_IOC_MAGIC, 0x40, struct kdbus_msg), KDBUS_CMD_MSG_RECV = _IOWR(KDBUS_IOC_MAGIC, 0x41, __u64 *), - KDBUS_CMD_MSG_RELEASE = _IOWR(KDBUS_IOC_MAGIC, 0x42, struct kdbus_msg), + KDBUS_CMD_MSG_RELEASE = _IOWR(KDBUS_IOC_MAGIC, 0x42, __u64 *), KDBUS_CMD_NAME_ACQUIRE = _IOWR(KDBUS_IOC_MAGIC, 0x50, struct kdbus_cmd_name), KDBUS_CMD_NAME_RELEASE = _IOWR(KDBUS_IOC_MAGIC, 0x51, struct kdbus_cmd_name), -- cgit v1.2.1 From ccd90a976dbaf2acd1b62eb46f26bc35ae090467 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 24 May 2013 13:34:53 -0400 Subject: Fix CPUShares configuration option This fixes the error message "Unknown or unsupported cgroup attribute CPUShares". --- src/core/cgroup-semantics.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/cgroup-semantics.c b/src/core/cgroup-semantics.c index 82b02bbd78..7df9d014e9 100644 --- a/src/core/cgroup-semantics.c +++ b/src/core/cgroup-semantics.c @@ -255,7 +255,7 @@ static int map_blkio(const CGroupSemantics *s, const char *value, char **ret) { } static const CGroupSemantics semantics[] = { - { "cpu", "cpu.shares", "CPUShare", false, parse_cpu_shares, NULL, NULL }, + { "cpu", "cpu.shares", "CPUShares", false, parse_cpu_shares, NULL, NULL }, { "memory", "memory.soft_limit_in_bytes", "MemorySoftLimit", false, parse_memory_limit, NULL, NULL }, { "memory", "memory.limit_in_bytes", "MemoryLimit", false, parse_memory_limit, NULL, NULL }, { "devices", "devices.allow", "DeviceAllow", true, parse_device, map_device, NULL }, -- cgit v1.2.1 From 310b59edcf0a98343425a47ea5835fc670c0cda3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 29 May 2013 22:38:06 -0400 Subject: man: link to XKB conf. guide in localectl(1) --- man/localectl.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/man/localectl.xml b/man/localectl.xml index febdeec150..4a0457018f 100644 --- a/man/localectl.xml +++ b/man/localectl.xml @@ -49,7 +49,9 @@ - localectl OPTIONS COMMAND + localectl + OPTIONS + COMMAND @@ -276,6 +278,9 @@ vconsole.conf5, loadkeys1, kbd4, + + The XKB Configuration Guide + , systemctl1, systemd-localed.service8 -- cgit v1.2.1 From 827f70eb764428baa397e9f3e295c470a1fd43e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 29 May 2013 22:31:20 -0400 Subject: man: fix display of keys which appear in two sections in directive index When an index key appeared in multiple sections (e.g. CPUAffinity= was present in both "SYSTEM MANAGER DIRECTIVES" and "UNIT DIRECTIVES"), when lxml was used, the key would be not be displayed in all but one of those sections, and only an empty element would be present. This happens because lxml allows only one parent for each node, and when the same formatted element was used in multiple places, it was actually moved between them. Fix this by making a copy of the element. The bug was present since lxml support was introduced. Also fix some indentation issues. --- make-directive-index.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/make-directive-index.py b/make-directive-index.py index 396947b303..468d14da75 100755 --- a/make-directive-index.py +++ b/make-directive-index.py @@ -21,6 +21,7 @@ import sys import collections import re from xml_helper import * +from copy import deepcopy TEMPLATE = '''\ @@ -226,19 +227,20 @@ def _make_section(template, name, directives, formatting): for varname, manpages in sorted(directives.items()): entry = tree.SubElement(varlist, 'varlistentry') term = tree.SubElement(entry, 'term') - term.append(formatting[varname]) + display = deepcopy(formatting[varname]) + term.append(display) para = tree.SubElement(tree.SubElement(entry, 'listitem'), 'para') b = None for manpage, manvolume in sorted(set(manpages)): - if b is not None: - b.tail = ', ' - b = tree.SubElement(para, 'citerefentry') - c = tree.SubElement(b, 'refentrytitle') - c.text = manpage - d = tree.SubElement(b, 'manvolnum') - d.text = manvolume + if b is not None: + b.tail = ', ' + b = tree.SubElement(para, 'citerefentry') + c = tree.SubElement(b, 'refentrytitle') + c.text = manpage + d = tree.SubElement(b, 'manvolnum') + d.text = manvolume entry.tail = '\n\n' def _make_colophon(template, groups): @@ -264,7 +266,7 @@ def _make_page(template, directive_groups, formatting): } """ for name, directives in directive_groups.items(): - _make_section(template, name, directives, formatting) + _make_section(template, name, directives, formatting) _make_colophon(template, directive_groups.values()) -- cgit v1.2.1 From cb0edd735c40f3bda8a1956489a5794c322aee59 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Wed, 29 May 2013 15:38:04 -0400 Subject: core: use the same test as upstart for apparmor Lennart: > Hmm, I just noticed this patch: > > https://code.launchpad.net/~mdeslaur/upstart/apparmor-support/+merge/164169 > > It contains a different check for AppArmor. Basically something like this: > > /sys/module/apparmor/parameters/enabled == 'Y' > > I'd prefer if we could change our code to do the same, given that > the Ubuntu guys are guys are upstream for apparmor. https://bugs.freedesktop.org/show_bug.cgi?id=63312 --- src/core/condition.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/core/condition.c b/src/core/condition.c index 4293d6d1f1..b2617ef5bf 100644 --- a/src/core/condition.c +++ b/src/core/condition.c @@ -157,13 +157,24 @@ static bool test_virtualization(const char *parameter) { return v > 0 && streq(parameter, id); } +static bool test_apparmor_enabled(void) { + int r; + _cleanup_free_ char *p = NULL; + + r = read_one_line_file("/sys/module/apparmor/parameters/enabled", &p); + if (r < 0) + return false; + + return parse_boolean(p) > 0; +} + static bool test_security(const char *parameter) { #ifdef HAVE_SELINUX if (streq(parameter, "selinux")) return is_selinux_enabled() > 0; #endif if (streq(parameter, "apparmor")) - return access("/sys/kernel/security/apparmor/", F_OK) == 0; + return test_apparmor_enabled(); if (streq(parameter, "ima")) return access("/sys/kernel/security/ima/", F_OK) == 0; if (streq(parameter, "smack")) -- cgit v1.2.1 From 8de1fd281e82c038797b02a447056a382f9b5110 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 29 May 2013 22:48:58 -0400 Subject: build-sys: more pretty colors --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 14a90c56d0..c24b4a8187 100644 --- a/configure.ac +++ b/configure.ac @@ -128,6 +128,7 @@ CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [\ -ffast-math \ -fno-common \ -fdiagnostics-show-option \ + -fdiagnostics-color \ -fno-strict-aliasing \ -fvisibility=hidden \ -ffunction-sections \ -- cgit v1.2.1 From 23ad4dd8844c582929115a11ed2830a1371568d6 Mon Sep 17 00:00:00 2001 From: "Jan Alexander Steffens (heftig)" Date: Tue, 28 May 2013 20:45:34 +0200 Subject: journald: DO recalculate the ACL mask, but only if it doesn't exist Since 11ec7ce, journald isn't setting the ACLs properly anymore if the files had no ACLs to begin with: acl_set_fd fails with EINVAL. An ACL with ACL_USER or ACL_GROUP entries but no ACL_MASK entry is invalid, so make sure a mask exists before trying to set the ACL. --- src/journal/journald-server.c | 6 ++++-- src/shared/acl-util.c | 28 ++++++++++++++++++++++++++++ src/shared/acl-util.h | 1 + 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index b717b92ffb..da5b725863 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -227,9 +227,11 @@ void server_fix_perms(Server *s, JournalFile *f, uid_t uid) { } } - /* We do not recalculate the mask here, so that the fchmod() mask above stays intact. */ + /* We do not recalculate the mask unconditionally here, + * so that the fchmod() mask above stays intact. */ if (acl_get_permset(entry, &permset) < 0 || - acl_add_perm(permset, ACL_READ) < 0) { + acl_add_perm(permset, ACL_READ) < 0 || + calc_acl_mask_if_needed(&acl) < 0) { log_warning("Failed to patch ACL on %s, ignoring: %m", f->path); goto finish; } diff --git a/src/shared/acl-util.c b/src/shared/acl-util.c index 48bb12f46b..fb04e49dc4 100644 --- a/src/shared/acl-util.c +++ b/src/shared/acl-util.c @@ -69,6 +69,34 @@ int acl_find_uid(acl_t acl, uid_t uid, acl_entry_t *entry) { return 0; } +int calc_acl_mask_if_needed(acl_t *acl_p) { + acl_entry_t i; + int found; + + assert(acl_p); + + for (found = acl_get_entry(*acl_p, ACL_FIRST_ENTRY, &i); + found > 0; + found = acl_get_entry(*acl_p, ACL_NEXT_ENTRY, &i)) { + + acl_tag_t tag; + + if (acl_get_tag_type(i, &tag) < 0) + return -errno; + + if (tag == ACL_MASK) + return 0; + } + + if (found < 0) + return -errno; + + if (acl_calc_mask(acl_p) < 0) + return -errno; + + return 0; +} + int search_acl_groups(char*** dst, const char* path, bool* belong) { acl_t acl; diff --git a/src/shared/acl-util.h b/src/shared/acl-util.h index 23090d9984..36ef490d7e 100644 --- a/src/shared/acl-util.h +++ b/src/shared/acl-util.h @@ -24,4 +24,5 @@ #include int acl_find_uid(acl_t acl, uid_t uid, acl_entry_t *entry); +int calc_acl_mask_if_needed(acl_t *acl_p); int search_acl_groups(char*** dst, const char* path, bool* belong); -- cgit v1.2.1 From 9749cd77bc6121a304a7f1eb0f03f26e620dc9da Mon Sep 17 00:00:00 2001 From: Lukas Nykryn Date: Wed, 29 May 2013 14:09:56 +0200 Subject: core: read "debug" from kernel commandline and set log level --- TODO | 3 --- man/kernel-command-line.xml | 12 ++++++++++++ man/systemd.xml | 23 ++++++++++++++++++----- src/core/main.c | 2 ++ 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/TODO b/TODO index f8a1b1b578..7883b7e33a 100644 --- a/TODO +++ b/TODO @@ -56,9 +56,6 @@ Features: complain loudly if they have argv[0][0] == '@' set. https://bugzilla.redhat.com/show_bug.cgi?id=961044 -* read the kernel's console "debug" keyword like we read "quiet" and adjust: - systemd.log_level=debug and maybe systemd.log_target=kmsg - * add an option to nspawn that uses seccomp to make socket(AF_NETLINK, SOCK_RAW, NETLINK_AUDIT) fail the the appropriate error code that makes the audit userspace to think auditing is not available in the diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml index 7ff2709fbd..db5d38a741 100644 --- a/man/kernel-command-line.xml +++ b/man/kernel-command-line.xml @@ -110,6 +110,18 @@ + + debug + + Parameter understood by + both the kernel and the system + and service manager to control + console log verbosity. For + details see + systemd1. + + + emergency single diff --git a/man/systemd.xml b/man/systemd.xml index d009ed8e1c..497dd2bfee 100644 --- a/man/systemd.xml +++ b/man/systemd.xml @@ -1114,15 +1114,28 @@ quiet - If passed turns off + Turn off status output at boot, much like systemd.show_status=false would. Note that this option is also read by the kernel itself and disables - kernel log output to the - kernel. Passing this option hence - turns off the usual output from both - the system manager and the + kernel log output. Passing this option + hence turns off the usual output from + both the system manager and the kernel. + + + + + debug + + Turn on debugging + output. This is equivalent to + systemd.log_level=debug. + Note that this option is also read by + the kernel itself and enables kernel + debug output. Passing this option + hence turns on the debug output from + both the system manager and the kernel. diff --git a/src/core/main.c b/src/core/main.c index bf1e3e8ffa..bb7364054e 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -410,6 +410,8 @@ static int parse_proc_cmdline_word(const char *word) { } else if (streq(word, "quiet")) arg_show_status = false; + else if (streq(word, "debug")) + log_set_max_level(LOG_DEBUG); else if (!in_initrd()) { unsigned i; -- cgit v1.2.1 From 99504dd4c13af7516a976fffc0f68e6f26d3faac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=A1clav=20Pavl=C3=ADn?= Date: Tue, 28 May 2013 11:05:48 +0200 Subject: systemctl: add commands set-default and get-default systemctl set-default NAME links the default.target to the given unit, get-default prints out the path to the currently set default target. --- man/systemctl.xml | 18 +++++++ shell-completion/bash/systemctl | 6 ++- src/core/dbus-manager.c | 28 ++++++++++- src/core/org.freedesktop.systemd1.conf | 4 ++ src/shared/install.c | 86 ++++++++++++++++++++++++++++++++++ src/shared/install.h | 2 + src/systemctl/systemctl.c | 65 ++++++++++++++++++++++++- 7 files changed, 206 insertions(+), 3 deletions(-) diff --git a/man/systemctl.xml b/man/systemctl.xml index 0afb0cc626..430e16c327 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -997,6 +997,24 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service + + get-default + + + Get the default target specified + via default.target link. + + + + + set-default NAME + + + Set the default target to boot into. Command links + default.target to the given unit. + + + load NAME... diff --git a/shell-completion/bash/systemctl b/shell-completion/bash/systemctl index 191b8d13ec..a05b756980 100644 --- a/shell-completion/bash/systemctl +++ b/shell-completion/bash/systemctl @@ -134,9 +134,10 @@ _systemctl () { [STANDALONE]='daemon-reexec daemon-reload default dump emergency exit halt hibernate hybrid-sleep kexec list-jobs list-units list-unit-files poweroff reboot rescue - show-environment suspend' + show-environment suspend get-default' [NAME]='snapshot load' [FILE]='link' + [TARGETS]='set-default' ) for ((i=0; $i <= $COMP_CWORD; i++)); do @@ -210,6 +211,9 @@ _systemctl () { elif __contains_word "$verb" ${VERBS[FILE]}; then comps=$( compgen -A file -- "$cur" ) compopt -o filenames + elif __contains_word "$verb" ${VERBS[TARGETS]}; then + comps=$( __systemctl $mode list-unit-files --type target --full --all \ + | { while read -r a b; do echo " $a"; done; } ) fi COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 56b02a1cf5..f3ddfc9761 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -227,6 +227,13 @@ " \n" \ " \n" \ " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ " \n" #define BUS_MANAGER_INTERFACE_SIGNALS \ @@ -1728,7 +1735,8 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ReenableUnitFiles") || dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "LinkUnitFiles") || dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "PresetUnitFiles") || - dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "MaskUnitFiles")) { + dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "MaskUnitFiles") || + dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "SetDefaultTarget")) { char **l = NULL; DBusMessageIter iter; @@ -1771,6 +1779,8 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, carries_install_info = r; } else if (streq(member, "MaskUnitFiles")) r = unit_file_mask(scope, runtime, NULL, l, force, &changes, &n_changes); + else if (streq(member, "SetDefaultTarget")) + r = unit_file_set_default(scope, NULL, l[0], &changes, &n_changes); else assert_not_reached("Uh? Wrong method"); @@ -1838,6 +1848,22 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, if (!reply) goto oom; + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetDefaultTarget")) { + UnitFileScope scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER; + _cleanup_free_ char *default_target = NULL; + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + r = unit_file_get_default(scope, NULL, &default_target); + + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &default_target, DBUS_TYPE_INVALID)) { + goto oom; + } } else { const BusBoundProperties bps[] = { { "org.freedesktop.systemd1.Manager", bus_systemd_properties, systemd_property_string }, diff --git a/src/core/org.freedesktop.systemd1.conf b/src/core/org.freedesktop.systemd1.conf index a07a8e1ce3..a375dce0b0 100644 --- a/src/core/org.freedesktop.systemd1.conf +++ b/src/core/org.freedesktop.systemd1.conf @@ -86,6 +86,10 @@ send_interface="org.freedesktop.systemd1.Manager" send_member="Dump"/> + + diff --git a/src/shared/install.c b/src/shared/install.c index 8f27c6d479..954dcb1e71 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -1570,6 +1570,92 @@ int unit_file_reenable( return r; } +int unit_file_set_default( + UnitFileScope scope, + const char *root_dir, + char *file, + UnitFileChange **changes, + unsigned *n_changes) { + + _cleanup_lookup_paths_free_ LookupPaths paths = {}; + _cleanup_install_context_done_ InstallContext c = {}; + _cleanup_free_ char *config_path = NULL; + char *path; + int r; + InstallInfo *i = NULL; + + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + + if (unit_name_to_type(file) != UNIT_TARGET) + return -EINVAL; + + r = lookup_paths_init_from_scope(&paths, scope); + if (r < 0) + return r; + + r = get_config_path(scope, false, root_dir, &config_path); + if (r < 0) + return r; + + r = install_info_add_auto(&c, file); + if (r < 0) + return r; + + i = (InstallInfo*)hashmap_first(c.will_install); + + r = unit_file_search(&c, i, &paths, root_dir, false); + if (r < 0) + return r; + + path = strappenda(config_path, "/default.target"); + r = create_symlink(i->path, path, true, changes, n_changes); + if (r < 0) + return r; + + return 0; +} + +int unit_file_get_default( + UnitFileScope scope, + const char *root_dir, + char **name) { + + _cleanup_lookup_paths_free_ LookupPaths paths = {}; + char **p; + int r; + + r = lookup_paths_init_from_scope(&paths, scope); + if (r < 0) + return r; + + STRV_FOREACH(p, paths.unit_path) { + _cleanup_free_ char *path = NULL, *tmp = NULL; + + if (isempty(root_dir)) + path = strappend(*p, "/default.target"); + else + path = strjoin(root_dir, "/", *p, "/default.target", NULL); + + if (!path) + return -ENOMEM; + + r = readlink_malloc(path, &tmp); + if (r == -ENOENT) + continue; + else if (r < 0) + return r; + + *name = strdup(path_get_file_name(tmp)); + if (!*name) + return -ENOMEM; + + return 0; + } + + return -ENOENT; +} + UnitFileState unit_file_get_state( UnitFileScope scope, const char *root_dir, diff --git a/src/shared/install.h b/src/shared/install.h index 94516c9d05..5609d1e8df 100644 --- a/src/shared/install.h +++ b/src/shared/install.h @@ -80,6 +80,8 @@ int unit_file_link(UnitFileScope scope, bool runtime, const char *root_dir, char int unit_file_preset(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes); int unit_file_mask(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes); int unit_file_unmask(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes); +int unit_file_set_default(UnitFileScope scope, const char *root_dir, char *file, UnitFileChange **changes, unsigned *n_changes); +int unit_file_get_default(UnitFileScope scope, const char *root_dir, char **name); UnitFileState unit_file_get_state(UnitFileScope scope, const char *root_dir, const char *filename); diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index f8573d315c..56021a6889 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -1177,6 +1177,59 @@ static int list_dependencies(DBusConnection *bus, char **args) { return list_dependencies_one(bus, u, 0, &units, 0); } +static int get_default(DBusConnection *bus, char **args) { + char *path = NULL; + _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL; + int r; + _cleanup_dbus_error_free_ DBusError error; + + dbus_error_init(&error); + + if (!bus || avoid_bus()) { + r = unit_file_get_default(arg_scope, arg_root, &path); + + if (r < 0) { + log_error("Operation failed: %s", strerror(-r)); + goto finish; + } + + r = 0; + } else { + r = bus_method_call_with_reply( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "GetDefaultTarget", + &reply, + NULL, + DBUS_TYPE_INVALID); + + if (r < 0) { + log_error("Operation failed: %s", strerror(-r)); + goto finish; + } + + if (!dbus_message_get_args(reply, &error, + DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse reply: %s", bus_error_message(&error)); + dbus_error_free(&error); + return -EIO; + } + } + + if (path) + printf("%s\n", path); + +finish: + if ((!bus || avoid_bus()) && path) + free(path); + + return r; + +} + struct job_info { uint32_t id; char *name, *type, *state; @@ -4243,6 +4296,8 @@ static int enable_unit(DBusConnection *bus, char **args) { r = unit_file_mask(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes); else if (streq(verb, "unmask")) r = unit_file_unmask(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes); + else if (streq(verb, "set-default")) + r = unit_file_set_default(arg_scope, arg_root, args[1], &changes, &n_changes); else assert_not_reached("Unknown verb"); @@ -4286,6 +4341,8 @@ static int enable_unit(DBusConnection *bus, char **args) { else if (streq(verb, "unmask")) { method = "UnmaskUnitFiles"; send_force = false; + } else if (streq(verb, "set-default")) { + method = "SetDefaultTarget"; } else assert_not_reached("Unknown verb"); @@ -4585,6 +4642,8 @@ static int systemctl_help(void) { " unmask [NAME...] Unmask one or more units\n" " link [PATH...] Link one or more units files into\n" " the search path\n" + " get-default Get the name of the default target\n" + " set-default NAME Set the default target\n" " is-enabled [NAME...] Check whether unit files are enabled\n\n" "Job Commands:\n" " list-jobs List jobs\n" @@ -5646,6 +5705,8 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError { "link", MORE, 2, enable_unit }, { "switch-root", MORE, 2, switch_root }, { "list-dependencies", LESS, 2, list_dependencies }, + { "set-default", EQUAL, 2, enable_unit }, + { "get-default", LESS, 1, get_default }, }; int left; @@ -5717,7 +5778,9 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError !streq(verbs[i].verb, "preset") && !streq(verbs[i].verb, "mask") && !streq(verbs[i].verb, "unmask") && - !streq(verbs[i].verb, "link")) { + !streq(verbs[i].verb, "link") && + !streq(verbs[i].verb, "set-default") && + !streq(verbs[i].verb, "get-default")) { if (running_in_chroot() > 0) { log_info("Running in chroot, ignoring request."); -- cgit v1.2.1 From 76d5a71de99b6fe0ecc9bfd82ec641a5d408e191 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=A1clav=20Pavl=C3=ADn?= Date: Wed, 29 May 2013 16:08:11 +0200 Subject: systemctl: add command set-log-level Command changes current log level --- TODO | 2 -- man/systemctl.xml | 13 +++++++++++++ src/systemctl/systemctl.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index 7883b7e33a..9ba1de01cb 100644 --- a/TODO +++ b/TODO @@ -91,8 +91,6 @@ Features: * we need dynamic units -* add s.th. like "systemctl set-log-level debug" - * cgtop: make cgtop useful in a container * test/: diff --git a/man/systemctl.xml b/man/systemctl.xml index 430e16c327..54573e8f5f 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -546,6 +546,19 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service + + set-log-level LEVEL + + + Change current log level of the + systemd daemon to + LEVEL (accepts the same values + as described in + systemd1). + + + + start NAME... diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 56021a6889..5ccbbbc0c7 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -4462,6 +4462,51 @@ finish: return r; } +static int set_log_level(DBusConnection *bus, char **args) { + _cleanup_dbus_error_free_ DBusError error; + _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL; + DBusMessageIter iter, sub; + const char* property = "LogLevel"; + const char* interface = "org.freedesktop.systemd1.Manager"; + const char* value; + + assert(bus); + assert(args); + + value = args[1]; + dbus_error_init(&error); + + m = dbus_message_new_method_call("org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.DBus.Properties", + "Set"); + if (!m) + return log_oom(); + + dbus_message_iter_init_append(m, &iter); + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &interface) || + !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &property) || + !dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "s", &sub)) + return log_oom(); + + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &value)) { + dbus_message_iter_abandon_container(&iter, &sub); + return log_oom(); + } + + if (!dbus_message_iter_close_container(&iter, &sub)) + return log_oom(); + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + return -EIO; + } + + return 0; +} + static int unit_is_enabled(DBusConnection *bus, char **args) { _cleanup_dbus_error_free_ DBusError error; int r; @@ -5707,6 +5752,7 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError { "list-dependencies", LESS, 2, list_dependencies }, { "set-default", EQUAL, 2, enable_unit }, { "get-default", LESS, 1, get_default }, + { "set-log-level", EQUAL, 2, set_log_level }, }; int left; -- cgit v1.2.1 From 1058cbf2ad3d62d039f8f0be92d9d37777925a39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 30 May 2013 20:28:09 -0400 Subject: systemctl: suggest 'systemctl daemon-reload' without --system --system is default anyway, and some poor user might type 9 characters without needing to. --- src/core/manager.c | 3 ++- src/shared/util.c | 8 ++++---- src/systemctl/systemctl.c | 8 ++++---- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/core/manager.c b/src/core/manager.c index a7cfe57038..6b0f567663 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -1037,7 +1037,8 @@ int manager_load_unit_prepare(Manager *m, const char *name, const char *path, DB } } - if ((r = unit_add_name(ret, name)) < 0) { + r = unit_add_name(ret, name); + if (r < 0) { unit_free(ret); return r; } diff --git a/src/shared/util.c b/src/shared/util.c index 673e0da6b6..2edf9cd875 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -850,18 +850,18 @@ int readlink_malloc(const char *p, char **r) { } int readlink_and_make_absolute(const char *p, char **r) { - char *target, *k; + _cleanup_free_ char *target = NULL; + char *k; int j; assert(p); assert(r); - if ((j = readlink_malloc(p, &target)) < 0) + j = readlink_malloc(p, &target); + if (j < 0) return j; k = file_in_same_dir(p, target); - free(target); - if (!k) return -ENOMEM; diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 5ccbbbc0c7..6a4c2d6900 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -1913,8 +1913,8 @@ static int start_unit_one( } if (need_daemon_reload(bus, n)) - log_warning("Warning: Unit file of %s changed on disk, 'systemctl %s daemon-reload' recommended.", - n, arg_scope == UNIT_FILE_SYSTEM ? "--system" : "--user"); + log_warning("Warning: Unit file of %s changed on disk, 'systemctl %sdaemon-reload' recommended.", + n, arg_scope == UNIT_FILE_SYSTEM ? "" : "--user "); if (s) { char *p; @@ -2974,10 +2974,10 @@ static void print_status_info(UnitStatusInfo *i) { } if (i->need_daemon_reload) - printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %s daemon-reload' recommended.\n", + printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n", ansi_highlight_red(true), ansi_highlight_red(false), - arg_scope == UNIT_FILE_SYSTEM ? "--system" : "--user"); + arg_scope == UNIT_FILE_SYSTEM ? "" : "--user "); } static void show_unit_help(UnitStatusInfo *i) { -- cgit v1.2.1 From 1a2a4cf250adc7f8caf0e43963db3547e330b929 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 31 May 2013 04:54:55 +0200 Subject: bus: update for kdbus changes --- src/libsystemd-bus/kdbus.h | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/libsystemd-bus/kdbus.h b/src/libsystemd-bus/kdbus.h index 3b7783e1b1..4604eb32b7 100644 --- a/src/libsystemd-bus/kdbus.h +++ b/src/libsystemd-bus/kdbus.h @@ -83,6 +83,7 @@ struct kdbus_vec { struct kdbus_memfd { __u64 size; int fd; + __u32 __pad; }; /* Message Item Types */ @@ -389,6 +390,7 @@ struct kdbus_cmd_match { struct kdbus_cmd_monitor { __u64 id; /* We allow setting the monitor flag of other peers */ unsigned int enable; /* A boolean to enable/disable monitoring */ + __u32 __pad; }; /* FD states: @@ -403,35 +405,35 @@ struct kdbus_cmd_monitor { */ enum { /* kdbus control node commands: require unset state */ - KDBUS_CMD_BUS_MAKE = _IOWR(KDBUS_IOC_MAGIC, 0x00, struct kdbus_cmd_bus_make), - KDBUS_CMD_NS_MAKE = _IOWR(KDBUS_IOC_MAGIC, 0x10, struct kdbus_cmd_ns_make), + KDBUS_CMD_BUS_MAKE = _IOW(KDBUS_IOC_MAGIC, 0x00, struct kdbus_cmd_bus_make), + KDBUS_CMD_NS_MAKE = _IOR(KDBUS_IOC_MAGIC, 0x10, struct kdbus_cmd_ns_make), /* kdbus ep node commands: require unset state */ - KDBUS_CMD_EP_MAKE = _IOWR(KDBUS_IOC_MAGIC, 0x20, struct kdbus_cmd_ep_make), + KDBUS_CMD_EP_MAKE = _IOW(KDBUS_IOC_MAGIC, 0x20, struct kdbus_cmd_ep_make), KDBUS_CMD_HELLO = _IOWR(KDBUS_IOC_MAGIC, 0x30, struct kdbus_cmd_hello), /* kdbus ep node commands: require connected state */ - KDBUS_CMD_MSG_SEND = _IOWR(KDBUS_IOC_MAGIC, 0x40, struct kdbus_msg), - KDBUS_CMD_MSG_RECV = _IOWR(KDBUS_IOC_MAGIC, 0x41, __u64 *), - KDBUS_CMD_MSG_RELEASE = _IOWR(KDBUS_IOC_MAGIC, 0x42, __u64 *), + KDBUS_CMD_MSG_SEND = _IOW(KDBUS_IOC_MAGIC, 0x40, struct kdbus_msg), + KDBUS_CMD_MSG_RECV = _IOR(KDBUS_IOC_MAGIC, 0x41, __u64 *), + KDBUS_CMD_MSG_RELEASE = _IOW(KDBUS_IOC_MAGIC, 0x42, __u64 *), KDBUS_CMD_NAME_ACQUIRE = _IOWR(KDBUS_IOC_MAGIC, 0x50, struct kdbus_cmd_name), - KDBUS_CMD_NAME_RELEASE = _IOWR(KDBUS_IOC_MAGIC, 0x51, struct kdbus_cmd_name), + KDBUS_CMD_NAME_RELEASE = _IOW(KDBUS_IOC_MAGIC, 0x51, struct kdbus_cmd_name), KDBUS_CMD_NAME_LIST = _IOWR(KDBUS_IOC_MAGIC, 0x52, struct kdbus_cmd_names), KDBUS_CMD_NAME_QUERY = _IOWR(KDBUS_IOC_MAGIC, 0x53, struct kdbus_cmd_name_info), - KDBUS_CMD_MATCH_ADD = _IOWR(KDBUS_IOC_MAGIC, 0x60, struct kdbus_cmd_match), - KDBUS_CMD_MATCH_REMOVE = _IOWR(KDBUS_IOC_MAGIC, 0x61, struct kdbus_cmd_match), - KDBUS_CMD_MONITOR = _IOWR(KDBUS_IOC_MAGIC, 0x62, struct kdbus_cmd_monitor), + KDBUS_CMD_MATCH_ADD = _IOW(KDBUS_IOC_MAGIC, 0x60, struct kdbus_cmd_match), + KDBUS_CMD_MATCH_REMOVE = _IOW(KDBUS_IOC_MAGIC, 0x61, struct kdbus_cmd_match), + KDBUS_CMD_MONITOR = _IOW(KDBUS_IOC_MAGIC, 0x62, struct kdbus_cmd_monitor), /* kdbus ep node commands: require ep owner state */ - KDBUS_CMD_EP_POLICY_SET = _IOWR(KDBUS_IOC_MAGIC, 0x70, struct kdbus_cmd_policy), + KDBUS_CMD_EP_POLICY_SET = _IOW(KDBUS_IOC_MAGIC, 0x70, struct kdbus_cmd_policy), /* kdbus memfd commands: */ - KDBUS_CMD_MEMFD_NEW = _IOWR(KDBUS_IOC_MAGIC, 0x80, int *), - KDBUS_CMD_MEMFD_SIZE_GET = _IOWR(KDBUS_IOC_MAGIC, 0x81, __u64 *), - KDBUS_CMD_MEMFD_SIZE_SET = _IOWR(KDBUS_IOC_MAGIC, 0x82, __u64 *), - KDBUS_CMD_MEMFD_SEAL_GET = _IOWR(KDBUS_IOC_MAGIC, 0x83, int *), - KDBUS_CMD_MEMFD_SEAL_SET = _IOWR(KDBUS_IOC_MAGIC, 0x84, int), + KDBUS_CMD_MEMFD_NEW = _IOR(KDBUS_IOC_MAGIC, 0x80, int *), + KDBUS_CMD_MEMFD_SIZE_GET = _IOR(KDBUS_IOC_MAGIC, 0x81, __u64 *), + KDBUS_CMD_MEMFD_SIZE_SET = _IOW(KDBUS_IOC_MAGIC, 0x82, __u64 *), + KDBUS_CMD_MEMFD_SEAL_GET = _IOR(KDBUS_IOC_MAGIC, 0x83, int *), + KDBUS_CMD_MEMFD_SEAL_SET = _IO(KDBUS_IOC_MAGIC, 0x84), }; #endif -- cgit v1.2.1 From fe1abefcd3bf1718dde3b5b835db56142c9f7082 Mon Sep 17 00:00:00 2001 From: Daniel Albers Date: Fri, 31 May 2013 14:39:34 +0200 Subject: journal: take KeepFree into account when reporting maximum size When reporting the maximum journal size add a hint if it's limited by KeepFree. --- src/journal/journald-server.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index da5b725863..0bf557c809 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -780,6 +780,9 @@ static int system_journal_open(Server *s) { char *fn; sd_id128_t machine; char ids[33]; + uint64_t avail; + + avail = available_space(s); r = sd_id128_get_machine(&machine); if (r < 0) @@ -821,6 +824,10 @@ static int system_journal_open(Server *s) { server_driver_message(s, SD_ID128_NULL, "Allowing system journal files to grow to %s.", format_bytes(fb, sizeof(fb), s->system_metrics.max_use)); + if (s->system_metrics.max_use > avail) + server_driver_message(s, SD_ID128_NULL, "Journal size currently limited to %s due to SystemKeepFree.", + format_bytes(fb, sizeof(fb), avail)); + } else if (r < 0) { if (r != -ENOENT && r != -EROFS) @@ -874,6 +881,10 @@ static int system_journal_open(Server *s) { server_fix_perms(s, s->runtime_journal, 0); server_driver_message(s, SD_ID128_NULL, "Allowing runtime journal files to grow to %s.", format_bytes(fb, sizeof(fb), s->runtime_metrics.max_use)); + + if (s->system_metrics.max_use > avail) + server_driver_message(s, SD_ID128_NULL, "Journal size currently limited to %s due to RuntimeKeepFree.", + format_bytes(fb, sizeof(fb), avail)); } } -- cgit v1.2.1 From 6351163bf3e519cc07adb2732d12450741f5a0d3 Mon Sep 17 00:00:00 2001 From: Umut Tezduyar Date: Sun, 2 Jun 2013 10:54:44 +0200 Subject: build-sys: option to disable tmpfiles --- Makefile.am | 52 +++++++++++++++++++++++++++++++++++++--------------- configure.ac | 9 +++++++++ 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/Makefile.am b/Makefile.am index e63563f87a..54c4582abd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -280,9 +280,13 @@ rootbin_PROGRAMS = \ systemd-notify \ systemd-ask-password \ systemd-tty-ask-password-agent \ - systemd-tmpfiles \ systemd-machine-id-setup +if ENABLE_TMPFILES +rootbin_PROGRAMS += \ + systemd-tmpfiles +endif + bin_PROGRAMS = \ systemd-cgls \ systemd-cgtop \ @@ -336,18 +340,20 @@ dist_bashcompletion_DATA = \ shell-completion/bash/systemd-analyze \ shell-completion/bash/udevadm +if ENABLE_TMPFILES dist_tmpfiles_DATA = \ tmpfiles.d/systemd.conf \ tmpfiles.d/tmp.conf \ tmpfiles.d/x11.conf -dist_sysctl_DATA = \ - sysctl.d/50-default.conf - if HAVE_SYSV_COMPAT dist_tmpfiles_DATA += \ tmpfiles.d/legacy.conf endif +endif + +dist_sysctl_DATA = \ + sysctl.d/50-default.conf dist_systemunit_DATA = \ units/graphical.target \ @@ -400,7 +406,6 @@ dist_systemunit_DATA = \ units/sound.target \ units/bluetooth.target \ units/smartcard.target \ - units/systemd-tmpfiles-clean.timer \ units/quotaon.service \ units/systemd-ask-password-wall.path \ units/systemd-ask-password-console.path \ @@ -419,9 +424,6 @@ nodist_systemunit_DATA = \ units/systemd-remount-fs.service \ units/systemd-update-utmp.service \ units/systemd-update-utmp-runlevel.service \ - units/systemd-tmpfiles-setup-dev.service \ - units/systemd-tmpfiles-setup.service \ - units/systemd-tmpfiles-clean.service \ units/systemd-ask-password-wall.service \ units/systemd-ask-password-console.service \ units/systemd-sysctl.service \ @@ -465,9 +467,6 @@ EXTRA_DIST += \ units/systemd-remount-fs.service.in \ units/systemd-update-utmp.service.in \ units/systemd-update-utmp-runlevel.service.in \ - units/systemd-tmpfiles-setup-dev.service.in \ - units/systemd-tmpfiles-setup.service.in \ - units/systemd-tmpfiles-clean.service.in \ units/systemd-ask-password-wall.service.in \ units/systemd-ask-password-console.service.in \ units/systemd-sysctl.service.in \ @@ -500,6 +499,19 @@ CLEANFILES += \ units/console-getty.service.m4 \ units/rescue.service.m4 +if ENABLE_TMPFILES +dist_systemunit_DATA += \ + units/systemd-tmpfiles-clean.timer +nodist_systemunit_DATA += \ + units/systemd-tmpfiles-setup-dev.service \ + units/systemd-tmpfiles-setup.service \ + units/systemd-tmpfiles-clean.service +EXTRA_DIST += \ + units/systemd-tmpfiles-setup-dev.service.in \ + units/systemd-tmpfiles-setup.service.in \ + units/systemd-tmpfiles-clean.service.in +endif + if HAVE_SYSV_COMPAT nodist_systemunit_DATA += \ units/rc-local.service \ @@ -1437,6 +1449,7 @@ EXTRA_DIST += \ units/systemd-modules-load.service.in # ------------------------------------------------------------------------------ +if ENABLE_TMPFILES systemd_tmpfiles_SOURCES = \ src/tmpfiles/tmpfiles.c @@ -1444,6 +1457,7 @@ systemd_tmpfiles_LDADD = \ libsystemd-label.la \ libsystemd-shared.la \ libsystemd-capability.la +endif # ------------------------------------------------------------------------------ systemd_machine_id_setup_SOURCES = \ @@ -4115,12 +4129,16 @@ SYSINIT_TARGET_WANTS += \ sys-kernel-config.mount \ sys-kernel-debug.mount \ sys-fs-fuse-connections.mount \ - systemd-tmpfiles-setup-dev.service \ - systemd-tmpfiles-setup.service \ systemd-sysctl.service \ systemd-ask-password-console.path + +if ENABLE_TMPFILES +SYSINIT_TARGET_WANTS += \ + systemd-tmpfiles-setup-dev.service \ + systemd-tmpfiles-setup.service TIMERS_TARGET_WANTS += \ systemd-tmpfiles-clean.timer +endif if HAVE_SYSV_COMPAT SYSTEM_UNIT_ALIASES += \ @@ -4164,8 +4182,6 @@ INSTALL_DIRS += \ endif INSTALL_DIRS += \ - $(tmpfilesdir) \ - $(sysconfdir)/tmpfiles.d \ $(prefix)/lib/modules-load.d \ $(sysconfdir)/modules-load.d \ $(prefix)/lib/sysctl.d \ @@ -4185,6 +4201,12 @@ INSTALL_DIRS += \ $(dbussessionservicedir) \ $(sysconfdir)/xdg/systemd +if ENABLE_TMPFILES +INSTALL_DIRS += \ + $(tmpfilesdir) \ + $(sysconfdir)/tmpfiles.d +endif + install-exec-hook: $(INSTALL_EXEC_HOOKS) uninstall-hook: $(UNINSTALL_DATA_HOOKS) $(UNINSTALL_EXEC_HOOKS) diff --git a/configure.ac b/configure.ac index c24b4a8187..d266601aeb 100644 --- a/configure.ac +++ b/configure.ac @@ -616,6 +616,14 @@ if test "x$enable_quotacheck" != "xno"; then fi AM_CONDITIONAL(ENABLE_QUOTACHECK, [test "$have_quotacheck" = "yes"]) +# ------------------------------------------------------------------------------ +have_tmpfiles=no +AC_ARG_ENABLE(tmpfiles, AS_HELP_STRING([--disable-tmpfiles], [disable tmpfiles support])) +if test "x$enable_tmpfiles" != "xno"; then + have_tmpfiles=yes +fi +AM_CONDITIONAL(ENABLE_TMPFILES, [test "$have_tmpfiles" = "yes"]) + # ------------------------------------------------------------------------------ have_randomseed=no AC_ARG_ENABLE(randomseed, AS_HELP_STRING([--disable-randomseed], [disable randomseed tools])) @@ -954,6 +962,7 @@ AC_MSG_RESULT([ readahead: ${have_readahead} bootchart: ${have_bootchart} quotacheck: ${have_quotacheck} + tmpfiles: ${have_tmpfiles} randomseed: ${have_randomseed} logind: ${have_logind} hostnamed: ${have_hostnamed} -- cgit v1.2.1 From 518d10e98508ec8181e864924484a2ca994c5d43 Mon Sep 17 00:00:00 2001 From: Umut Tezduyar Date: Wed, 8 May 2013 14:29:12 +0200 Subject: analyze: show generators on plot --- src/analyze/systemd-analyze.c | 42 ++++++++++++++++++++++++++++++++++++------ src/core/dbus-manager.c | 8 ++++++++ src/core/manager.c | 2 ++ src/core/manager.h | 2 ++ 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/src/analyze/systemd-analyze.c b/src/analyze/systemd-analyze.c index bb86ec7da8..df3d307240 100644 --- a/src/analyze/systemd-analyze.c +++ b/src/analyze/systemd-analyze.c @@ -78,6 +78,8 @@ struct boot_times { usec_t initrd_time; usec_t userspace_time; usec_t finish_time; + usec_t generators_start_time; + usec_t generators_finish_time; }; struct unit_times { char *name; @@ -303,7 +305,17 @@ static int acquire_boot_times(DBusConnection *bus, struct boot_times **bt) { "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "FinishTimestampMonotonic", - ×.finish_time) < 0) + ×.finish_time) < 0 || + bus_get_uint64_property(bus, + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "GeneratorsStartTimestampMonotonic", + ×.generators_start_time) < 0 || + bus_get_uint64_property(bus, + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "GeneratorsFinishTimestampMonotonic", + ×.generators_finish_time) < 0) return -EIO; if (times.finish_time <= 0) { @@ -459,7 +471,8 @@ static int analyze_plot(DBusConnection *bus) { svg("\n\n", - 80.0 + width, 150.0 + (m * SCALE_Y)); + 80.0 + width, 150.0 + (m * SCALE_Y) + + 4 * SCALE_Y /* legend */); /* write some basic info as a comment, including some help */ svg("\n" @@ -480,6 +493,7 @@ static int analyze_plot(DBusConnection *bus) { " rect.firmware { fill: rgb(150,150,150); fill-opacity: 0.7; }\n" " rect.loader { fill: rgb(150,150,150); fill-opacity: 0.7; }\n" " rect.userspace { fill: rgb(150,150,150); fill-opacity: 0.7; }\n" + " rect.generators { fill: rgb(102,204,255); fill-opacity: 0.7; }\n" " rect.box { fill: rgb(240,240,240); stroke: rgb(192,192,192); }\n" " line { stroke: rgb(64,64,64); stroke-width: 1; }\n" "// line.sec1 { }\n" @@ -495,8 +509,6 @@ static int analyze_plot(DBusConnection *bus) { svg("%s %s (%s %s) %s", isempty(osname) ? "Linux" : osname, name.nodename, name.release, name.version, name.machine); - svg("Legend: Red = Activating; Pink = Active; Dark Pink = Deactivating", - 120.0 + (m *SCALE_Y)); svg("\n", 20.0 + (SCALE_X * boot->firmware_time)); svg_graph_box(m, -boot->firmware_time, boot->finish_time); @@ -521,8 +533,9 @@ static int analyze_plot(DBusConnection *bus) { svg_text(true, boot->initrd_time, y, "initrd"); y++; } - svg_bar("userspace", boot->userspace_time, boot->finish_time, y); - svg_text("left", boot->userspace_time, y, "userspace"); + svg_bar("active", boot->userspace_time, boot->finish_time, y); + svg_bar("generators", boot->generators_start_time, boot->generators_finish_time, y); + svg_text("left", boot->userspace_time, y, "systemd"); y++; for (u = times; u < times + n; u++) { @@ -544,6 +557,23 @@ static int analyze_plot(DBusConnection *bus) { svg_text(b, u->ixt, y, "%s", u->name); y++; } + + /* Legend */ + y++; + svg_bar("activating", 0, 300000, y); + svg_text("right", 400000, y, "Activating"); + y++; + svg_bar("active", 0, 300000, y); + svg_text("right", 400000, y, "Active"); + y++; + svg_bar("deactivating", 0, 300000, y); + svg_text("right", 400000, y, "Deactivating"); + y++; + svg_bar("generators", 0, 300000, y); + svg_text("right", 400000, y, "Generators"); + y++; + + svg("\n\n"); svg(""); diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index f3ddfc9761..988c06aa44 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -282,6 +282,10 @@ " \n" \ " \n" \ " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ @@ -587,6 +591,10 @@ static const BusProperty bus_manager_properties[] = { { "UserspaceTimestampMonotonic", bus_property_append_uint64, "t", offsetof(Manager, userspace_timestamp.monotonic) }, { "FinishTimestamp", bus_property_append_uint64, "t", offsetof(Manager, finish_timestamp.realtime) }, { "FinishTimestampMonotonic", bus_property_append_uint64, "t", offsetof(Manager, finish_timestamp.monotonic) }, + { "GeneratorsStartTimestamp", bus_property_append_uint64, "t", offsetof(Manager, generators_start_timestamp.realtime) }, + { "GeneratorsStartTimestampMonotonic", bus_property_append_uint64, "t", offsetof(Manager, generators_start_timestamp.monotonic) }, + { "GeneratorsFinishTimestamp", bus_property_append_uint64, "t", offsetof(Manager, generators_finish_timestamp.realtime) }, + { "GeneratorsFinishTimestampMonotonic", bus_property_append_uint64, "t", offsetof(Manager, generators_finish_timestamp.monotonic) }, { "LogLevel", bus_manager_append_log_level, "s", 0, false, bus_manager_set_log_level }, { "LogTarget", bus_manager_append_log_target, "s", 0, false, bus_manager_set_log_target }, { "NNames", bus_manager_append_n_names, "u", 0 }, diff --git a/src/core/manager.c b/src/core/manager.c index 6b0f567663..73f4c102e8 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -826,7 +826,9 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) { assert(m); + dual_timestamp_get(&m->generators_start_timestamp); manager_run_generators(m); + dual_timestamp_get(&m->generators_finish_timestamp); r = lookup_paths_init( &m->lookup_paths, m->running_as, true, diff --git a/src/core/manager.h b/src/core/manager.h index bf833540ae..5d777e6ed3 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -150,6 +150,8 @@ struct Manager { dual_timestamp initrd_timestamp; dual_timestamp userspace_timestamp; dual_timestamp finish_timestamp; + dual_timestamp generators_start_timestamp; + dual_timestamp generators_finish_timestamp; char *generator_unit_path; char *generator_unit_path_early; -- cgit v1.2.1 From d9acfb71dbfb6e916b9752593158698b8021b28c Mon Sep 17 00:00:00 2001 From: Thomas Hindoe Paaboel Andersen Date: Wed, 15 May 2013 21:18:26 +0200 Subject: analyze: show unit file loading on plot This will add another color to the legend called "Loading unit files" Like the generators it will mark a part of the systemd bar indicating the time spent while loading unit files. --- src/analyze/systemd-analyze.c | 21 +++++++++++++++++++-- src/core/dbus-manager.c | 8 ++++++++ src/core/manager.c | 2 ++ src/core/manager.h | 2 ++ 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/analyze/systemd-analyze.c b/src/analyze/systemd-analyze.c index df3d307240..6d97256c73 100644 --- a/src/analyze/systemd-analyze.c +++ b/src/analyze/systemd-analyze.c @@ -80,6 +80,8 @@ struct boot_times { usec_t finish_time; usec_t generators_start_time; usec_t generators_finish_time; + usec_t unitsload_start_time; + usec_t unitsload_finish_time; }; struct unit_times { char *name; @@ -315,7 +317,17 @@ static int acquire_boot_times(DBusConnection *bus, struct boot_times **bt) { "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "GeneratorsFinishTimestampMonotonic", - ×.generators_finish_time) < 0) + ×.generators_finish_time) < 0 || + bus_get_uint64_property(bus, + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "UnitsLoadStartTimestampMonotonic", + ×.unitsload_start_time) < 0 || + bus_get_uint64_property(bus, + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "UnitsLoadFinishTimestampMonotonic", + ×.unitsload_finish_time) < 0) return -EIO; if (times.finish_time <= 0) { @@ -472,7 +484,7 @@ static int analyze_plot(DBusConnection *bus) { svg("\n\n", 80.0 + width, 150.0 + (m * SCALE_Y) + - 4 * SCALE_Y /* legend */); + 5 * SCALE_Y /* legend */); /* write some basic info as a comment, including some help */ svg("\n" @@ -494,6 +506,7 @@ static int analyze_plot(DBusConnection *bus) { " rect.loader { fill: rgb(150,150,150); fill-opacity: 0.7; }\n" " rect.userspace { fill: rgb(150,150,150); fill-opacity: 0.7; }\n" " rect.generators { fill: rgb(102,204,255); fill-opacity: 0.7; }\n" + " rect.unitsload { fill: rgb( 82,184,255); fill-opacity: 0.7; }\n" " rect.box { fill: rgb(240,240,240); stroke: rgb(192,192,192); }\n" " line { stroke: rgb(64,64,64); stroke-width: 1; }\n" "// line.sec1 { }\n" @@ -535,6 +548,7 @@ static int analyze_plot(DBusConnection *bus) { } svg_bar("active", boot->userspace_time, boot->finish_time, y); svg_bar("generators", boot->generators_start_time, boot->generators_finish_time, y); + svg_bar("unitsload", boot->unitsload_start_time, boot->unitsload_finish_time, y); svg_text("left", boot->userspace_time, y, "systemd"); y++; @@ -572,6 +586,9 @@ static int analyze_plot(DBusConnection *bus) { svg_bar("generators", 0, 300000, y); svg_text("right", 400000, y, "Generators"); y++; + svg_bar("unitsload", 0, 300000, y); + svg_text("right", 400000, y, "Loading unit files"); + y++; svg("\n\n"); diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 988c06aa44..25d38cc491 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -286,6 +286,10 @@ " \n" \ " \n" \ " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ @@ -595,6 +599,10 @@ static const BusProperty bus_manager_properties[] = { { "GeneratorsStartTimestampMonotonic", bus_property_append_uint64, "t", offsetof(Manager, generators_start_timestamp.monotonic) }, { "GeneratorsFinishTimestamp", bus_property_append_uint64, "t", offsetof(Manager, generators_finish_timestamp.realtime) }, { "GeneratorsFinishTimestampMonotonic", bus_property_append_uint64, "t", offsetof(Manager, generators_finish_timestamp.monotonic) }, + { "UnitsLoadStartTimestamp", bus_property_append_uint64, "t", offsetof(Manager, unitsload_start_timestamp.realtime) }, + { "UnitsLoadStartTimestampMonotonic", bus_property_append_uint64, "t", offsetof(Manager, unitsload_start_timestamp.monotonic) }, + { "UnitsLoadFinishTimestamp", bus_property_append_uint64, "t", offsetof(Manager, unitsload_finish_timestamp.realtime) }, + { "UnitsLoadFinishTimestampMonotonic", bus_property_append_uint64, "t", offsetof(Manager, unitsload_finish_timestamp.monotonic) }, { "LogLevel", bus_manager_append_log_level, "s", 0, false, bus_manager_set_log_level }, { "LogTarget", bus_manager_append_log_target, "s", 0, false, bus_manager_set_log_target }, { "NNames", bus_manager_append_n_names, "u", 0 }, diff --git a/src/core/manager.c b/src/core/manager.c index 73f4c102e8..f16621ac2b 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -847,7 +847,9 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) { m->n_reloading ++; /* First, enumerate what we can from all config files */ + dual_timestamp_get(&m->unitsload_start_timestamp); r = manager_enumerate(m); + dual_timestamp_get(&m->unitsload_finish_timestamp); /* Second, deserialize if there is something to deserialize */ if (serialization) { diff --git a/src/core/manager.h b/src/core/manager.h index 5d777e6ed3..dcc4ebed92 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -152,6 +152,8 @@ struct Manager { dual_timestamp finish_timestamp; dual_timestamp generators_start_timestamp; dual_timestamp generators_finish_timestamp; + dual_timestamp unitsload_start_timestamp; + dual_timestamp unitsload_finish_timestamp; char *generator_unit_path; char *generator_unit_path_early; -- cgit v1.2.1 From 2b7d6965be9a06dadfc971d0d37fc9b2ef0cad7a Mon Sep 17 00:00:00 2001 From: Thomas Hindoe Paaboel Andersen Date: Wed, 15 May 2013 21:52:07 +0200 Subject: analyze: fix font size on plot The font-size was missing a unit so they were ignored. This patch sets the unit to 'px' and adjusts the sizes a bit as the text got very small. --- src/analyze/systemd-analyze.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/analyze/systemd-analyze.c b/src/analyze/systemd-analyze.c index 6d97256c73..fe1abdc6bd 100644 --- a/src/analyze/systemd-analyze.c +++ b/src/analyze/systemd-analyze.c @@ -512,10 +512,10 @@ static int analyze_plot(DBusConnection *bus) { "// line.sec1 { }\n" " line.sec5 { stroke-width: 2; }\n" " line.sec01 { stroke: rgb(224,224,224); stroke-width: 1; }\n" - " text { font-family: Verdana, Helvetica; font-size: 10; }\n" - " text.left { font-family: Verdana, Helvetica; font-size: 10; text-anchor: start; }\n" - " text.right { font-family: Verdana, Helvetica; font-size: 10; text-anchor: end; }\n" - " text.sec { font-size: 8; }\n" + " text { font-family: Verdana, Helvetica; font-size: 14px; }\n" + " text.left { font-family: Verdana, Helvetica; font-size: 14px; text-anchor: start; }\n" + " text.right { font-family: Verdana, Helvetica; font-size: 14px; text-anchor: end; }\n" + " text.sec { font-size: 10px; }\n" " ]]>\n \n\n\n"); svg("%s", pretty_times); -- cgit v1.2.1 From 5b46fc6c609cab439eb447c7528d5d7096aa3d2f Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Mon, 3 Jun 2013 15:54:58 +0200 Subject: Makefile.am: merge conditionals Merge all ENABLE_TMPFILES conditionals into one, and merge two ENABLE_EFI conditionals. Also make sure the .in files are always distributed. --- Makefile.am | 117 ++++++++++++++++++++++++++++-------------------------------- 1 file changed, 54 insertions(+), 63 deletions(-) diff --git a/Makefile.am b/Makefile.am index 54c4582abd..70da1e4a2c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -282,11 +282,6 @@ rootbin_PROGRAMS = \ systemd-tty-ask-password-agent \ systemd-machine-id-setup -if ENABLE_TMPFILES -rootbin_PROGRAMS += \ - systemd-tmpfiles -endif - bin_PROGRAMS = \ systemd-cgls \ systemd-cgtop \ @@ -340,18 +335,6 @@ dist_bashcompletion_DATA = \ shell-completion/bash/systemd-analyze \ shell-completion/bash/udevadm -if ENABLE_TMPFILES -dist_tmpfiles_DATA = \ - tmpfiles.d/systemd.conf \ - tmpfiles.d/tmp.conf \ - tmpfiles.d/x11.conf - -if HAVE_SYSV_COMPAT -dist_tmpfiles_DATA += \ - tmpfiles.d/legacy.conf -endif -endif - dist_sysctl_DATA = \ sysctl.d/50-default.conf @@ -499,19 +482,6 @@ CLEANFILES += \ units/console-getty.service.m4 \ units/rescue.service.m4 -if ENABLE_TMPFILES -dist_systemunit_DATA += \ - units/systemd-tmpfiles-clean.timer -nodist_systemunit_DATA += \ - units/systemd-tmpfiles-setup-dev.service \ - units/systemd-tmpfiles-setup.service \ - units/systemd-tmpfiles-clean.service -EXTRA_DIST += \ - units/systemd-tmpfiles-setup-dev.service.in \ - units/systemd-tmpfiles-setup.service.in \ - units/systemd-tmpfiles-clean.service.in -endif - if HAVE_SYSV_COMPAT nodist_systemunit_DATA += \ units/rc-local.service \ @@ -1457,8 +1427,45 @@ systemd_tmpfiles_LDADD = \ libsystemd-label.la \ libsystemd-shared.la \ libsystemd-capability.la + +rootbin_PROGRAMS += \ + systemd-tmpfiles + +dist_systemunit_DATA += \ + units/systemd-tmpfiles-clean.timer + +nodist_systemunit_DATA += \ + units/systemd-tmpfiles-setup-dev.service \ + units/systemd-tmpfiles-setup.service \ + units/systemd-tmpfiles-clean.service + +dist_tmpfiles_DATA = \ + tmpfiles.d/systemd.conf \ + tmpfiles.d/tmp.conf \ + tmpfiles.d/x11.conf + +if HAVE_SYSV_COMPAT +dist_tmpfiles_DATA += \ + tmpfiles.d/legacy.conf endif +SYSINIT_TARGET_WANTS += \ + systemd-tmpfiles-setup-dev.service \ + systemd-tmpfiles-setup.service + +TIMERS_TARGET_WANTS += \ + systemd-tmpfiles-clean.timer + +INSTALL_DIRS += \ + $(tmpfilesdir) \ + $(sysconfdir)/tmpfiles.d +endif + +EXTRA_DIST += \ + units/systemd-tmpfiles-setup-dev.service.in \ + units/systemd-tmpfiles-setup.service.in \ + units/systemd-tmpfiles-clean.service.in + # ------------------------------------------------------------------------------ systemd_machine_id_setup_SOURCES = \ src/machine-id-setup/machine-id-setup-main.c \ @@ -1557,8 +1564,8 @@ systemd_system_update_generator_LDADD = \ libsystemd-label.la \ libsystemd-shared.la -# ------------------------------------------------------------------------------ if ENABLE_EFI +# ------------------------------------------------------------------------------ systemgenerator_PROGRAMS += \ systemd-efi-boot-generator @@ -1568,6 +1575,22 @@ systemd_efi_boot_generator_SOURCES = \ systemd_efi_boot_generator_LDADD = \ libsystemd-label.la \ libsystemd-shared.la + +# ------------------------------------------------------------------------------ +bootctl_SOURCES = \ + src/boot/boot.h \ + src/boot/boot-loader.h \ + src/boot/bootctl.c \ + src/boot/boot-loader.c \ + src/boot/boot-efi.c + +bootctl_LDADD = \ + libsystemd-shared.la \ + libsystemd-id128.la \ + libsystemd-daemon.la + +bin_PROGRAMS += \ + bootctl endif # ------------------------------------------------------------------------------ @@ -3471,24 +3494,6 @@ polkitpolicy_in_files += \ EXTRA_DIST += \ units/systemd-timedated.service.in -# ------------------------------------------------------------------------------ -if ENABLE_EFI -bootctl_SOURCES = \ - src/boot/boot.h \ - src/boot/boot-loader.h \ - src/boot/bootctl.c \ - src/boot/boot-loader.c \ - src/boot/boot-efi.c - -bootctl_LDADD = \ - libsystemd-shared.la \ - libsystemd-id128.la \ - libsystemd-daemon.la - -bin_PROGRAMS += \ - bootctl -endif - # ------------------------------------------------------------------------------ if HAVE_MYHOSTNAME libnss_myhostname_la_SOURCES = \ @@ -4132,14 +4137,6 @@ SYSINIT_TARGET_WANTS += \ systemd-sysctl.service \ systemd-ask-password-console.path -if ENABLE_TMPFILES -SYSINIT_TARGET_WANTS += \ - systemd-tmpfiles-setup-dev.service \ - systemd-tmpfiles-setup.service -TIMERS_TARGET_WANTS += \ - systemd-tmpfiles-clean.timer -endif - if HAVE_SYSV_COMPAT SYSTEM_UNIT_ALIASES += \ poweroff.target runlevel0.target \ @@ -4201,12 +4198,6 @@ INSTALL_DIRS += \ $(dbussessionservicedir) \ $(sysconfdir)/xdg/systemd -if ENABLE_TMPFILES -INSTALL_DIRS += \ - $(tmpfilesdir) \ - $(sysconfdir)/tmpfiles.d -endif - install-exec-hook: $(INSTALL_EXEC_HOOKS) uninstall-hook: $(UNINSTALL_DATA_HOOKS) $(UNINSTALL_EXEC_HOOKS) -- cgit v1.2.1 From 02b9e969a6f512d2312e7028ce5c48c84ad87d06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 3 Jun 2013 13:55:13 -0400 Subject: systemctl,core: allow nuking of symlinks to removed units Before, one the unit file was deleted, install_context_for_removal() would refuse to look for symlinks. But we can remove dangling symlinks anyway. In principle, package installation/deinstallation scripts should do that before the unit is uninstalled, but they don't always do. Also, a user might have added additional symlinks manually. https://bugs.freedesktop.org/show_bug.cgi?id=62395 --- src/shared/install.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/shared/install.c b/src/shared/install.c index 954dcb1e71..d2dd276803 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -1413,7 +1413,9 @@ static int install_context_mark_for_removal( assert_se(hashmap_move_one(c->have_installed, c->will_install, i->name) == 0); q = unit_file_search(c, i, paths, root_dir, false); - if (q < 0) { + if (q == -ENOENT) { + /* do nothing */ + } else if (q < 0) { if (r >= 0) r = q; -- cgit v1.2.1 From 061b2c43652570c067ca93391cec9940a24d474f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 3 Jun 2013 19:44:44 +0900 Subject: test: determine number of transactions per second rather than time per transaction This way the measurements are not skewed by twoo short total measurement times, and results become stabler. --- src/libsystemd-bus/test-bus-kernel-benchmark.c | 37 ++++++++++++++++++-------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/src/libsystemd-bus/test-bus-kernel-benchmark.c b/src/libsystemd-bus/test-bus-kernel-benchmark.c index 0cf685e6de..01074dd4f3 100644 --- a/src/libsystemd-bus/test-bus-kernel-benchmark.c +++ b/src/libsystemd-bus/test-bus-kernel-benchmark.c @@ -24,6 +24,7 @@ #include "util.h" #include "log.h" +#include "time-util.h" #include "sd-bus.h" #include "bus-message.h" @@ -31,9 +32,10 @@ #include "bus-kernel.h" #include "bus-internal.h" -#define N_TRIES 10000 #define MAX_SIZE (1*1024*1024) +static usec_t arg_loop_usec = 10 * USEC_PER_SEC; + static void server(sd_bus *b, size_t *result) { int r; @@ -107,8 +109,8 @@ static void client(const char *address) { rsize = MAX_SIZE; for (;;) { - usec_t copy, memfd, t; - unsigned i; + usec_t t; + unsigned n_copying, n_memfd; csize = (lsize + rsize) / 2; @@ -122,24 +124,32 @@ static void client(const char *address) { log_info("copying..."); b->use_memfd = 0; + t = now(CLOCK_MONOTONIC); - for (i = 0; i < N_TRIES; i++) + for (n_copying = 0;; n_copying++) { transaction(b, csize); - copy = (now(CLOCK_MONOTONIC) - t); - log_info("%llu usec per copy transaction", (unsigned long long) (copy / N_TRIES)); + if (now(CLOCK_MONOTONIC) >= t + arg_loop_usec) + break; + } + + log_info("%u copy transactions per second", (unsigned) ((n_copying * USEC_PER_SEC) / arg_loop_usec)); log_info("sending memfd..."); b->use_memfd = -1; + t = now(CLOCK_MONOTONIC); - for (i = 0; i < N_TRIES; i++) + for (n_memfd = 0;; n_memfd++) { transaction(b, csize); - memfd = (now(CLOCK_MONOTONIC) - t); - log_info("%llu usec per memfd transaction", (unsigned long long) (memfd / N_TRIES)); + if (now(CLOCK_MONOTONIC) >= t + arg_loop_usec) + break; + } - if (copy == memfd) + log_info("%u memfd transactions per second", (unsigned) ((n_memfd * USEC_PER_SEC) / arg_loop_usec)); + + if (n_copying == n_memfd) break; - if (copy < memfd) + if (n_copying > n_memfd) lsize = csize; else rsize = csize; @@ -163,6 +173,11 @@ int main(int argc, char *argv[]) { log_set_max_level(LOG_DEBUG); + if (argc > 1) + assert_se(parse_sec(argv[1], &arg_loop_usec) >= 0); + + assert_se(arg_loop_usec > 0); + bus_ref = bus_kernel_create("deine-mutter", &bus_name); if (bus_ref == -ENOENT) exit(EXIT_TEST_SKIP); -- cgit v1.2.1 From 59967d30e53336755ae1cfdf7cb1a9424aa8c158 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 4 Jun 2013 12:00:50 +0200 Subject: bus-benchmark: lower loop time to 100ms by default, to ensure "make check" finishes more quickly To get useful results you should however specify a much longer time on the command line. --- src/libsystemd-bus/test-bus-kernel-benchmark.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsystemd-bus/test-bus-kernel-benchmark.c b/src/libsystemd-bus/test-bus-kernel-benchmark.c index 01074dd4f3..e2a872c6c5 100644 --- a/src/libsystemd-bus/test-bus-kernel-benchmark.c +++ b/src/libsystemd-bus/test-bus-kernel-benchmark.c @@ -34,7 +34,7 @@ #define MAX_SIZE (1*1024*1024) -static usec_t arg_loop_usec = 10 * USEC_PER_SEC; +static usec_t arg_loop_usec = 100 * USEC_PER_MSEC; static void server(sd_bus *b, size_t *result) { int r; -- cgit v1.2.1 From 7c1b8f043ed3d23663549dd6084c5a4de51b8e28 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Mon, 3 Jun 2013 14:28:29 +0200 Subject: units: cleanup agetty command line * baud rate is optional and unnecessary for virtual terminals * term type is optional (default is 'linux' for virtual terminals and 'vt102' for serial lines) * long options are more user-friendly ... all this is supported since util-linux v2.20 (Aug 2011). --- units/getty@.service.m4 | 2 +- units/serial-getty@.service.m4 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/units/getty@.service.m4 b/units/getty@.service.m4 index 083eb97059..f32ca99ea9 100644 --- a/units/getty@.service.m4 +++ b/units/getty@.service.m4 @@ -27,7 +27,7 @@ ConditionPathExists=/dev/tty0 [Service] # the VT is cleared by TTYVTDisallocate -ExecStart=-/sbin/agetty --noclear %I 38400 linux +ExecStart=-/sbin/agetty --noclear %I Type=idle Restart=always RestartSec=0 diff --git a/units/serial-getty@.service.m4 b/units/serial-getty@.service.m4 index 60d7737b74..5e16963e92 100644 --- a/units/serial-getty@.service.m4 +++ b/units/serial-getty@.service.m4 @@ -22,7 +22,7 @@ Before=getty.target IgnoreOnIsolate=yes [Service] -ExecStart=-/sbin/agetty -s %I 115200,38400,9600 vt102 +ExecStart=-/sbin/agetty --keep-baud %I 115200,38400,9600 Type=idle Restart=always RestartSec=0 -- cgit v1.2.1 From 5ec76417764e19486261fb8e38e8e71b28185b37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 3 Jun 2013 18:28:12 -0400 Subject: systemctl: limit logs in status to current boot Also reworded a few debug messages for brevity, and added a log statement which prints out the filter at debug level: Journal filter: (((UNIT=sys-module-configfs.device AND _PID=1) OR (COREDUMP_UNIT=sys-module-configfs.device AND MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1) OR _SYSTEMD_UNIT=sys-module-configfs.device) AND _BOOT_ID=4e3c518ab0474c12ac8de7896fe6b154) --- TODO | 3 --- src/journal/journalctl.c | 25 +------------------------ src/journal/sd-journal.c | 12 ++++++------ src/shared/logs-show.c | 33 +++++++++++++++++++++++++++++++++ src/shared/logs-show.h | 2 ++ 5 files changed, 42 insertions(+), 33 deletions(-) diff --git a/TODO b/TODO index 9ba1de01cb..ecc5748c63 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,4 @@ Bugfixes: -* systemctl status *.path shows all logs, not only the ones since the unit is - active - * check systemd-tmpfiles for selinux context hookup for mknod(), symlink() and similar * swap units that are activated by one name but shown in the kernel under another are semi-broken diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 2e672fa096..eb79c4d853 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -591,33 +591,10 @@ static int add_matches(sd_journal *j, char **args) { } static int add_this_boot(sd_journal *j) { - char match[9+32+1] = "_BOOT_ID="; - sd_id128_t boot_id; - int r; - - assert(j); - if (!arg_this_boot) return 0; - r = sd_id128_get_boot(&boot_id); - if (r < 0) { - log_error("Failed to get boot id: %s", strerror(-r)); - return r; - } - - sd_id128_to_string(boot_id, match + 9); - r = sd_journal_add_match(j, match, strlen(match)); - if (r < 0) { - log_error("Failed to add match: %s", strerror(-r)); - return r; - } - - r = sd_journal_add_conjunction(j); - if (r < 0) - return r; - - return 0; + return add_match_this_boot(j); } static int add_dmesg(sd_journal *j) { diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index 779af62b51..cf60ebcee2 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -1302,7 +1302,7 @@ static int add_file(sd_journal *j, const char *prefix, const char *filename) { return r; } - log_debug("File %s got added.", f->path); + log_debug("File %s added.", f->path); check_network(j, f->fd); @@ -1330,7 +1330,7 @@ static int remove_file(sd_journal *j, const char *prefix, const char *filename) hashmap_remove(j->files, f->path); - log_debug("File %s got removed.", f->path); + log_debug("File %s removed.", f->path); if (j->current_file == f) { j->current_file = NULL; @@ -1397,7 +1397,7 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname) path = NULL; /* avoid freeing in cleanup */ j->current_invalidate_counter ++; - log_debug("Directory %s got added.", m->path); + log_debug("Directory %s added.", m->path); } else if (m->is_root) return 0; @@ -1476,7 +1476,7 @@ static int add_root_directory(sd_journal *j, const char *p) { j->current_invalidate_counter ++; - log_debug("Root directory %s got added.", m->path); + log_debug("Root directory %s added.", m->path); } else if (!m->is_root) return 0; @@ -1537,9 +1537,9 @@ static int remove_directory(sd_journal *j, Directory *d) { hashmap_remove(j->directories_by_path, d->path); if (d->is_root) - log_debug("Root directory %s got removed.", d->path); + log_debug("Root directory %s removed.", d->path); else - log_debug("Directory %s got removed.", d->path); + log_debug("Directory %s removed.", d->path); free(d->path); free(d); diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index 116dc8a36c..79a977c156 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -931,6 +931,33 @@ int add_matches_for_user_unit(sd_journal *j, const char *unit, uid_t uid) { return r; } +int add_match_this_boot(sd_journal *j) { + char match[9+32+1] = "_BOOT_ID="; + sd_id128_t boot_id; + int r; + + assert(j); + + r = sd_id128_get_boot(&boot_id); + if (r < 0) { + log_error("Failed to get boot id: %s", strerror(-r)); + return r; + } + + sd_id128_to_string(boot_id, match + 9); + r = sd_journal_add_match(j, match, strlen(match)); + if (r < 0) { + log_error("Failed to add match: %s", strerror(-r)); + return r; + } + + r = sd_journal_add_conjunction(j); + if (r < 0) + return r; + + return 0; +} + int show_journal_by_unit( FILE *f, const char *unit, @@ -957,6 +984,10 @@ int show_journal_by_unit( if (r < 0) return r; + r = add_match_this_boot(j); + if (r < 0) + return r; + if (system) r = add_matches_for_unit(j, unit); else @@ -964,6 +995,8 @@ int show_journal_by_unit( if (r < 0) return r; + log_debug("Journal filter: %s", journal_make_match_string(j)); + r = show_journal(f, j, mode, n_columns, not_before, how_many, flags); if (r < 0) return r; diff --git a/src/shared/logs-show.h b/src/shared/logs-show.h index b0f93a661a..c9a9ad3e91 100644 --- a/src/shared/logs-show.h +++ b/src/shared/logs-show.h @@ -37,6 +37,8 @@ int output_journal( unsigned n_columns, OutputFlags flags); +int add_match_this_boot(sd_journal *j); + int add_matches_for_unit( sd_journal *j, const char *unit); -- cgit v1.2.1 From 3a256a12ad2f5b635d852d2b7068b1de30f8cf59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 4 Jun 2013 10:57:47 -0400 Subject: systemctl: add missing verbs to help --- src/systemctl/systemctl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 6a4c2d6900..58a6fd4044 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -4645,6 +4645,7 @@ static int systemctl_help(void) { " verbose, export, json, json-pretty, json-sse, cat)\n\n" "Unit Commands:\n" " list-units List loaded units\n" + " list-sockets List loaded sockets ordered by address\n" " start [NAME...] Start (activate) one or more units\n" " stop [NAME...] Stop (deactivate) one or more units\n" " reload [NAME...] Reload one or more units\n" @@ -4701,7 +4702,8 @@ static int systemctl_help(void) { "Environment Commands:\n" " show-environment Dump environment\n" " set-environment [NAME=VALUE...] Set one or more environment variables\n" - " unset-environment [NAME...] Unset one or more environment variables\n\n" + " unset-environment [NAME...] Unset one or more environment variables\n" + " set-log-level LEVEL Set logging threshold for systemd\n\n" "Manager Lifecycle Commands:\n" " daemon-reload Reload systemd manager configuration\n" " daemon-reexec Reexecute systemd manager\n\n" -- cgit v1.2.1 From 311754514cd24210f9c72e0af5173d7895690e5f Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 4 Jun 2013 20:55:00 +0200 Subject: bus-benchmark: add performance data output mode - for now, comment out munmap() check to enable memfd passing - print tab-separated values and header - add memcpy() to fill the memfd, to produce real-world results $ ./test-bus-kernel-benchmark SIZE COPY MEMFD 4194304 370 370 2097152 810 810 1048576 2130 2130 524288 4090 4090 262144 7080 7080 131072 11380 11380 65536 17140 17140 98304 13930 13930 114688 12890 12890 122880 12350 12350 126976 12150 12150 129024 12170 12170 130048 12040 12040 130560 12080 12080 130816 12010 12010 130944 12020 12020 131008 12040 12040 131040 12050 12050 131056 12010 12010 131064 12060 12060 131068 12040 12040 131070 11310 11310 131069 11420 11420 Copying/memfd are equally fast at 131068 bytes $ ./test-bus-kernel-benchmark chart SIZE COPY MEMFD 1 35570 23690 2 36470 23680 4 36160 23520 8 36600 22220 16 33900 20830 32 33990 21360 64 33480 21280 128 34050 20910 256 32950 21750 512 34730 21900 1024 33810 22890 2048 36280 23110 4096 30790 21610 8192 29380 21100 16384 26880 19820 32768 22510 17980 65536 17270 15180 131072 11400 11420 262144 7140 8270 524288 4090 5050 1048576 2110 2780 2097152 800 1140 4194304 350 580 --- src/libsystemd-bus/bus-message.c | 5 +- src/libsystemd-bus/test-bus-kernel-benchmark.c | 110 ++++++++++++++++++++----- 2 files changed, 94 insertions(+), 21 deletions(-) diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c index e6bf9db99a..77a875d4eb 100644 --- a/src/libsystemd-bus/bus-message.c +++ b/src/libsystemd-bus/bus-message.c @@ -2358,8 +2358,9 @@ void bus_body_part_unmap(struct bus_body_part *part) { if (!part->data) return; - if (!part->munmap_this) - return; + //FIXME: this is not set in the benchmark + //if (!part->munmap_this) + // return; assert_se(munmap(part->data, part->mapped) == 0); diff --git a/src/libsystemd-bus/test-bus-kernel-benchmark.c b/src/libsystemd-bus/test-bus-kernel-benchmark.c index e2a872c6c5..2ece2a0029 100644 --- a/src/libsystemd-bus/test-bus-kernel-benchmark.c +++ b/src/libsystemd-bus/test-bus-kernel-benchmark.c @@ -32,7 +32,7 @@ #include "bus-kernel.h" #include "bus-internal.h" -#define MAX_SIZE (1*1024*1024) +#define MAX_SIZE (8*1024*1024) static usec_t arg_loop_usec = 100 * USEC_PER_MSEC; @@ -74,21 +74,17 @@ static void server(sd_bus *b, size_t *result) { static void transaction(sd_bus *b, size_t sz) { _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL; - /* size_t psz, i; */ uint8_t *p; assert_se(sd_bus_message_new_method_call(b, ":1.1", "/", "benchmark.server", "Work", &m) >= 0); assert_se(sd_bus_message_append_array_space(m, 'y', sz, (void**) &p) >= 0); - /* Touch every page */ - /* psz = page_size(); */ - /* for (i = 0; i < sz; i += psz) */ - /* p[i] = 'X'; */ + memset(p, 0x80, sz); assert_se(sd_bus_send_with_reply_and_block(b, m, 0, NULL, &reply) >= 0); } -static void client(const char *address) { +static void client_bisect(const char *address) { _cleanup_bus_message_unref_ sd_bus_message *x = NULL; size_t lsize, rsize, csize; sd_bus *b; @@ -108,21 +104,22 @@ static void client(const char *address) { lsize = 1; rsize = MAX_SIZE; + printf("SIZE\tCOPY\tMEMFD\n"); + for (;;) { usec_t t; unsigned n_copying, n_memfd; csize = (lsize + rsize) / 2; - log_info("Trying size=%zu", csize); - if (csize <= lsize) break; if (csize <= 0) break; - log_info("copying..."); + fprintf(stderr, "%zu\t", csize); + b->use_memfd = 0; t = now(CLOCK_MONOTONIC); @@ -131,10 +128,8 @@ static void client(const char *address) { if (now(CLOCK_MONOTONIC) >= t + arg_loop_usec) break; } + printf("%u\t", (unsigned) ((n_copying * USEC_PER_SEC) / arg_loop_usec)); - log_info("%u copy transactions per second", (unsigned) ((n_copying * USEC_PER_SEC) / arg_loop_usec)); - - log_info("sending memfd..."); b->use_memfd = -1; t = now(CLOCK_MONOTONIC); @@ -143,8 +138,7 @@ static void client(const char *address) { if (now(CLOCK_MONOTONIC) >= t + arg_loop_usec) break; } - - log_info("%u memfd transactions per second", (unsigned) ((n_memfd * USEC_PER_SEC) / arg_loop_usec)); + printf("%u\n", (unsigned) ((n_copying * USEC_PER_SEC) / arg_loop_usec)); if (n_copying == n_memfd) break; @@ -155,6 +149,63 @@ static void client(const char *address) { rsize = csize; } + b->use_memfd = 1; + assert_se(sd_bus_message_new_method_call(b, ":1.1", "/", "benchmark.server", "Exit", &x) >= 0); + assert_se(sd_bus_message_append(x, "t", csize) >= 0); + assert_se(sd_bus_send(b, x, NULL) >= 0); + + sd_bus_unref(b); +} + +static void client_chart(const char *address) { + _cleanup_bus_message_unref_ sd_bus_message *x = NULL; + size_t csize; + sd_bus *b; + int r; + + r = sd_bus_new(&b); + assert_se(r >= 0); + + r = sd_bus_set_address(b, address); + assert_se(r >= 0); + + r = sd_bus_start(b); + assert_se(r >= 0); + + assert_se(sd_bus_call_method(b, ":1.1", "/", "benchmark.server", "Ping", NULL, NULL, NULL) >= 0); + + printf("SIZE\tCOPY\tMEMFD\n"); + + for (csize = 1; csize < MAX_SIZE; csize *= 2) { + usec_t t; + unsigned n_copying, n_memfd; + + fprintf(stderr, "%zu\t", csize); + + b->use_memfd = 0; + + t = now(CLOCK_MONOTONIC); + for (n_copying = 0;; n_copying++) { + transaction(b, csize); + if (now(CLOCK_MONOTONIC) >= t + arg_loop_usec) + break; + } + + printf("%u\t", (unsigned) ((n_copying * USEC_PER_SEC) / arg_loop_usec)); + + b->use_memfd = -1; + + t = now(CLOCK_MONOTONIC); + for (n_memfd = 0;; n_memfd++) { + transaction(b, csize); + if (now(CLOCK_MONOTONIC) >= t + arg_loop_usec) + break; + } + + printf("%u\n", (unsigned) ((n_memfd * USEC_PER_SEC) / arg_loop_usec)); + } + + b->use_memfd = 1; assert_se(sd_bus_message_new_method_call(b, ":1.1", "/", "benchmark.server", "Exit", &x) >= 0); assert_se(sd_bus_message_append(x, "t", csize) >= 0); assert_se(sd_bus_send(b, x, NULL) >= 0); @@ -163,6 +214,11 @@ static void client(const char *address) { } int main(int argc, char *argv[]) { + enum { + MODE_BISECT, + MODE_CHART, + } mode = MODE_BISECT; + int i; _cleanup_free_ char *bus_name = NULL, *address = NULL; _cleanup_close_ int bus_ref = -1; cpu_set_t cpuset; @@ -173,8 +229,14 @@ int main(int argc, char *argv[]) { log_set_max_level(LOG_DEBUG); - if (argc > 1) - assert_se(parse_sec(argv[1], &arg_loop_usec) >= 0); + for (i = 1; i < argc; i++) { + if (streq(argv[i], "chart")) { + mode = MODE_CHART; + continue; + } + + assert_se(parse_sec(argv[i], &arg_loop_usec) >= 0); + } assert_se(arg_loop_usec > 0); @@ -210,7 +272,16 @@ int main(int argc, char *argv[]) { close_nointr_nofail(bus_ref); sd_bus_unref(b); - client(address); + switch (mode) { + case MODE_BISECT: + client_bisect(address); + break; + + case MODE_CHART: + client_chart(address); + break; + } + _exit(0); } @@ -220,7 +291,8 @@ int main(int argc, char *argv[]) { server(b, &result); - log_info("Copying/memfd are equally fast at %zu", result); + if (mode == MODE_BISECT) + printf("Copying/memfd are equally fast at %zu bytes\n", result); assert_se(waitpid(pid, NULL, 0) == pid); -- cgit v1.2.1 From bf30e48fe5c6a042f157804631d7d3817c8119fc Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 4 Jun 2013 23:37:57 +0200 Subject: bus: unmap memfd retrieved from the memfd cache --- src/libsystemd-bus/bus-kernel.c | 2 +- src/libsystemd-bus/bus-message.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index ad0d573149..ffa843d5d1 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -729,7 +729,7 @@ int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) { return fd; } - c = &bus->memfd_cache[-- bus->n_memfd_cache]; + c = &bus->memfd_cache[--bus->n_memfd_cache]; assert(c->fd >= 0); assert(c->size == 0 || c->address); diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c index 77a875d4eb..760a148fad 100644 --- a/src/libsystemd-bus/bus-message.c +++ b/src/libsystemd-bus/bus-message.c @@ -1216,8 +1216,9 @@ static int part_make_space( part->mapped = psz; part->data = n; - part->munmap_this = true; } + + part->munmap_this = true; } else { n = realloc(part->data, sz); if (!n) { @@ -2358,9 +2359,8 @@ void bus_body_part_unmap(struct bus_body_part *part) { if (!part->data) return; - //FIXME: this is not set in the benchmark - //if (!part->munmap_this) - // return; + if (!part->munmap_this) + return; assert_se(munmap(part->data, part->mapped) == 0); -- cgit v1.2.1 From bdf874d4bfd0292e8240418930fac568134389d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 4 Jun 2013 17:44:23 -0400 Subject: man: mention that units are 1024-based --- man/journald.conf.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/man/journald.conf.xml b/man/journald.conf.xml index 6d54c94b57..fe47fdffec 100644 --- a/man/journald.conf.xml +++ b/man/journald.conf.xml @@ -263,8 +263,9 @@ that usually seven rotated journal files are kept as history. Specify values in bytes or use K, M, G, T, P, - E as units for the specified - sizes. Note that size limits are + E as units for the specified sizes + (equal to 1024, 1024²,... bytes). + Note that size limits are enforced synchronously to journal files as they are extended, and need no explicit rotation step triggered by -- cgit v1.2.1 From f3dbb13c8535882be9de14d1cf2b0656c96c89bb Mon Sep 17 00:00:00 2001 From: Pierre Neidhardt Date: Tue, 4 Jun 2013 17:32:33 -0400 Subject: keymap: add some more Asus laptop keys With Linux 3.9 (commit a935eaecef2b209ad661dadabb4e32b7c9a9b924), the Asus keyboard driver has changed to be more compliant to the symbol signification. This has led to some issues with udev. In particular, the XF86TouchpadToggle (a Fn key) does not work anymore on Asus X52J. I found another similar patch which does not seem to have been ever submitted/merged: https://launchpadlibrarian.net/73337842/95-keymap.rules.patch Find enclosed the patch containing both the launchpad patch and mine into one file. https://bugs.freedesktop.org/show_bug.cgi?id=65375 --- src/udev/keymap/95-keymap.rules | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/udev/keymap/95-keymap.rules b/src/udev/keymap/95-keymap.rules index 994950cbaa..18816f17bb 100644 --- a/src/udev/keymap/95-keymap.rules +++ b/src/udev/keymap/95-keymap.rules @@ -49,6 +49,10 @@ ENV{DMI_VENDOR}=="LENOVO*", KERNELS=="input*", ATTRS{name}=="Lenovo ThinkPad SL ENV{DMI_VENDOR}=="LENOVO*", KERNELS=="input*", ATTRS{name}=="Ideapad extra buttons", RUN+="keymap $name 0x42 f23 0x43 f22" ENV{DMI_VENDOR}=="ASUS*", KERNELS=="input*", ATTRS{name}=="Asus Extra Buttons", ATTR{[dmi/id]product_name}=="W3J", RUN+="keymap $name module-asus-w3j" +ENV{DMI_VENDOR}=="ASUS*", KERNELS=="input*", ATTRS{name}=="Asus Laptop extra buttons", RUN+="keymap $name 0x6B f21" +ENV{DMI_VENDOR}=="ASUS*", KERNELS=="input*", ATTRS{name}=="Asus Laptop Support", RUN+="keymap $name 0x6B f21" +ENV{DMI_VENDOR}=="ASUS*", KERNELS=="input*", ATTRS{name}=="Asus WMI hotkeys", RUN+="keymap $name 0x6B f21" +ENV{DMI_VENDOR}=="ASUS*", KERNELS=="input*", ATTRS{name}=="Asus Notebooks WMI Hotkey Driver", RUN+="keymap $name 0x6B f21" ENV{DMI_VENDOR}=="ASUS*", KERNELS=="input*", ATTRS{name}=="Eee PC WMI hotkeys|Asus Laptop Support|Asus*WMI*", RUN+="keymap $name 0x6B f21" ENV{DMI_VENDOR}=="ASUS*", KERNELS=="input*", ATTRS{name}=="Eee PC Hotkey Driver", RUN+="keymap $name 0x37 f21" -- cgit v1.2.1 From 83d97ce664806829b027c02708d648d469724362 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 5 Jun 2013 10:26:00 +0200 Subject: bus: benchmark - adjust printf and MAX_SIZE --- src/libsystemd-bus/test-bus-kernel-benchmark.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libsystemd-bus/test-bus-kernel-benchmark.c b/src/libsystemd-bus/test-bus-kernel-benchmark.c index 2ece2a0029..d9ccdc2239 100644 --- a/src/libsystemd-bus/test-bus-kernel-benchmark.c +++ b/src/libsystemd-bus/test-bus-kernel-benchmark.c @@ -32,7 +32,7 @@ #include "bus-kernel.h" #include "bus-internal.h" -#define MAX_SIZE (8*1024*1024) +#define MAX_SIZE (4*1024*1024) static usec_t arg_loop_usec = 100 * USEC_PER_MSEC; @@ -118,7 +118,7 @@ static void client_bisect(const char *address) { if (csize <= 0) break; - fprintf(stderr, "%zu\t", csize); + printf("%zu\t", csize); b->use_memfd = 0; @@ -176,11 +176,11 @@ static void client_chart(const char *address) { printf("SIZE\tCOPY\tMEMFD\n"); - for (csize = 1; csize < MAX_SIZE; csize *= 2) { + for (csize = 1; csize <= MAX_SIZE; csize *= 2) { usec_t t; unsigned n_copying, n_memfd; - fprintf(stderr, "%zu\t", csize); + printf("%zu\t", csize); b->use_memfd = 0; -- cgit v1.2.1 From 6cbf6931d2d651a5b5adb51f5c784e3c4ce27fe9 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Wed, 5 Jun 2013 12:24:17 +0200 Subject: test-bus-kernel-benchmark: corrected output for memfd bisect --- src/libsystemd-bus/test-bus-kernel-benchmark.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsystemd-bus/test-bus-kernel-benchmark.c b/src/libsystemd-bus/test-bus-kernel-benchmark.c index d9ccdc2239..2e84cd9244 100644 --- a/src/libsystemd-bus/test-bus-kernel-benchmark.c +++ b/src/libsystemd-bus/test-bus-kernel-benchmark.c @@ -138,7 +138,7 @@ static void client_bisect(const char *address) { if (now(CLOCK_MONOTONIC) >= t + arg_loop_usec) break; } - printf("%u\n", (unsigned) ((n_copying * USEC_PER_SEC) / arg_loop_usec)); + printf("%u\n", (unsigned) ((n_memfd * USEC_PER_SEC) / arg_loop_usec)); if (n_copying == n_memfd) break; -- cgit v1.2.1 From 4a4c0be0ab713410ab65bb6bd0c0702abd9e9f4c Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Wed, 5 Jun 2013 12:24:41 +0200 Subject: libsystemd-bus/bus-kernel.h: set MEMFD_MIN_SIZE to 128k --- src/libsystemd-bus/bus-kernel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsystemd-bus/bus-kernel.h b/src/libsystemd-bus/bus-kernel.h index 9515e8f05f..c4573c9222 100644 --- a/src/libsystemd-bus/bus-kernel.h +++ b/src/libsystemd-bus/bus-kernel.h @@ -42,7 +42,7 @@ /* This determines at which minimum size we prefer sending memfds over * sending vectors */ -#define MEMFD_MIN_SIZE (96*1024) +#define MEMFD_MIN_SIZE (128*1024) /* The size of the per-connection memory pool that we set up and where * the kernel places our incoming messages */ -- cgit v1.2.1 From 1cce5d639cdcb3b237e2eda3c36782f98ff23b46 Mon Sep 17 00:00:00 2001 From: Chengwei Yang Date: Mon, 20 May 2013 15:22:27 +0800 Subject: manager: Do not handle SIGKILL since we can not This is a minor fix because it's not a major issue, this fix just avoid to get EINVAL error from sigaction(2). There are two signals can not handled at user space, SIGKILL and SIGSTOP even we're PID 1, trying to handle these two signals will get EINVAL error. There are two kinds of systemd instance, running as system manager or user session manager, apparently, the latter is a general user space process which can not handle SIGKILL. The special pid 1 also can not do that refer to kernel/signal.c:do_sigaction(). However, pid 1 is unkillable because the kernel did attach SIGNAL_UNKILLABLE to it at system boot up, refer to init/main.c:start_kernel() --> rest_init() --> kernel_thread() --> kernel_init() --> init_post() current->signal->flags |= SIGNAL_UNKILLABLE --- src/core/main.c | 1 - src/shared/def.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index bb7364054e..26aa561218 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1405,7 +1405,6 @@ int main(int argc, char *argv[]) { /* Reset all signal handlers. */ assert_se(reset_all_signal_handlers() == 0); - /* If we are init, we can block sigkill. Yay. */ ignore_signals(SIGNALS_IGNORE, -1); if (parse_config_file() < 0) diff --git a/src/shared/def.h b/src/shared/def.h index 5ba170f965..5abb544247 100644 --- a/src/shared/def.h +++ b/src/shared/def.h @@ -32,4 +32,4 @@ #define SYSTEMD_CGROUP_CONTROLLER "name=systemd" #define SIGNALS_CRASH_HANDLER SIGSEGV,SIGILL,SIGFPE,SIGBUS,SIGQUIT,SIGABRT -#define SIGNALS_IGNORE SIGKILL,SIGPIPE +#define SIGNALS_IGNORE SIGPIPE -- cgit v1.2.1 From af4713396cff773beb56fef23cd8a9a3803670ab Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 6 Jun 2013 09:10:12 +0200 Subject: service: execute ExecStopPost= commands when the watchdog timeout hits We can assume that a service for which a watchdog timeout was triggered is unresponsive to a clean shutdown. However, it still makes sense to execute the post-stop cleanup commands that can be configured with ExecStopPost=. Hence, when the timeout is hit enter STOP_SIGKILL rather than FINAL_SIGKILL. --- src/core/service.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/service.c b/src/core/service.c index e110a41dae..20990d2a19 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -249,7 +249,7 @@ static void service_handle_watchdog(Service *s) { offset = now(CLOCK_MONOTONIC) - s->watchdog_timestamp.monotonic; if (offset >= s->watchdog_usec) { log_error_unit(UNIT(s)->id, "%s watchdog timeout!", UNIT(s)->id); - service_enter_signal(s, SERVICE_FINAL_SIGKILL, SERVICE_FAILURE_WATCHDOG); + service_enter_signal(s, SERVICE_STOP_SIGKILL, SERVICE_FAILURE_WATCHDOG); return; } -- cgit v1.2.1 From 5e63ce78b5018ba612e794a610a6f13c5eefade7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristian=20Rodr=C3=ADguez?= Date: Tue, 4 Jun 2013 14:42:56 -0400 Subject: build-sys: do not allow --enable static --- configure.ac | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configure.ac b/configure.ac index d266601aeb..bd46b33e85 100644 --- a/configure.ac +++ b/configure.ac @@ -44,6 +44,8 @@ AS_IF([test "x$host_cpu" = "xmips" || test "x$host_cpu" = "xmipsel" || LT_PREREQ(2.2) LT_INIT([disable-static]) +AS_IF([test "x$enable_static" = "xyes"], [AC_MSG_ERROR([--enable-static is not supported by systemd])]) + # i18n stuff for the PolicyKit policy files IT_PROG_INTLTOOL([0.40.0]) -- cgit v1.2.1 From 3d585edbb14b9705c80183aeb16dfd0a28df0ac9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 6 Jun 2013 10:38:31 +0200 Subject: build-sys: we do not support --disable-largefile builds --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index bd46b33e85..fc71b74c96 100644 --- a/configure.ac +++ b/configure.ac @@ -45,6 +45,7 @@ LT_PREREQ(2.2) LT_INIT([disable-static]) AS_IF([test "x$enable_static" = "xyes"], [AC_MSG_ERROR([--enable-static is not supported by systemd])]) +AS_IF([test "x$enable_largefile" = "xno"], [AC_MSG_ERROR([--disable-largefile is not supported by systemd])]) # i18n stuff for the PolicyKit policy files IT_PROG_INTLTOOL([0.40.0]) -- cgit v1.2.1 From b043cd0b7e0e6567d9ce01bf1905337631fe0fc0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 6 Jun 2013 15:49:01 +0200 Subject: cgroup: the "tasks" attribute is obsolete, cgroup.procs is the new replacement --- src/cgtop/cgtop.c | 2 +- src/shared/cgroup-util.c | 80 +++++++++++++++++++++++++++++------------------- src/shared/cgroup-util.h | 1 - 3 files changed, 49 insertions(+), 34 deletions(-) diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c index 1e21b0074d..fb523a3e6c 100644 --- a/src/cgtop/cgtop.c +++ b/src/cgtop/cgtop.c @@ -134,7 +134,7 @@ static int process(const char *controller, const char *path, Hashmap *a, Hashmap /* Regardless which controller, let's find the maximum number * of processes in any of it */ - r = cg_enumerate_tasks(controller, path, &f); + r = cg_enumerate_processes(controller, path, &f); if (r < 0) return r; diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index 43c415d760..7af0c3c124 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -58,25 +58,6 @@ int cg_enumerate_processes(const char *controller, const char *path, FILE **_f) return 0; } -int cg_enumerate_tasks(const char *controller, const char *path, FILE **_f) { - _cleanup_free_ char *fs = NULL; - FILE *f; - int r; - - assert(_f); - - r = cg_get_path(controller, path, "tasks", &fs); - if (r < 0) - return r; - - f = fopen(fs, "re"); - if (!f) - return -errno; - - *_f = f; - return 0; -} - int cg_read_pid(FILE *f, pid_t *_pid) { unsigned long ul; @@ -159,16 +140,28 @@ int cg_rmdir(const char *controller, const char *path, bool honour_sticky) { return r; if (honour_sticky) { - char *tasks; + char *fn; - /* If the sticky bit is set don't remove the directory */ + /* If the sticky bit is set on cgroup.procs, don't + * remove the directory */ - tasks = strappend(p, "/tasks"); - if (!tasks) + fn = strappend(p, "/cgroup.procs"); + if (!fn) return -ENOMEM; - r = file_is_priv_sticky(tasks); - free(tasks); + r = file_is_priv_sticky(fn); + free(fn); + + if (r > 0) + return 0; + + /* Compatibility ... */ + fn = strappend(p, "/tasks"); + if (!fn) + return -ENOMEM; + + r = file_is_priv_sticky(fn); + free(fn); if (r > 0) return 0; @@ -365,7 +358,7 @@ int cg_migrate(const char *cfrom, const char *pfrom, const char *cto, const char pid_t pid = 0; done = true; - r = cg_enumerate_tasks(cfrom, pfrom, &f); + r = cg_enumerate_processes(cfrom, pfrom, &f); if (r < 0) { if (ret >= 0 && r != -ENOENT) return r; @@ -573,6 +566,19 @@ static int trim_cb(const char *path, const struct stat *sb, int typeflag, struct if (ftwbuf->level < 1) return 0; + p = strappend(path, "/cgroup.procs"); + if (!p) { + errno = ENOMEM; + return 1; + } + + is_sticky = file_is_priv_sticky(p) > 0; + free(p); + + if (is_sticky) + return 0; + + /* Compatibility */ p = strappend(path, "/tasks"); if (!p) { errno = ENOMEM; @@ -607,13 +613,22 @@ int cg_trim(const char *controller, const char *path, bool delete_root) { bool is_sticky; char *p; - p = strappend(fs, "/tasks"); + p = strappend(fs, "/cgroup.procs"); if (!p) return -ENOMEM; is_sticky = file_is_priv_sticky(p) > 0; free(p); + if (!is_sticky) { + p = strappend(fs, "/tasks"); + if (!p) + return -ENOMEM; + + is_sticky = file_is_priv_sticky(p) > 0; + free(p); + } + if (!is_sticky) if (rmdir(fs) < 0 && errno != ENOENT && r == 0) return -errno; @@ -644,7 +659,7 @@ int cg_attach(const char *controller, const char *path, pid_t pid) { assert(path); assert(pid >= 0); - r = cg_get_path_and_check(controller, path, "tasks", &fs); + r = cg_get_path_and_check(controller, path, "cgroup.procs", &fs); if (r < 0) return r; @@ -697,7 +712,7 @@ int cg_set_task_access( if (mode != (mode_t) -1) mode &= 0666; - r = cg_get_path(controller, path, "tasks", &fs); + r = cg_get_path(controller, path, "cgroup.procs", &fs); if (r < 0) return r; @@ -727,8 +742,9 @@ int cg_set_task_access( if (r < 0) return r; - /* Always keep values for "cgroup.procs" in sync with "tasks" */ - r = cg_get_path(controller, path, "cgroup.procs", &procs); + /* Compatibility, Always keep values for "tasks" in sync with + * "cgroup.procs" */ + r = cg_get_path(controller, path, "tasks", &procs); if (r < 0) return r; @@ -869,7 +885,7 @@ int cg_is_empty(const char *controller, const char *path, bool ignore_self) { assert(path); - r = cg_enumerate_tasks(controller, path, &f); + r = cg_enumerate_processes(controller, path, &f); if (r < 0) return r == -ENOENT ? 1 : r; diff --git a/src/shared/cgroup-util.h b/src/shared/cgroup-util.h index 25dd277ba5..5835e04075 100644 --- a/src/shared/cgroup-util.h +++ b/src/shared/cgroup-util.h @@ -44,7 +44,6 @@ */ int cg_enumerate_processes(const char *controller, const char *path, FILE **_f); -int cg_enumerate_tasks(const char *controller, const char *path, FILE **_f); int cg_read_pid(FILE *f, pid_t *_pid); int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d); -- cgit v1.2.1 From 4e09014daf8f98584b3f15e64e93bed232e70a6b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 6 Jun 2013 16:25:38 +0200 Subject: update TODO --- TODO | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index ecc5748c63..fc8044b434 100644 --- a/TODO +++ b/TODO @@ -26,6 +26,18 @@ Fedora 19: Features: +* cgroup-agent: downgrade error messages + +* document systemd-journal-flush.service properly + +* chane systemd-journal-flush into a service that stays around during + boot, and causes the journal to be moved back to /run on shutdown, + so that we don't keep /var busy. This needs to happen synchronously, + hence doing this via signals is not going to work. + +* allow implementation of InaccessibleDirectories=/ plus + ReadOnlyDirectories=... for whitelisting files for a service. + * libsystemd-journal: - return ECHILD as soon as somebody tries to reuse a journal object across a fork() @@ -33,7 +45,6 @@ Features: - default policy (allow uid == 0 and our own uid) - enforce alignment of pointers passed in - when kdbus doesn't take our message without memfds, try again with memfds - - kdbus: generate correct bloom filter for matches - implement translator service - port systemd to new library - implement busname unit type in systemd @@ -46,7 +57,6 @@ Features: - object vtable logic - longer term: * priority queues - * worker threads * priority inheritance * in the final killing spree, detect processes from the root directory, and -- cgit v1.2.1 From 31f7bf1994523f5b8fd014c69b97e09d7043d9ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 23 Apr 2013 22:40:26 -0400 Subject: logs-show: print multiline messages [ 0.019862] fedora kernel: CPU0: Thermal monitoring enabled (TM1) [ 0.019900] fedora kernel: Last level iTLB entries: 4KB 512, 2MB 0, 4MB 0 Last level dTLB entries: 4KB 512, 2MB 32, 4MB 32 tlb_flushall_shift: 5 [ 0.020118] fedora kernel: Freeing SMP alternatives: 24k freed --- src/shared/logs-show.c | 116 ++++++++++++++++++++++++++++++------------------- src/shared/utf8.c | 21 ++++----- src/shared/utf8.h | 4 +- 3 files changed, 83 insertions(+), 58 deletions(-) diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index 79a977c156..b88547eb83 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -95,12 +95,54 @@ static bool shall_print(const char *p, size_t l, OutputFlags flags) { if (l >= PRINT_THRESHOLD) return false; - if (!utf8_is_printable_n(p, l)) + if (!utf8_is_printable(p, l)) return false; return true; } +static void print_multiline(FILE *f, unsigned prefix, unsigned n_columns, int flags, int priority, const char* message, size_t message_len) { + const char *color_on = "", *color_off = ""; + const char *pos, *end; + bool continuation = false; + + if (flags & OUTPUT_COLOR) { + if (priority <= LOG_ERR) { + color_on = ANSI_HIGHLIGHT_RED_ON; + color_off = ANSI_HIGHLIGHT_OFF; + } else if (priority <= LOG_NOTICE) { + color_on = ANSI_HIGHLIGHT_ON; + color_off = ANSI_HIGHLIGHT_OFF; + } + } + + for (pos = message; pos < message + message_len; pos = end + 1) { + int len; + for (end = pos; end < message + message_len && *end != '\n'; end++) + ; + len = end - pos; + assert(len >= 0); + + if ((flags & OUTPUT_FULL_WIDTH) || (prefix + len + 1 < n_columns)) + fprintf(f, "%*s%s%.*s%s\n", + continuation * prefix, "", + color_on, len, pos, color_off); + else if (prefix < n_columns && n_columns - prefix >= 3) { + _cleanup_free_ char *e; + + e = ellipsize_mem(pos, len, n_columns - prefix, 90); + + if (!e) + fprintf(f, "%s%.*s%s\n", color_on, len, pos, color_off); + else + fprintf(f, "%s%s%s\n", color_on, e, color_off); + } else + fputs("...\n", f); + + continuation = true; + } +} + static int output_short( FILE *f, sd_journal *j, @@ -115,7 +157,6 @@ static int output_short( _cleanup_free_ char *hostname = NULL, *identifier = NULL, *comm = NULL, *pid = NULL, *fake_pid = NULL, *message = NULL, *realtime = NULL, *monotonic = NULL, *priority = NULL; size_t hostname_len = 0, identifier_len = 0, comm_len = 0, pid_len = 0, fake_pid_len = 0, message_len = 0, realtime_len = 0, monotonic_len = 0, priority_len = 0; int p = LOG_INFO; - const char *color_on = "", *color_off = ""; assert(f); assert(j); @@ -260,34 +301,13 @@ static int output_short( n += fake_pid_len + 2; } - if (flags & OUTPUT_COLOR) { - if (p <= LOG_ERR) { - color_on = ANSI_HIGHLIGHT_RED_ON; - color_off = ANSI_HIGHLIGHT_OFF; - } else if (p <= LOG_NOTICE) { - color_on = ANSI_HIGHLIGHT_ON; - color_off = ANSI_HIGHLIGHT_OFF; - } - } - - if (flags & OUTPUT_SHOW_ALL) - fprintf(f, ": %s%.*s%s\n", color_on, (int) message_len, message, color_off); - else if (!utf8_is_printable_n(message, message_len)) { + if (!(flags & OUTPUT_SHOW_ALL) && !utf8_is_printable(message, message_len)) { char bytes[FORMAT_BYTES_MAX]; fprintf(f, ": [%s blob data]\n", format_bytes(bytes, sizeof(bytes), message_len)); - } else if ((flags & OUTPUT_FULL_WIDTH) || (message_len + n + 1 < n_columns)) - fprintf(f, ": %s%.*s%s\n", color_on, (int) message_len, message, color_off); - else if (n < n_columns && n_columns - n - 2 >= 3) { - _cleanup_free_ char *e; - - e = ellipsize_mem(message, message_len, n_columns - n - 2, 90); - - if (!e) - fprintf(f, ": %s%.*s%s\n", color_on, (int) message_len, message, color_off); - else - fprintf(f, ": %s%s%s\n", color_on, e, color_off); - } else - fputs("\n", f); + } else { + fputs(": ", f); + print_multiline(f, n + 2, n_columns, flags, p, message, message_len); + } if (flags & OUTPUT_CATALOG) print_catalog(f, j); @@ -331,22 +351,26 @@ static int output_verbose( cursor); SD_JOURNAL_FOREACH_DATA(j, data, length) { - if (!shall_print(data, length, flags)) { - const char *c; - char bytes[FORMAT_BYTES_MAX]; + const char *c; + int fieldlen; + c = memchr(data, '=', length); + if (!c) { + log_error("Invalid field."); + return -EINVAL; + } + fieldlen = c - (const char*) data; - c = memchr(data, '=', length); - if (!c) { - log_error("Invalid field."); - return -EINVAL; - } + if ((flags & OUTPUT_SHOW_ALL) || (length < PRINT_THRESHOLD && utf8_is_printable(data, length))) { + fprintf(f, " %.*s=", fieldlen, (const char*)data); + print_multiline(f, 4 + fieldlen + 1, 0, OUTPUT_FULL_WIDTH, 0, c + 1, length - fieldlen - 1); + } else { + char bytes[FORMAT_BYTES_MAX]; - fprintf(f, "\t%.*s=[%s blob data]\n", - (int) (c - (const char*) data), - (const char*) data, - format_bytes(bytes, sizeof(bytes), length - (c - (const char *) data) - 1)); - } else - fprintf(f, "\t%.*s\n", (int) length, (const char*) data); + fprintf(f, " %.*s=[%s blob data]\n", + (int) (c - (const char*) data), + (const char*) data, + format_bytes(bytes, sizeof(bytes), length - (c - (const char *) data) - 1)); + } } if (flags & OUTPUT_CATALOG) @@ -410,7 +434,7 @@ static int output_export( memcmp(data, "_BOOT_ID=", 9) == 0) continue; - if (!utf8_is_printable_n(data, length)) { + if (!utf8_is_printable(data, length)) { const char *c; uint64_t le64; @@ -449,7 +473,7 @@ void json_escape( fputs("null", f); - else if (!utf8_is_printable_n(p, l)) { + else if (!utf8_is_printable(p, l)) { bool not_first = false; fputs("[ ", f); @@ -474,7 +498,9 @@ void json_escape( if (*p == '"' || *p == '\\') { fputc('\\', f); fputc(*p, f); - } else if (*p < ' ') + } else if (*p == '\n') + fputs("\\n", f); + else if (*p < ' ') fprintf(f, "\\u%04x", *p); else fputc(*p, f); diff --git a/src/shared/utf8.c b/src/shared/utf8.c index 3964e8b1ce..655cc771d4 100644 --- a/src/shared/utf8.c +++ b/src/shared/utf8.c @@ -86,11 +86,11 @@ static bool is_unicode_control(uint32_t ch) { '\t' is in C0 range, but more or less harmless and commonly used. */ - return (ch < ' ' && ch != '\t') || + return (ch < ' ' && ch != '\t' && ch != '\n') || (0x7F <= ch && ch <= 0x9F); } -char* utf8_is_printable_n(const char* str, size_t length) { +bool utf8_is_printable(const char* str, size_t length) { uint32_t val = 0; uint32_t min = 0; const uint8_t *p; @@ -113,40 +113,37 @@ char* utf8_is_printable_n(const char* str, size_t length) { min = (1 << 16); val = (uint32_t) (*p & 0x07); } else - goto error; + return false; p++; length--; if (!length || !is_continuation_char(*p)) - goto error; + return false; merge_continuation_char(&val, *p); TWO_REMAINING: p++; length--; if (!is_continuation_char(*p)) - goto error; + return false; merge_continuation_char(&val, *p); ONE_REMAINING: p++; length--; if (!is_continuation_char(*p)) - goto error; + return false; merge_continuation_char(&val, *p); if (val < min) - goto error; + return false; } if (is_unicode_control(val)) - goto error; + return false; } - return (char*) str; - -error: - return NULL; + return true; } static char* utf8_validate(const char *str, char *output) { diff --git a/src/shared/utf8.h b/src/shared/utf8.h index 794ae15ab9..f805ea6b59 100644 --- a/src/shared/utf8.h +++ b/src/shared/utf8.h @@ -21,12 +21,14 @@ along with systemd; If not, see . ***/ +#include + #include "macro.h" char *utf8_is_valid(const char *s) _pure_; char *ascii_is_valid(const char *s) _pure_; -char *utf8_is_printable_n(const char* str, size_t length) _pure_; +bool utf8_is_printable(const char* str, size_t length) _pure_; char *utf8_filter(const char *s); char *ascii_filter(const char *s); -- cgit v1.2.1 From 856323c9cb0ef368367126588d0b43b4846ab0d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 9 Jun 2013 14:02:32 -0400 Subject: systemctl: remove extra padding from status output In 131601349 'systemctl: align all status fields to common column', padding was calculated for 'ListenStream: ...', etc. Later on in 45a4f7233 'systemctl: tweak output of Listen: fields a bit' output was changed to 'Listen: ... (stream)', but calculation didn't change. Just remove the calculation, since now the result will be always 8, and it it more important to have everything aligned to the widest field ("Main-PID"), than to save a few columns, usually at most two (e.g. "Listen"). Note: strlen is more natural, and is optimized to sizeof even with -O0. --- src/systemctl/systemctl.c | 70 ++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 41 deletions(-) diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 58a6fd4044..0ba3568a1e 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -2700,20 +2700,10 @@ static void print_status_info(UnitStatusInfo *i) { on_tty() * OUTPUT_COLOR | !arg_quiet * OUTPUT_WARN_CUTOFF | arg_full * OUTPUT_FULL_WIDTH; - int maxlen = 8; /* a value that'll suffice most of the time */ char **t, **t2; assert(i); - STRV_FOREACH_PAIR(t, t2, i->listen) - maxlen = MAX(maxlen, (int)(sizeof("Listen") - 1 + strlen(*t))); - if (i->accept) - maxlen = MAX(maxlen, (int)sizeof("Accept") - 1); - if (i->main_pid > 0) - maxlen = MAX(maxlen, (int)sizeof("Main PID") - 1); - else if (i->control_pid > 0) - maxlen = MAX(maxlen, (int)sizeof("Control") - 1); - /* This shows pretty information about a unit. See * print_property() for a low-level property printer */ @@ -2725,7 +2715,7 @@ static void print_status_info(UnitStatusInfo *i) { printf("\n"); if (i->following) - printf(" %*s: unit currently follows state of %s\n", maxlen, "Follow", i->following); + printf(" Follow: unit currently follows state of %s\n", i->following); if (streq_ptr(i->load_state, "error")) { on = ansi_highlight_red(true); @@ -2736,17 +2726,17 @@ static void print_status_info(UnitStatusInfo *i) { path = i->source_path ? i->source_path : i->fragment_path; if (i->load_error) - printf(" %*s: %s%s%s (Reason: %s)\n", - maxlen, "Loaded", on, strna(i->load_state), off, i->load_error); + printf(" Loaded: %s%s%s (Reason: %s)\n", + on, strna(i->load_state), off, i->load_error); else if (path && i->unit_file_state) - printf(" %*s: %s%s%s (%s; %s)\n", - maxlen, "Loaded", on, strna(i->load_state), off, path, i->unit_file_state); + printf(" Loaded: %s%s%s (%s; %s)\n", + on, strna(i->load_state), off, path, i->unit_file_state); else if (path) - printf(" %*s: %s%s%s (%s)\n", - maxlen, "Loaded", on, strna(i->load_state), off, path); + printf(" Loaded: %s%s%s (%s)\n", + on, strna(i->load_state), off, path); else - printf(" %*s: %s%s%s\n", - maxlen, "Loaded", on, strna(i->load_state), off); + printf(" Loaded: %s%s%s\n", + on, strna(i->load_state), off); if (!strv_isempty(i->dropin_paths)) { char ** dropin; @@ -2755,7 +2745,7 @@ static void print_status_info(UnitStatusInfo *i) { STRV_FOREACH(dropin, i->dropin_paths) { if (! dir || last) { - printf(" %*s ", maxlen, dir ? "" : "Drop-In:"); + printf(dir ? " " : " Drop-In: "); free(dir); @@ -2764,7 +2754,7 @@ static void print_status_info(UnitStatusInfo *i) { return; } - printf("%s\n %*s %s", dir, maxlen, "", + printf("%s\n %s", dir, draw_special_char(DRAW_TREE_RIGHT)); } @@ -2788,11 +2778,11 @@ static void print_status_info(UnitStatusInfo *i) { on = off = ""; if (ss) - printf(" %*s: %s%s (%s)%s", - maxlen, "Active", on, strna(i->active_state), ss, off); + printf(" Active: %s%s (%s)%s", + on, strna(i->active_state), ss, off); else - printf(" %*s: %s%s%s", - maxlen, "Active", on, strna(i->active_state), off); + printf(" Active: %s%s%s", + on, strna(i->active_state), off); if (!isempty(i->result) && !streq(i->result, "success")) printf(" (Result: %s)", i->result); @@ -2819,26 +2809,26 @@ static void print_status_info(UnitStatusInfo *i) { s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp); if (s1) - printf(" %*s start condition failed at %s; %s\n", maxlen, "", s2, s1); + printf(" start condition failed at %s; %s\n", s2, s1); else if (s2) - printf(" %*s start condition failed at %s\n", maxlen, "", s2); + printf(" start condition failed at %s\n", s2); } if (i->sysfs_path) - printf(" %*s: %s\n", maxlen, "Device", i->sysfs_path); + printf(" Device: %s\n", i->sysfs_path); if (i->where) - printf(" %*s: %s\n", maxlen, "Where", i->where); + printf(" Where: %s\n", i->where); if (i->what) - printf(" %*s: %s\n", maxlen, "What", i->what); + printf(" What: %s\n", i->what); STRV_FOREACH(t, i->documentation) - printf(" %*s %s\n", maxlen+1, t == i->documentation ? "Docs:" : "", *t); + printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t); STRV_FOREACH_PAIR(t, t2, i->listen) - printf(" %*s %s (%s)\n", maxlen+1, t == i->listen ? "Listen:" : "", *t2, *t); + printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t); if (i->accept) - printf(" %*s: %u; Connected: %u\n", maxlen, "Accepted", i->n_accepted, i->n_connections); + printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections); LIST_FOREACH(exec, p, i->exec) { _cleanup_free_ char *argv = NULL; @@ -2849,7 +2839,7 @@ static void print_status_info(UnitStatusInfo *i) { continue; argv = strv_join(p->argv, " "); - printf(" %*s: %u %s=%s ", maxlen, "Process", p->pid, p->name, strna(argv)); + printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv)); good = is_clean_exit_lsb(p->code, p->status, NULL); if (!good) { @@ -2886,7 +2876,7 @@ static void print_status_info(UnitStatusInfo *i) { if (i->main_pid > 0 || i->control_pid > 0) { if (i->main_pid > 0) { - printf(" %*s: %u", maxlen, "Main PID", (unsigned) i->main_pid); + printf(" Main PID: %u", (unsigned) i->main_pid); if (i->running) { _cleanup_free_ char *comm = NULL; @@ -2917,7 +2907,7 @@ static void print_status_info(UnitStatusInfo *i) { if (i->control_pid > 0) { _cleanup_free_ char *c = NULL; - printf(" %*s: %u", i->main_pid ? 0 : maxlen, "Control", (unsigned) i->control_pid); + printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid); get_process_comm(i->control_pid, &c); if (c) @@ -2928,20 +2918,18 @@ static void print_status_info(UnitStatusInfo *i) { } if (i->status_text) - printf(" %*s: \"%s\"\n", maxlen, "Status", i->status_text); + printf(" Status: \"%s\"\n", i->status_text); if (i->default_control_group && (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_by_spec(i->default_control_group, false) == 0)) { unsigned c; - printf(" %*s: %s\n", maxlen, "CGroup", i->default_control_group); + printf(" CGroup: %s\n", i->default_control_group); if (arg_transport != TRANSPORT_SSH) { unsigned k = 0; pid_t extra[2]; - char prefix[maxlen + 4]; - memset(prefix, ' ', sizeof(prefix) - 1); - prefix[sizeof(prefix) - 1] = '\0'; + char prefix[] = " "; c = columns(); if (c > sizeof(prefix) - 1) -- cgit v1.2.1 From 7085053a437456ab87d726f3697002dd811fdf7a Mon Sep 17 00:00:00 2001 From: Daniel Wallace Date: Sun, 9 Jun 2013 15:54:39 -0500 Subject: Allow for the use of @ in remote host calls Without this you have to use %40 with the -H flag because dbus doesn't like the @ sign being unescaped. --- src/hostname/hostnamectl.c | 5 +++-- src/locale/localectl.c | 5 +++-- src/login/loginctl.c | 5 +++-- src/shared/dbus-common.c | 4 ++-- src/shared/util.c | 14 ++++++++++++++ src/shared/util.h | 1 + src/systemctl/systemctl.c | 7 ++++--- src/timedate/timedatectl.c | 5 +++-- 8 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/hostname/hostnamectl.c b/src/hostname/hostnamectl.c index d108a2489d..f7d844b975 100644 --- a/src/hostname/hostnamectl.c +++ b/src/hostname/hostnamectl.c @@ -44,7 +44,8 @@ static enum transport { TRANSPORT_POLKIT } arg_transport = TRANSPORT_NORMAL; static bool arg_ask_password = true; -static const char *arg_host = NULL; +static char *arg_host = NULL; +static char *arg_user = NULL; static bool arg_set_transient = false; static bool arg_set_pretty = false; static bool arg_set_static = false; @@ -421,7 +422,7 @@ static int parse_argv(int argc, char *argv[]) { case 'H': arg_transport = TRANSPORT_SSH; - arg_host = optarg; + parse_user_at_host(optarg, &arg_user, &arg_host); break; case ARG_SET_TRANSIENT: diff --git a/src/locale/localectl.c b/src/locale/localectl.c index b5cd344397..cd7356a1e1 100644 --- a/src/locale/localectl.c +++ b/src/locale/localectl.c @@ -46,7 +46,8 @@ static enum transport { TRANSPORT_POLKIT } arg_transport = TRANSPORT_NORMAL; static bool arg_ask_password = true; -static const char *arg_host = NULL; +static char *arg_host = NULL; +static char *arg_user = NULL; static bool arg_convert = true; static void pager_open_if_enabled(void) { @@ -777,7 +778,7 @@ static int parse_argv(int argc, char *argv[]) { case 'H': arg_transport = TRANSPORT_SSH; - arg_host = optarg; + parse_user_at_host(optarg, &arg_user, &arg_host); break; case ARG_NO_CONVERT: diff --git a/src/login/loginctl.c b/src/login/loginctl.c index caaea8dfaa..b09aa37ff8 100644 --- a/src/login/loginctl.c +++ b/src/login/loginctl.c @@ -50,7 +50,8 @@ static enum transport { TRANSPORT_POLKIT } arg_transport = TRANSPORT_NORMAL; static bool arg_ask_password = true; -static const char *arg_host = NULL; +static char *arg_host = NULL; +static char *arg_user = NULL; static void pager_open_if_enabled(void) { @@ -1421,7 +1422,7 @@ static int parse_argv(int argc, char *argv[]) { case 'H': arg_transport = TRANSPORT_SSH; - arg_host = optarg; + parse_user_at_host(optarg, &arg_user, &arg_host); break; case ARG_FULL: diff --git a/src/shared/dbus-common.c b/src/shared/dbus-common.c index b8c15cb9fc..f579567321 100644 --- a/src/shared/dbus-common.c +++ b/src/shared/dbus-common.c @@ -178,9 +178,9 @@ int bus_connect_system_ssh(const char *user, const char *host, DBusConnection ** assert(user || host); if (user && host) - asprintf(&p, "unixexec:path=ssh,argv1=-xT,argv2=%s@%s,argv3=systemd-stdio-bridge", user, host); + asprintf(&p, "unixexec:path=ssh,argv1=-xT,argv2=%s%%40%s,argv3=systemd-stdio-bridge", user, host); else if (user) - asprintf(&p, "unixexec:path=ssh,argv1=-xT,argv2=%s@localhost,argv3=systemd-stdio-bridge", user); + asprintf(&p, "unixexec:path=ssh,argv1=-xT,argv2=%s%%40localhost,argv3=systemd-stdio-bridge", user); else if (host) asprintf(&p, "unixexec:path=ssh,argv1=-xT,argv2=%s,argv3=systemd-stdio-bridge", host); diff --git a/src/shared/util.c b/src/shared/util.c index 2edf9cd875..d0bbf78bf3 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -5847,3 +5847,17 @@ bool id128_is_valid(const char *s) { return true; } + +void parse_user_at_host(char *arg, char **user, char **host) { + assert(arg); + assert(user); + assert(host); + + *host = strchr(arg, '@'); + if (*host == NULL) + *host = arg; + else { + *host[0]++ = '\0'; + *user = arg; + } +} diff --git a/src/shared/util.h b/src/shared/util.h index 64e63b8c07..e6f9312e95 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -732,3 +732,4 @@ static inline void _reset_locale_(struct _locale_struct_ *s) { _saved_locale_.quit = true) bool id128_is_valid(const char *s) _pure_; +void parse_user_at_host(char *arg, char **user, char **host); diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 0ba3568a1e..3e4cefec76 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -129,7 +129,8 @@ static enum transport { TRANSPORT_SSH, TRANSPORT_POLKIT } arg_transport = TRANSPORT_NORMAL; -static const char *arg_host = NULL; +static char *arg_host = NULL; +static char *arg_user = NULL; static unsigned arg_lines = 10; static OutputMode arg_output = OUTPUT_SHORT; static bool arg_plain = false; @@ -5065,7 +5066,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { case 'H': arg_transport = TRANSPORT_SSH; - arg_host = optarg; + parse_user_at_host(optarg, &arg_user, &arg_host); break; case ARG_RUNTIME: @@ -6086,7 +6087,7 @@ int main(int argc, char*argv[]) { bus_connect_system_polkit(&bus, &error); private_bus = false; } else if (arg_transport == TRANSPORT_SSH) { - bus_connect_system_ssh(NULL, arg_host, &bus, &error); + bus_connect_system_ssh(arg_user, arg_host, &bus, &error); private_bus = false; } else assert_not_reached("Uh, invalid transport..."); diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c index e8bc4529f3..d2b483efac 100644 --- a/src/timedate/timedatectl.c +++ b/src/timedate/timedatectl.c @@ -44,7 +44,8 @@ static enum transport { TRANSPORT_POLKIT } arg_transport = TRANSPORT_NORMAL; static bool arg_ask_password = true; -static const char *arg_host = NULL; +static char *arg_host = NULL; +static char *arg_user = NULL; static void pager_open_if_enabled(void) { @@ -560,7 +561,7 @@ static int parse_argv(int argc, char *argv[]) { case 'H': arg_transport = TRANSPORT_SSH; - arg_host = optarg; + parse_user_at_host(optarg, &arg_user, &arg_host); break; case ARG_NO_ASK_PASSWORD: -- cgit v1.2.1 From 62220cf70e381f6e08390523e4696f7bc431f927 Mon Sep 17 00:00:00 2001 From: Ross Lagerwall Date: Sun, 9 Jun 2013 17:28:44 +0100 Subject: service: don't report alien child as alive when it's not When a sigchld is received from an alien child, main_pid is set to 0 then service_enter_running calls main_pid_good to check if the child is running. This incorrectly returned true because kill(main_pid, 0) would return >= 0. This fixes an error where a service would die and the cgroup would become empty but the service would still report as active (running). --- src/core/service.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/service.c b/src/core/service.c index 20990d2a19..dadd98123c 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -1865,7 +1865,7 @@ static int main_pid_good(Service *s) { /* If it's an alien child let's check if it is still * alive ... */ - if (s->main_pid_alien) + if (s->main_pid_alien && s->main_pid > 0) return kill(s->main_pid, 0) >= 0 || errno != ESRCH; /* .. otherwise assume we'll get a SIGCHLD for it, -- cgit v1.2.1 From a72b63536f1da3a97677bf38590f22a962e5fe98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 9 Jun 2013 21:50:56 -0400 Subject: journalctl: fix verbose output when no logs are found $ journalctl -o verbose _EXE=/quiet/binary -f -- Logs begin at Sun 2013-03-17 17:28:22 EDT. -- Failed to get realtime timestamp: Cannot assign requested address JOURNAL_FOREACH_DATA_RETVAL is added, which allows the caller to get the return value from sd_journal_enumerate_data. I think we might want to expose this macro like SD_JOURNAL_FOREACH_DATA, but for now it is in journal-internal.h. There's a change in behaviour for output_*, not only in output_verbose, that errors in sd_j_enumerate_data are not silently ignored anymore. https://bugs.freedesktop.org/show_bug.cgi?id=56459 --- src/journal/journal-internal.h | 3 +++ src/journal/journalctl.c | 11 ++++++----- src/shared/logs-show.c | 27 ++++++++++++++++++++------- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/journal/journal-internal.h b/src/journal/journal-internal.h index c7e585d810..f576a0073d 100644 --- a/src/journal/journal-internal.h +++ b/src/journal/journal-internal.h @@ -139,3 +139,6 @@ static inline void journal_closep(sd_journal **j) { } #define _cleanup_journal_close_ _cleanup_(journal_closep) + +#define JOURNAL_FOREACH_DATA_RETVAL(j, data, l, retval) \ + for (sd_journal_restart_data(j); ((retval) = sd_journal_enumerate_data((j), &(data), &(l))) > 0; ) diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index eb79c4d853..de972a17db 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -1288,11 +1288,10 @@ int main(int argc, char *argv[]) { log_error("Failed to iterate through journal: %s", strerror(-r)); goto finish; } + if (r == 0) + break; } - if (r == 0) - break; - if (arg_until_set && !arg_reverse) { usec_t usec; @@ -1338,10 +1337,12 @@ int main(int argc, char *argv[]) { arg_catalog * OUTPUT_CATALOG; r = output_journal(stdout, j, arg_output, 0, flags); - if (r < 0 || ferror(stdout)) + need_seek = true; + if (r == -EADDRNOTAVAIL) + break; + else if (r < 0 || ferror(stdout)) goto finish; - need_seek = true; n_shown++; } diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index b88547eb83..7947df3a89 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -163,7 +163,7 @@ static int output_short( sd_journal_set_data_threshold(j, flags & OUTPUT_SHOW_ALL ? 0 : PRINT_THRESHOLD); - SD_JOURNAL_FOREACH_DATA(j, data, length) { + JOURNAL_FOREACH_DATA_RETVAL(j, data, length, r) { r = parse_field(data, length, "PRIORITY=", &priority, &priority_len); if (r < 0) @@ -218,6 +218,9 @@ static int output_short( return r; } + if (r < 0) + return r; + if (!message) return 0; @@ -240,7 +243,7 @@ static int output_short( r = sd_journal_get_monotonic_usec(j, &t, &boot_id); if (r < 0) { - log_error("Failed to get monotonic: %s", strerror(-r)); + log_error("Failed to get monotonic timestamp: %s", strerror(-r)); return r; } @@ -265,7 +268,7 @@ static int output_short( r = sd_journal_get_realtime_usec(j, &x); if (r < 0) { - log_error("Failed to get realtime: %s", strerror(-r)); + log_error("Failed to get realtime timestamp: %s", strerror(-r)); return r; } @@ -336,7 +339,8 @@ static int output_verbose( r = sd_journal_get_realtime_usec(j, &realtime); if (r < 0) { - log_error("Failed to get realtime timestamp: %s", strerror(-r)); + log_full(r == -EADDRNOTAVAIL ? LOG_DEBUG : LOG_ERR, + "Failed to get realtime timestamp: %s", strerror(-r)); return r; } @@ -350,7 +354,7 @@ static int output_verbose( format_timestamp(ts, sizeof(ts), realtime), cursor); - SD_JOURNAL_FOREACH_DATA(j, data, length) { + JOURNAL_FOREACH_DATA_RETVAL(j, data, length, r) { const char *c; int fieldlen; c = memchr(data, '=', length); @@ -373,6 +377,9 @@ static int output_verbose( } } + if (r < 0) + return r; + if (flags & OUTPUT_CATALOG) print_catalog(f, j); @@ -426,7 +433,7 @@ static int output_export( (unsigned long long) monotonic, sd_id128_to_string(boot_id, sid)); - SD_JOURNAL_FOREACH_DATA(j, data, length) { + JOURNAL_FOREACH_DATA_RETVAL(j, data, length, r) { /* We already printed the boot id, from the data in * the header, hence let's suppress it here */ @@ -455,6 +462,9 @@ static int output_export( fputc('\n', f); } + if (r < 0) + return r; + fputc('\n', f); return 0; @@ -583,7 +593,7 @@ static int output_json( return -ENOMEM; /* First round, iterate through the entry and count how often each field appears */ - SD_JOURNAL_FOREACH_DATA(j, data, length) { + JOURNAL_FOREACH_DATA_RETVAL(j, data, length, r) { const char *eq; char *n; unsigned u; @@ -617,6 +627,9 @@ static int output_json( } } + if (r < 0) + return r; + separator = true; do { done = true; -- cgit v1.2.1 From 696fee7d95194948f7f6a17eab93213b925a846d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 10 Jun 2013 08:50:59 -0400 Subject: dev-setup: do not create a dangling /proc/kcore symlink https://bugs.freedesktop.org/show_bug.cgi?id=65382 https://bugs.gentoo.org/472060?id=472060 --- src/shared/dev-setup.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/shared/dev-setup.c b/src/shared/dev-setup.c index b0ac02d461..50a187fda9 100644 --- a/src/shared/dev-setup.c +++ b/src/shared/dev-setup.c @@ -54,13 +54,19 @@ void dev_setup(const char *prefix) { const char *j, *k; static const char symlinks[] = - "/proc/kcore\0" "/dev/core\0" + "-/proc/kcore\0" "/dev/core\0" "/proc/self/fd\0" "/dev/fd\0" "/proc/self/fd/0\0" "/dev/stdin\0" "/proc/self/fd/1\0" "/dev/stdout\0" "/proc/self/fd/2\0" "/dev/stderr\0"; NULSTR_FOREACH_PAIR(j, k, symlinks) { + if (j[0] == '-') { + j++; + + if (access(j, F_OK)) + continue; + } if (prefix) { char *linkname; -- cgit v1.2.1 From c5a10d9ca017be6133154e09383c84c3d5b85f7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 2 Jun 2013 15:00:00 -0400 Subject: journal: simplify match_free_if_empty --- src/journal/sd-journal.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index cf60ebcee2..2bad243ea1 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -197,9 +197,7 @@ static void match_free(Match *m) { } static void match_free_if_empty(Match *m) { - assert(m); - - if (m->matches) + if (!m || m->matches) return; match_free(m); @@ -296,17 +294,10 @@ _public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size) return 0; fail: - if (add_here) - match_free_if_empty(add_here); - - if (j->level2) - match_free_if_empty(j->level2); - - if (j->level1) - match_free_if_empty(j->level1); - - if (j->level0) - match_free_if_empty(j->level0); + match_free_if_empty(add_here); + match_free_if_empty(j->level2); + match_free_if_empty(j->level1); + match_free_if_empty(j->level0); return -ENOMEM; } -- cgit v1.2.1 From a688baa8b71f9c74500f7883dfb137194874266a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 4 Jun 2013 22:31:05 -0400 Subject: journal: add ability to filter by current user This is the just the library part. SD_JOURNAL_CURRENT_USER flags is added to sd_j_open(), to open files from current user. SD_JOURNAL_SYSTEM_ONLY is renamed to SD_JOURNAL_SYSTEM, and changed to mean to (also) open system files. This way various flags can be combined, which gives them nicer semantics, especially if other ones are added later. Backwards compatibility is kept, because SD_JOURNAL_SYSTEM_ONLY is equivalent to SD_JOURNAL_SYSTEM if used alone, and before there we no other flags. --- Makefile-man.am | 10 ++++++++++ man/sd_journal_open.xml | 35 +++++++++++++++++++++++++++----- src/journal/journal-gatewayd.c | 2 +- src/journal/sd-journal.c | 45 ++++++++++++++++++++++++++++++++++++------ src/python-systemd/_reader.c | 1 + src/shared/logs-show.c | 2 +- src/systemd/sd-journal.h | 4 +++- 7 files changed, 85 insertions(+), 14 deletions(-) diff --git a/Makefile-man.am b/Makefile-man.am index 58881586cf..a31427e9b9 100644 --- a/Makefile-man.am +++ b/Makefile-man.am @@ -107,6 +107,7 @@ MANPAGES_ALIAS += \ man/SD_ID128_MAKE.3 \ man/SD_INFO.3 \ man/SD_JOURNAL_APPEND.3 \ + man/SD_JOURNAL_CURRENT_USER.3 \ man/SD_JOURNAL_FOREACH.3 \ man/SD_JOURNAL_FOREACH_BACKWARDS.3 \ man/SD_JOURNAL_FOREACH_DATA.3 \ @@ -116,6 +117,7 @@ MANPAGES_ALIAS += \ man/SD_JOURNAL_NOP.3 \ man/SD_JOURNAL_RUNTIME_ONLY.3 \ man/SD_JOURNAL_SUPPRESS_LOCATION.3 \ + man/SD_JOURNAL_SYSTEM.3 \ man/SD_JOURNAL_SYSTEM_ONLY.3 \ man/SD_LISTEN_FDS_START.3 \ man/SD_NOTICE.3 \ @@ -205,6 +207,7 @@ man/SD_ID128_FORMAT_VAL.3: man/sd-id128.3 man/SD_ID128_MAKE.3: man/sd-id128.3 man/SD_INFO.3: man/sd-daemon.3 man/SD_JOURNAL_APPEND.3: man/sd_journal_get_fd.3 +man/SD_JOURNAL_CURRENT_USER.3: man/sd_journal_open.3 man/SD_JOURNAL_FOREACH.3: man/sd_journal_next.3 man/SD_JOURNAL_FOREACH_BACKWARDS.3: man/sd_journal_next.3 man/SD_JOURNAL_FOREACH_DATA.3: man/sd_journal_get_data.3 @@ -214,6 +217,7 @@ man/SD_JOURNAL_LOCAL_ONLY.3: man/sd_journal_open.3 man/SD_JOURNAL_NOP.3: man/sd_journal_get_fd.3 man/SD_JOURNAL_RUNTIME_ONLY.3: man/sd_journal_open.3 man/SD_JOURNAL_SUPPRESS_LOCATION.3: man/sd_journal_print.3 +man/SD_JOURNAL_SYSTEM.3: man/sd_journal_open.3 man/SD_JOURNAL_SYSTEM_ONLY.3: man/sd_journal_open.3 man/SD_LISTEN_FDS_START.3: man/sd_listen_fds.3 man/SD_NOTICE.3: man/sd-daemon.3 @@ -325,6 +329,9 @@ man/SD_INFO.html: man/sd-daemon.html man/SD_JOURNAL_APPEND.html: man/sd_journal_get_fd.html $(html-alias) +man/SD_JOURNAL_CURRENT_USER.html: man/sd_journal_open.html + $(html-alias) + man/SD_JOURNAL_FOREACH.html: man/sd_journal_next.html $(html-alias) @@ -352,6 +359,9 @@ man/SD_JOURNAL_RUNTIME_ONLY.html: man/sd_journal_open.html man/SD_JOURNAL_SUPPRESS_LOCATION.html: man/sd_journal_print.html $(html-alias) +man/SD_JOURNAL_SYSTEM.html: man/sd_journal_open.html + $(html-alias) + man/SD_JOURNAL_SYSTEM_ONLY.html: man/sd_journal_open.html $(html-alias) diff --git a/man/sd_journal_open.xml b/man/sd_journal_open.xml index 76b857b991..dd2f32d81a 100644 --- a/man/sd_journal_open.xml +++ b/man/sd_journal_open.xml @@ -49,7 +49,8 @@ sd_journal SD_JOURNAL_LOCAL_ONLY SD_JOURNAL_RUNTIME_ONLY - SD_JOURNAL_SYSTEM_ONLY + SD_JOURNAL_SYSTEM + SD_JOURNAL_CURRENT_USER Open the system journal for reading @@ -93,10 +94,14 @@ be opened. SD_JOURNAL_RUNTIME_ONLY makes sure only volatile journal files will be opened, excluding those which are stored on persistent - storage. SD_JOURNAL_SYSTEM_ONLY - will ensure that only journal files of system services - and the kernel (in opposition to user session processes) will - be opened. + storage. SD_JOURNAL_SYSTEM + will cause journal files of system services and the + kernel (in opposition to user session processes) to + be opened. SD_JOURNAL_CURRENT_USER + will cause journal files of the current user to be + opened. If neither SD_JOURNAL_SYSTEM + nor SD_JOURNAL_CURRENT_USER are + specified, all journal file types will be opened. sd_journal_open_directory() is similar to sd_journal_open() @@ -170,6 +175,26 @@ file. + + History + + sd_journal_open(), + sd_journal_close(), + SD_JOURNAL_LOCAL_ONLY, + SD_JOURNAL_RUNTIME_ONLY, + SD_JOURNAL_SYSTEM_ONLY were added + in systemd-38. + + sd_journal_open_directory() + was added in systemd-187. + + SD_JOURNAL_SYSTEM and + SD_JOURNAL_CURRENT_USER were added + in systemd-205. + SD_JOURNAL_SYSTEM_ONLY + was deprecated. + + See Also diff --git a/src/journal/journal-gatewayd.c b/src/journal/journal-gatewayd.c index 745f45f932..86338c66f3 100644 --- a/src/journal/journal-gatewayd.c +++ b/src/journal/journal-gatewayd.c @@ -109,7 +109,7 @@ static int open_journal(RequestMeta *m) { if (m->journal) return 0; - return sd_journal_open(&m->journal, SD_JOURNAL_LOCAL_ONLY|SD_JOURNAL_SYSTEM_ONLY); + return sd_journal_open(&m->journal, SD_JOURNAL_LOCAL_ONLY|SD_JOURNAL_SYSTEM); } static int respond_oom_internal(struct MHD_Connection *connection) { diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index 2bad243ea1..46511df6be 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -1249,6 +1249,42 @@ static void check_network(sd_journal *j, int fd) { F_TYPE_CMP(sfs.f_type, SMB_SUPER_MAGIC); } +static bool file_has_type_prefix(const char *prefix, const char *filename) { + const char *full, *tilded, *atted; + + full = strappend(prefix, ".journal"); + tilded = strappenda(full, "~"); + atted = strappenda(prefix, "@"); + + return streq(filename, full) || + streq(filename, tilded) || + startswith(filename, atted); +} + +static bool file_type_wanted(int flags, const char *filename) { + if (!endswith(filename, ".journal") && !endswith(filename, ".journal~")) + return false; + + /* no flags set → every type is OK */ + if (!(flags & (SD_JOURNAL_SYSTEM | SD_JOURNAL_CURRENT_USER))) + return true; + + if (flags & SD_JOURNAL_SYSTEM && file_has_type_prefix("system", filename)) + return true; + + if (flags & SD_JOURNAL_CURRENT_USER) { + char prefix[5 + DECIMAL_STR_MAX(uid_t) + 1]; + + assert_se(snprintf(prefix, sizeof(prefix), "user-%lu", (unsigned long) getuid()) + < (int) sizeof(prefix)); + + if (file_has_type_prefix(prefix, filename)) + return true; + } + + return false; +} + static int add_file(sd_journal *j, const char *prefix, const char *filename) { _cleanup_free_ char *path = NULL; int r; @@ -1258,11 +1294,7 @@ static int add_file(sd_journal *j, const char *prefix, const char *filename) { assert(prefix); assert(filename); - if ((j->flags & SD_JOURNAL_SYSTEM_ONLY) && - !(streq(filename, "system.journal") || - streq(filename, "system.journal~") || - (startswith(filename, "system@") && - (endswith(filename, ".journal") || endswith(filename, ".journal~"))))) + if (!file_type_wanted(j->flags, filename)) return 0; path = strjoin(prefix, "/", filename, NULL); @@ -1619,7 +1651,8 @@ _public_ int sd_journal_open(sd_journal **ret, int flags) { if (flags & ~(SD_JOURNAL_LOCAL_ONLY| SD_JOURNAL_RUNTIME_ONLY| - SD_JOURNAL_SYSTEM_ONLY)) + SD_JOURNAL_SYSTEM| + SD_JOURNAL_CURRENT_USER)) return -EINVAL; j = journal_new(flags, NULL); diff --git a/src/python-systemd/_reader.c b/src/python-systemd/_reader.c index c4c4fdfe1d..2c699630c2 100644 --- a/src/python-systemd/_reader.c +++ b/src/python-systemd/_reader.c @@ -1097,6 +1097,7 @@ init_reader(void) PyModule_AddIntConstant(m, "INVALIDATE", SD_JOURNAL_INVALIDATE) || PyModule_AddIntConstant(m, "LOCAL_ONLY", SD_JOURNAL_LOCAL_ONLY) || PyModule_AddIntConstant(m, "RUNTIME_ONLY", SD_JOURNAL_RUNTIME_ONLY) || + PyModule_AddIntConstant(m, "SYSTEM", SD_JOURNAL_SYSTEM) || PyModule_AddIntConstant(m, "SYSTEM_ONLY", SD_JOURNAL_SYSTEM_ONLY) || PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION)) { #if PY_MAJOR_VERSION >= 3 diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index 7947df3a89..013a281eac 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -1010,7 +1010,7 @@ int show_journal_by_unit( _cleanup_journal_close_ sd_journal*j = NULL; int r; - int jflags = SD_JOURNAL_LOCAL_ONLY | system * SD_JOURNAL_SYSTEM_ONLY; + int jflags = SD_JOURNAL_LOCAL_ONLY | system * SD_JOURNAL_SYSTEM; assert(mode >= 0); assert(mode < _OUTPUT_MODE_MAX); diff --git a/src/systemd/sd-journal.h b/src/systemd/sd-journal.h index 5375d49963..cf105cde72 100644 --- a/src/systemd/sd-journal.h +++ b/src/systemd/sd-journal.h @@ -86,7 +86,9 @@ typedef struct sd_journal sd_journal; enum { SD_JOURNAL_LOCAL_ONLY = 1, SD_JOURNAL_RUNTIME_ONLY = 2, - SD_JOURNAL_SYSTEM_ONLY = 4 + SD_JOURNAL_SYSTEM = 4, + SD_JOURNAL_SYSTEM_ONLY = SD_JOURNAL_SYSTEM, /* deprecated */ + SD_JOURNAL_CURRENT_USER = 8, }; /* Wakeup event types */ -- cgit v1.2.1 From 3f3a438f58d7b1d2ba2b44d6d356fb1eaa65b66a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 4 Jun 2013 19:33:34 -0400 Subject: journalctl: add --system/--user flags --user basically gives messages from your own systemd --user services. --system basically gives messages from PID 1, kernel, and --system services. Those two options are not exahustive, because a priviledged user might be able to see messages from other users, and they will not be shown with either or both of those flags. --- man/journalctl.xml | 14 ++++++++++++++ shell-completion/bash/journalctl | 1 + shell-completion/systemd-zsh-completion.zsh | 2 ++ src/journal/journalctl.c | 21 ++++++++++++++++++--- 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/man/journalctl.xml b/man/journalctl.xml index d9ca0a6074..66100816ae 100644 --- a/man/journalctl.xml +++ b/man/journalctl.xml @@ -447,6 +447,20 @@ journal. + + + + + Show messages from + system services and the kernel (with + ). Show + messages from service of current user + (with ). + If neither is specified, show all + messages that the user can see. + + + diff --git a/shell-completion/bash/journalctl b/shell-completion/bash/journalctl index 19362ae77b..5ab59c9940 100644 --- a/shell-completion/bash/journalctl +++ b/shell-completion/bash/journalctl @@ -38,6 +38,7 @@ _journalctl() { local field_vals= cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} local -A OPTS=( [STANDALONE]='-a --all --full + --system --user -b --this-boot --disk-usage -f --follow --header -h --help -l --local --new-id128 -m --merge --no-pager --no-tail -q --quiet --setup-keys --this-boot --verify diff --git a/shell-completion/systemd-zsh-completion.zsh b/shell-completion/systemd-zsh-completion.zsh index 411646ea59..6862891723 100644 --- a/shell-completion/systemd-zsh-completion.zsh +++ b/shell-completion/systemd-zsh-completion.zsh @@ -71,6 +71,8 @@ _ctls() '--since=[Start showing entries newer or of the specified date]:YYYY-MM-DD HH\:MM\:SS' \ '--until=[Stop showing entries older or of the specified date]:YYYY-MM-DD HH\:MM\:SS' \ {-c,--cursor=}'[Start showing entries from specified cursor]:cursors:_journal_fields __CURSORS' \ + '--system[Show system and kernel messages]' \ + '--user[Show messages from user services]' \ {-b,--this-boot}'[Show data only from current boot]' \ {-u,--unit=}'[Show data only from the specified unit]:units:_journal_fields _SYSTEMD_UNIT' \ '--user-unit[Show data only from the specified user session unit]:units:_journal_fields _SYSTEMD_USER_UNIT' \ diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index de972a17db..f404e414f4 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -86,6 +86,7 @@ static char **arg_user_units = NULL; static const char *arg_field = NULL; static bool arg_catalog = false; static bool arg_reverse = false; +static int arg_journal_type = 0; static const char *arg_root = NULL; static enum { @@ -105,6 +106,8 @@ static int help(void) { printf("%s [OPTIONS...] [MATCHES...]\n\n" "Query the journal.\n\n" "Flags:\n" + " --system Show only the system journal\n" + " --user Show only the user journal for current user\n" " --since=DATE Start showing entries newer or of the specified date\n" " --until=DATE Stop showing entries older or of the specified date\n" " -c --cursor=CURSOR Start showing entries from specified cursor\n" @@ -158,6 +161,8 @@ static int parse_argv(int argc, char *argv[]) { ARG_NO_PAGER, ARG_NO_TAIL, ARG_NEW_ID128, + ARG_USER, + ARG_SYSTEM, ARG_ROOT, ARG_HEADER, ARG_FULL, @@ -171,7 +176,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_USER_UNIT, ARG_LIST_CATALOG, ARG_DUMP_CATALOG, - ARG_UPDATE_CATALOG + ARG_UPDATE_CATALOG, }; static const struct option options[] = { @@ -190,6 +195,8 @@ static int parse_argv(int argc, char *argv[]) { { "merge", no_argument, NULL, 'm' }, { "this-boot", no_argument, NULL, 'b' }, { "dmesg", no_argument, NULL, 'k' }, + { "system", no_argument, NULL, ARG_SYSTEM }, + { "user", no_argument, NULL, ARG_USER }, { "directory", required_argument, NULL, 'D' }, { "root", required_argument, NULL, ARG_ROOT }, { "header", no_argument, NULL, ARG_HEADER }, @@ -324,6 +331,14 @@ static int parse_argv(int argc, char *argv[]) { arg_this_boot = arg_dmesg = true; break; + case ARG_SYSTEM: + arg_journal_type |= SD_JOURNAL_SYSTEM; + break; + + case ARG_USER: + arg_journal_type |= SD_JOURNAL_CURRENT_USER; + break; + case 'D': arg_directory = optarg; break; @@ -1094,9 +1109,9 @@ int main(int argc, char *argv[]) { } if (arg_directory) - r = sd_journal_open_directory(&j, arg_directory, 0); + r = sd_journal_open_directory(&j, arg_directory, arg_journal_type); else - r = sd_journal_open(&j, arg_merge ? 0 : SD_JOURNAL_LOCAL_ONLY); + r = sd_journal_open(&j, !arg_merge*SD_JOURNAL_LOCAL_ONLY + arg_journal_type); if (r < 0) { log_error("Failed to open journal: %s", strerror(-r)); return EXIT_FAILURE; -- cgit v1.2.1 From 2bc8ca0ca2fefcfb63a37723d7a9bbb9ae76ceb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 5 Jun 2013 00:56:03 -0400 Subject: journal: loop less in MATCH_AND_TERM conditionals MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AND term usually don't have many subterms (4 seems to be the maximum sensible number, e.g. _BOOT_ID && _SYSTEMD_UNIT && _PID && MESSAGE_ID). Nevertheless, the cost of checking each subterm can be relatively high, especially when the nested terms are compound, and it makes sense to minimize the number of checks. Instead of looping to the end and then again over the whole list once again after at least one term changed the offset, start the loop at the term which caused the change. This way ½ terms in the AND match are not checked unnecessarily again. --- src/journal/sd-journal.c | 41 +++++++++++++++++------------------------ src/shared/list.h | 7 +++++++ 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index 46511df6be..8b9a589cd3 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -593,42 +593,35 @@ static int next_for_match( } } else if (m->type == MATCH_AND_TERM) { - Match *i; - bool continue_looking; + Match *i, *last_moved; /* Always jump to the next matching entry and repeat - * this until we fine and offset that matches for all + * this until we find an offset that matches for all * matches. */ if (!m->matches) return 0; - np = 0; - do { - continue_looking = false; + r = next_for_match(j, m->matches, f, after_offset, direction, NULL, &np); + if (r <= 0) + return r; - LIST_FOREACH(matches, i, m->matches) { - uint64_t cp, limit; + assert(direction == DIRECTION_DOWN ? np >= after_offset : np <= after_offset); + last_moved = m->matches; - if (np == 0) - limit = after_offset; - else if (direction == DIRECTION_DOWN) - limit = MAX(np, after_offset); - else - limit = MIN(np, after_offset); + LIST_LOOP_BUT_ONE(matches, i, m->matches, last_moved) { + uint64_t cp; - r = next_for_match(j, i, f, limit, direction, NULL, &cp); - if (r <= 0) - return r; + r = next_for_match(j, i, f, np, direction, NULL, &cp); + if (r <= 0) + return r; - if ((direction == DIRECTION_DOWN ? cp >= after_offset : cp <= after_offset) && - (np == 0 || (direction == DIRECTION_DOWN ? cp > np : cp < np))) { - np = cp; - continue_looking = true; - } + assert(direction == DIRECTION_DOWN ? cp >= np : cp <= np); + if (direction == DIRECTION_DOWN ? cp > np : cp < np) { + np = cp; + last_moved = i; } - - } while (continue_looking); + } } if (np == 0) diff --git a/src/shared/list.h b/src/shared/list.h index 47f275a019..96d6237974 100644 --- a/src/shared/list.h +++ b/src/shared/list.h @@ -123,3 +123,10 @@ #define LIST_FOREACH_AFTER(name,i,p) \ for ((i) = (p)->name##_next; (i); (i) = (i)->name##_next) + +/* Loop starting from p->next until p->prev. + p can be adjusted meanwhile. */ +#define LIST_LOOP_BUT_ONE(name,i,head,p) \ + for ((i) = (p)->name##_next ? (p)->name##_next : (head); \ + (i) != (p); \ + (i) = (i)->name##_next ? (i)->name##_next : (head)) -- cgit v1.2.1 From 3001c74580c1713bd634990a0b2ab351fdec7a98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 5 Jun 2013 20:33:42 -0400 Subject: journalctl: no color for --reboot-- when not on tty --- src/journal/journalctl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index f404e414f4..af0f4ba3c8 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -1333,12 +1333,14 @@ int main(int argc, char *argv[]) { if (!arg_merge) { sd_id128_t boot_id; + const char *color_on = on_tty() ? ANSI_HIGHLIGHT_ON : "", + *color_off = on_tty() ? ANSI_HIGHLIGHT_OFF : ""; r = sd_journal_get_monotonic_usec(j, NULL, &boot_id); if (r >= 0) { if (previous_boot_id_valid && !sd_id128_equal(boot_id, previous_boot_id)) - printf(ANSI_HIGHLIGHT_ON "-- Reboot --" ANSI_HIGHLIGHT_OFF "\n"); + printf("%s-- Reboot --%s\n", color_on, color_off); previous_boot_id = boot_id; previous_boot_id_valid = true; -- cgit v1.2.1 From b32ff512191bf873266ee8067f6f6c8a30c96a5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 5 Jun 2013 19:33:45 -0400 Subject: Properly check for overflow in offsets --- src/shared/util.c | 18 ++++++++++++++---- src/test/test-util.c | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/src/shared/util.c b/src/shared/util.c index d0bbf78bf3..17928ec36e 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -2261,7 +2261,7 @@ ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) { int parse_bytes(const char *t, off_t *bytes) { static const struct { const char *suffix; - off_t factor; + unsigned long long factor; } table[] = { { "B", 1 }, { "K", 1024ULL }, @@ -2274,7 +2274,7 @@ int parse_bytes(const char *t, off_t *bytes) { }; const char *p; - off_t r = 0; + unsigned long long r = 0; assert(t); assert(bytes); @@ -2301,7 +2301,17 @@ int parse_bytes(const char *t, off_t *bytes) { for (i = 0; i < ELEMENTSOF(table); i++) if (startswith(e, table[i].suffix)) { - r += (off_t) l * table[i].factor; + unsigned long long tmp; + if ((unsigned long long) l > ULLONG_MAX / table[i].factor) + return -ERANGE; + tmp = l * table[i].factor; + if (tmp > ULLONG_MAX - r) + return -ERANGE; + + r += tmp; + if ((unsigned long long) (off_t) r != r) + return -ERANGE; + p = e + strlen(table[i].suffix); break; } @@ -2309,7 +2319,7 @@ int parse_bytes(const char *t, off_t *bytes) { if (i >= ELEMENTSOF(table)) return -EINVAL; - } while (*p != 0); + } while (*p); *bytes = r; diff --git a/src/test/test-util.c b/src/test/test-util.c index 4c3a8a6b88..9396aebd63 100644 --- a/src/test/test-util.c +++ b/src/test/test-util.c @@ -439,6 +439,44 @@ static void test_protect_errno(void) { assert(errno == 12); } +static void test_parse_bytes(void) { + off_t bytes; + + assert_se(parse_bytes("111", &bytes) == 0); + assert_se(bytes == 111); + + assert_se(parse_bytes(" 112 B", &bytes) == 0); + assert_se(bytes == 112); + + assert_se(parse_bytes("3 K", &bytes) == 0); + assert_se(bytes == 3*1024); + + assert_se(parse_bytes(" 4 M 11K", &bytes) == 0); + assert_se(bytes == 4*1024*1024 + 11 * 1024); + + assert_se(parse_bytes("3B3G", &bytes) == 0); + assert_se(bytes == 3ULL*1024*1024*1024 + 3); + + assert_se(parse_bytes("3B3G4T", &bytes) == 0); + assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3); + + assert_se(parse_bytes("12P", &bytes) == 0); + assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024); + + assert_se(parse_bytes("3E 2P", &bytes) == 0); + assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024); + + assert_se(parse_bytes("12X", &bytes) == -EINVAL); + + assert_se(parse_bytes("1024E", &bytes) == -ERANGE); + assert_se(parse_bytes("-1", &bytes) == -ERANGE); + assert_se(parse_bytes("-1024E", &bytes) == -ERANGE); + + assert_se(parse_bytes("-1024P", &bytes) == -ERANGE); + + assert_se(parse_bytes("-10B 20K", &bytes) == -ERANGE); +} + int main(int argc, char *argv[]) { test_streq_ptr(); test_first_word(); @@ -467,6 +505,7 @@ int main(int argc, char *argv[]) { test_u64log2(); test_get_process_comm(); test_protect_errno(); + test_parse_bytes(); return 0; } -- cgit v1.2.1 From 507f22bd0172bff5e5d98145b1419bd472a2c57f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 5 Jun 2013 18:44:16 -0400 Subject: Use stdint.h macros instead of casts to print uint64_t values Casts are visually heavy, and can obscure unwanted truncations. --- src/core/execute.c | 2 +- src/journal/journal-authenticate.c | 10 ++-- src/journal/journal-file.c | 90 ++++++++++++++++++------------------ src/journal/journal-gatewayd.c | 12 ++--- src/journal/journal-qrcode.c | 6 +-- src/journal/journal-verify.c | 94 ++++++++++++++++++-------------------- src/journal/journald-kmsg.c | 3 +- src/journal/sd-journal.c | 10 ++-- src/journal/test-journal-verify.c | 4 +- src/libudev/libudev-hwdb.c | 10 ++-- src/login/logind-session.c | 59 ++++++------------------ 11 files changed, 133 insertions(+), 167 deletions(-) diff --git a/src/core/execute.c b/src/core/execute.c index 3959ef9623..9148d06df4 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -1837,7 +1837,7 @@ static void strv_fprintf(FILE *f, char **l) { } void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { - char ** e; + char **e; unsigned i; assert(c); diff --git a/src/journal/journal-authenticate.c b/src/journal/journal-authenticate.c index 64bf96874e..bd7100a8d5 100644 --- a/src/journal/journal-authenticate.c +++ b/src/journal/journal-authenticate.c @@ -60,9 +60,9 @@ int journal_file_append_tag(JournalFile *f) { o->tag.seqnum = htole64(journal_file_tag_seqnum(f)); o->tag.epoch = htole64(FSPRG_GetEpoch(f->fsprg_state)); - log_debug("Writing tag %llu for epoch %llu\n", - (unsigned long long) le64toh(o->tag.seqnum), - (unsigned long long) FSPRG_GetEpoch(f->fsprg_state)); + log_debug("Writing tag %"PRIu64" for epoch %"PRIu64"\n", + le64toh(o->tag.seqnum), + FSPRG_GetEpoch(f->fsprg_state)); /* Add the tag object itself, so that we can protect its * header. This will exclude the actual hash value in it */ @@ -152,7 +152,7 @@ int journal_file_fsprg_evolve(JournalFile *f, uint64_t realtime) { epoch = FSPRG_GetEpoch(f->fsprg_state); if (epoch < goal) - log_debug("Evolving FSPRG key from epoch %llu to %llu.", (unsigned long long) epoch, (unsigned long long) goal); + log_debug("Evolving FSPRG key from epoch %"PRIu64" to %"PRIu64".", epoch, goal); for (;;) { if (epoch > goal) @@ -195,7 +195,7 @@ int journal_file_fsprg_seek(JournalFile *f, uint64_t goal) { return -ENOMEM; } - log_debug("Seeking FSPRG key to %llu.", (unsigned long long) goal); + log_debug("Seeking FSPRG key to %"PRIu64".", goal); msk = alloca(FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR)); FSPRG_GenMK(msk, NULL, f->fsprg_seed, f->fsprg_seed_size, FSPRG_RECOMMENDED_SECPAR); diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index 38499a6881..3cb8f79947 100644 --- a/src/journal/journal-file.c +++ b/src/journal/journal-file.c @@ -549,7 +549,7 @@ static int journal_file_setup_data_hash_table(JournalFile *f) { if (s < DEFAULT_DATA_HASH_TABLE_SIZE) s = DEFAULT_DATA_HASH_TABLE_SIZE; - log_debug("Reserving %llu entries in hash table.", (unsigned long long) (s / sizeof(HashItem))); + log_debug("Reserving %"PRIu64" entries in hash table.", s / sizeof(HashItem)); r = journal_file_append_object(f, OBJECT_DATA_HASH_TABLE, @@ -985,7 +985,7 @@ static int journal_file_append_data( o->object.size = htole64(offsetof(Object, data.payload) + rsize); o->object.flags |= OBJECT_COMPRESSED; - log_debug("Compressed data object %lu -> %lu", (unsigned long) size, (unsigned long) rsize); + log_debug("Compressed data object %"PRIu64" -> %"PRIu64, size, rsize); } } #endif @@ -1206,7 +1206,7 @@ static int journal_file_link_entry(JournalFile *f, Object *o, uint64_t offset) { if (r < 0) return r; - /* log_debug("=> %s seqnr=%lu n_entries=%lu", f->path, (unsigned long) o->entry.seqnum, (unsigned long) f->header->n_entries); */ + /* log_debug("=> %s seqnr=%"PRIu64" n_entries=%"PRIu64, f->path, o->entry.seqnum, f->header->n_entries); */ if (f->header->head_entry_realtime == 0) f->header->head_entry_realtime = o->entry.realtime; @@ -2227,10 +2227,10 @@ void journal_file_dump(JournalFile *f) { break; case OBJECT_ENTRY: - printf("Type: OBJECT_ENTRY seqnum=%llu monotonic=%llu realtime=%llu\n", - (unsigned long long) le64toh(o->entry.seqnum), - (unsigned long long) le64toh(o->entry.monotonic), - (unsigned long long) le64toh(o->entry.realtime)); + printf("Type: OBJECT_ENTRY seqnum=%"PRIu64" monotonic=%"PRIu64" realtime=%"PRIu64"\n", + le64toh(o->entry.seqnum), + le64toh(o->entry.monotonic), + le64toh(o->entry.realtime)); break; case OBJECT_FIELD_HASH_TABLE: @@ -2246,9 +2246,9 @@ void journal_file_dump(JournalFile *f) { break; case OBJECT_TAG: - printf("Type: OBJECT_TAG seqnum=%llu epoch=%llu\n", - (unsigned long long) le64toh(o->tag.seqnum), - (unsigned long long) le64toh(o->tag.epoch)); + printf("Type: OBJECT_TAG seqnum=%"PRIu64" epoch=%"PRIu64"\n", + le64toh(o->tag.seqnum), + le64toh(o->tag.epoch)); break; default: @@ -2286,17 +2286,17 @@ void journal_file_print_header(JournalFile *f) { "State: %s\n" "Compatible Flags:%s%s\n" "Incompatible Flags:%s%s\n" - "Header size: %llu\n" - "Arena size: %llu\n" - "Data Hash Table Size: %llu\n" - "Field Hash Table Size: %llu\n" + "Header size: %"PRIu64"\n" + "Arena size: %"PRIu64"\n" + "Data Hash Table Size: %"PRIu64"\n" + "Field Hash Table Size: %"PRIu64"\n" "Rotate Suggested: %s\n" - "Head Sequential Number: %llu\n" - "Tail Sequential Number: %llu\n" + "Head Sequential Number: %"PRIu64"\n" + "Tail Sequential Number: %"PRIu64"\n" "Head Realtime Timestamp: %s\n" "Tail Realtime Timestamp: %s\n" - "Objects: %llu\n" - "Entry Objects: %llu\n", + "Objects: %"PRIu64"\n" + "Entry Objects: %"PRIu64"\n", f->path, sd_id128_to_string(f->header->file_id, a), sd_id128_to_string(f->header->machine_id, b), @@ -2309,36 +2309,36 @@ void journal_file_print_header(JournalFile *f) { (le32toh(f->header->compatible_flags) & ~HEADER_COMPATIBLE_SEALED) ? " ???" : "", JOURNAL_HEADER_COMPRESSED(f->header) ? " COMPRESSED" : "", (le32toh(f->header->incompatible_flags) & ~HEADER_INCOMPATIBLE_COMPRESSED) ? " ???" : "", - (unsigned long long) le64toh(f->header->header_size), - (unsigned long long) le64toh(f->header->arena_size), - (unsigned long long) le64toh(f->header->data_hash_table_size) / sizeof(HashItem), - (unsigned long long) le64toh(f->header->field_hash_table_size) / sizeof(HashItem), + le64toh(f->header->header_size), + le64toh(f->header->arena_size), + le64toh(f->header->data_hash_table_size) / sizeof(HashItem), + le64toh(f->header->field_hash_table_size) / sizeof(HashItem), yes_no(journal_file_rotate_suggested(f, 0)), - (unsigned long long) le64toh(f->header->head_entry_seqnum), - (unsigned long long) le64toh(f->header->tail_entry_seqnum), + le64toh(f->header->head_entry_seqnum), + le64toh(f->header->tail_entry_seqnum), format_timestamp(x, sizeof(x), le64toh(f->header->head_entry_realtime)), format_timestamp(y, sizeof(y), le64toh(f->header->tail_entry_realtime)), - (unsigned long long) le64toh(f->header->n_objects), - (unsigned long long) le64toh(f->header->n_entries)); + le64toh(f->header->n_objects), + le64toh(f->header->n_entries)); if (JOURNAL_HEADER_CONTAINS(f->header, n_data)) - printf("Data Objects: %llu\n" + printf("Data Objects: %"PRIu64"\n" "Data Hash Table Fill: %.1f%%\n", - (unsigned long long) le64toh(f->header->n_data), + le64toh(f->header->n_data), 100.0 * (double) le64toh(f->header->n_data) / ((double) (le64toh(f->header->data_hash_table_size) / sizeof(HashItem)))); if (JOURNAL_HEADER_CONTAINS(f->header, n_fields)) - printf("Field Objects: %llu\n" + printf("Field Objects: %"PRIu64"\n" "Field Hash Table Fill: %.1f%%\n", - (unsigned long long) le64toh(f->header->n_fields), + le64toh(f->header->n_fields), 100.0 * (double) le64toh(f->header->n_fields) / ((double) (le64toh(f->header->field_hash_table_size) / sizeof(HashItem)))); if (JOURNAL_HEADER_CONTAINS(f->header, n_tags)) - printf("Tag Objects: %llu\n", - (unsigned long long) le64toh(f->header->n_tags)); + printf("Tag Objects: %"PRIu64"\n", + le64toh(f->header->n_tags)); if (JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays)) - printf("Entry Array Objects: %llu\n", - (unsigned long long) le64toh(f->header->n_entry_arrays)); + printf("Entry Array Objects: %"PRIu64"\n", + le64toh(f->header->n_entry_arrays)); if (fstat(f->fd, &st) >= 0) printf("Disk usage: %s\n", format_bytes(bytes, sizeof(bytes), (off_t) st.st_blocks * 512ULL)); @@ -2564,9 +2564,9 @@ int journal_file_rotate(JournalFile **f, bool compress, bool seal) { p[l-8] = '@'; sd_id128_to_string(old_file->header->seqnum_id, p + l - 8 + 1); snprintf(p + l - 8 + 1 + 32, 1 + 16 + 1 + 16 + 8 + 1, - "-%016llx-%016llx.journal", - (unsigned long long) le64toh((*f)->header->head_entry_seqnum), - (unsigned long long) le64toh((*f)->header->head_entry_realtime)); + "-%016"PRIx64"-%016"PRIx64".journal", + le64toh((*f)->header->head_entry_seqnum), + le64toh((*f)->header->head_entry_realtime)); r = rename(old_file->path, p); free(p); @@ -2873,23 +2873,23 @@ bool journal_file_rotate_suggested(JournalFile *f, usec_t max_file_usec) { if (JOURNAL_HEADER_CONTAINS(f->header, n_data)) if (le64toh(f->header->n_data) * 4ULL > (le64toh(f->header->data_hash_table_size) / sizeof(HashItem)) * 3ULL) { - log_debug("Data hash table of %s has a fill level at %.1f (%llu of %llu items, %llu file size, %llu bytes per hash table item), suggesting rotation.", + log_debug("Data hash table of %s has a fill level at %.1f (%"PRIu64" of %"PRIu64" items, %llu file size, %"PRIu64" bytes per hash table item), suggesting rotation.", f->path, 100.0 * (double) le64toh(f->header->n_data) / ((double) (le64toh(f->header->data_hash_table_size) / sizeof(HashItem))), - (unsigned long long) le64toh(f->header->n_data), - (unsigned long long) (le64toh(f->header->data_hash_table_size) / sizeof(HashItem)), - (unsigned long long) (f->last_stat.st_size), - (unsigned long long) (f->last_stat.st_size / le64toh(f->header->n_data))); + le64toh(f->header->n_data), + le64toh(f->header->data_hash_table_size) / sizeof(HashItem), + (unsigned long long) f->last_stat.st_size, + f->last_stat.st_size / le64toh(f->header->n_data)); return true; } if (JOURNAL_HEADER_CONTAINS(f->header, n_fields)) if (le64toh(f->header->n_fields) * 4ULL > (le64toh(f->header->field_hash_table_size) / sizeof(HashItem)) * 3ULL) { - log_debug("Field hash table of %s has a fill level at %.1f (%llu of %llu items), suggesting rotation.", + log_debug("Field hash table of %s has a fill level at %.1f (%"PRIu64" of %"PRIu64" items), suggesting rotation.", f->path, 100.0 * (double) le64toh(f->header->n_fields) / ((double) (le64toh(f->header->field_hash_table_size) / sizeof(HashItem))), - (unsigned long long) le64toh(f->header->n_fields), - (unsigned long long) (le64toh(f->header->field_hash_table_size) / sizeof(HashItem))); + le64toh(f->header->n_fields), + le64toh(f->header->field_hash_table_size) / sizeof(HashItem)); return true; } diff --git a/src/journal/journal-gatewayd.c b/src/journal/journal-gatewayd.c index 86338c66f3..10224a1ac1 100644 --- a/src/journal/journal-gatewayd.c +++ b/src/journal/journal-gatewayd.c @@ -834,17 +834,17 @@ static int request_handler_machine( "\"hostname\" : \"%s\"," "\"os_pretty_name\" : \"%s\"," "\"virtualization\" : \"%s\"," - "\"usage\" : \"%llu\"," - "\"cutoff_from_realtime\" : \"%llu\"," - "\"cutoff_to_realtime\" : \"%llu\" }\n", + "\"usage\" : \"%"PRIu64"\"," + "\"cutoff_from_realtime\" : \"%"PRIu64"\"," + "\"cutoff_to_realtime\" : \"%"PRIu64"\" }\n", SD_ID128_FORMAT_VAL(mid), SD_ID128_FORMAT_VAL(bid), hostname_cleanup(hostname, false), os_name ? os_name : "Linux", v ? v : "bare", - (unsigned long long) usage, - (unsigned long long) cutoff_from, - (unsigned long long) cutoff_to); + usage, + cutoff_from, + cutoff_to); if (r < 0) return respond_oom(connection); diff --git a/src/journal/journal-qrcode.c b/src/journal/journal-qrcode.c index 10a14e4def..1db66e89c6 100644 --- a/src/journal/journal-qrcode.c +++ b/src/journal/journal-qrcode.c @@ -76,9 +76,9 @@ int print_qr_code( fprintf(f, "%02x", ((uint8_t*) seed)[i]); } - fprintf(f, "/%llx-%llx?machine=" SD_ID128_FORMAT_STR, - (unsigned long long) start, - (unsigned long long) interval, + fprintf(f, "/%"PRIx64"-%"PRIx64"?machine=" SD_ID128_FORMAT_STR, + start, + interval, SD_ID128_FORMAT_VAL(machine)); if (hn) diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c index ed28b45737..01c89bc8a4 100644 --- a/src/journal/journal-verify.c +++ b/src/journal/journal-verify.c @@ -203,7 +203,7 @@ static void draw_progress(uint64_t p, usec_t *last_usec) { for (i = 0; i < k; i++) fputs("\xe2\x96\x91", stdout); - printf(" %3lu%%", 100LU * (unsigned long) p / 65535LU); + printf(" %3"PRIu64"%%", 100U * p / 65535U); fputs("\r\x1B[?25h", stdout); fflush(stdout); @@ -288,7 +288,7 @@ static int entry_points_to_data( assert(entry_fd >= 0); if (!contains_uint64(f->mmap, entry_fd, n_entries, entry_p)) { - log_error("Data object references invalid entry at %llu", (unsigned long long) data_p); + log_error("Data object references invalid entry at %"PRIu64, data_p); return -EBADMSG; } @@ -304,7 +304,7 @@ static int entry_points_to_data( } if (!found) { - log_error("Data object not referenced by linked entry at %llu", (unsigned long long) data_p); + log_error("Data object not referenced by linked entry at %"PRIu64, data_p); return -EBADMSG; } @@ -347,7 +347,7 @@ static int entry_points_to_data( x = z; } - log_error("Entry object doesn't exist in main entry array at %llu", (unsigned long long) entry_p); + log_error("Entry object doesn't exist in main entry array at %"PRIu64, entry_p); return -EBADMSG; } @@ -388,12 +388,12 @@ static int verify_data( uint64_t next, m, j; if (a == 0) { - log_error("Array chain too short at %llu", (unsigned long long) p); + log_error("Array chain too short at %"PRIu64, p); return -EBADMSG; } if (!contains_uint64(f->mmap, entry_array_fd, n_entry_arrays, a)) { - log_error("Invalid array at %llu", (unsigned long long) p); + log_error("Invalid array at %"PRIu64, p); return -EBADMSG; } @@ -403,7 +403,7 @@ static int verify_data( next = le64toh(o->entry_array.next_entry_array_offset); if (next != 0 && next <= a) { - log_error("Array chain has cycle at %llu", (unsigned long long) p); + log_error("Array chain has cycle at %"PRIu64, p); return -EBADMSG; } @@ -412,7 +412,7 @@ static int verify_data( q = le64toh(o->entry_array.items[j]); if (q <= last) { - log_error("Data object's entry array not sorted at %llu", (unsigned long long) p); + log_error("Data object's entry array not sorted at %"PRIu64, p); return -EBADMSG; } last = q; @@ -463,8 +463,8 @@ static int verify_hash_table( uint64_t next; if (!contains_uint64(f->mmap, data_fd, n_data, p)) { - log_error("Invalid data object at hash entry %llu of %llu", - (unsigned long long) i, (unsigned long long) n); + log_error("Invalid data object at hash entry %"PRIu64" of %"PRIu64, + i, n); return -EBADMSG; } @@ -474,14 +474,14 @@ static int verify_hash_table( next = le64toh(o->data.next_hash_offset); if (next != 0 && next <= p) { - log_error("Hash chain has a cycle in hash entry %llu of %llu", - (unsigned long long) i, (unsigned long long) n); + log_error("Hash chain has a cycle in hash entry %"PRIu64" of %"PRIu64, + i, n); return -EBADMSG; } if (le64toh(o->data.hash) % n != i) { - log_error("Hash value mismatch in hash entry %llu of %llu", - (unsigned long long) i, (unsigned long long) n); + log_error("Hash value mismatch in hash entry %"PRIu64" of %"PRIu64, + i, n); return -EBADMSG; } @@ -548,8 +548,7 @@ static int verify_entry( h = le64toh(o->entry.items[i].hash); if (!contains_uint64(f->mmap, data_fd, n_data, q)) { - log_error("Invalid data object at entry %llu", - (unsigned long long) p); + log_error("Invalid data object at entry %"PRIu64, p); return -EBADMSG; } @@ -558,8 +557,7 @@ static int verify_entry( return r; if (le64toh(u->data.hash) != h) { - log_error("Hash mismatch for data object at entry %llu", - (unsigned long long) p); + log_error("Hash mismatch for data object at entry %"PRIu64, p); return -EBADMSG; } @@ -567,8 +565,7 @@ static int verify_entry( if (r < 0) return r; if (r == 0) { - log_error("Data object missing from hash at entry %llu", - (unsigned long long) p); + log_error("Data object missing from hash at entry %"PRIu64, p); return -EBADMSG; } } @@ -603,14 +600,12 @@ static int verify_entry_array( draw_progress(0x8000 + (0x3FFF * i / n), last_usec); if (a == 0) { - log_error("Array chain too short at %llu of %llu", - (unsigned long long) i, (unsigned long long) n); + log_error("Array chain too short at %"PRIu64" of %"PRIu64, i, n); return -EBADMSG; } if (!contains_uint64(f->mmap, entry_array_fd, n_entry_arrays, a)) { - log_error("Invalid array at %llu of %llu", - (unsigned long long) i, (unsigned long long) n); + log_error("Invalid array at %"PRIu64" of %"PRIu64, i, n); return -EBADMSG; } @@ -620,8 +615,7 @@ static int verify_entry_array( next = le64toh(o->entry_array.next_entry_array_offset); if (next != 0 && next <= a) { - log_error("Array chain has cycle at %llu of %llu", - (unsigned long long) i, (unsigned long long) n); + log_error("Array chain has cycle at %"PRIu64" of %"PRIu64, i, n); return -EBADMSG; } @@ -631,15 +625,15 @@ static int verify_entry_array( p = le64toh(o->entry_array.items[j]); if (p <= last) { - log_error("Entry array not sorted at %llu of %llu", - (unsigned long long) i, (unsigned long long) n); + log_error("Entry array not sorted at %"PRIu64" of %"PRIu64, + i, n); return -EBADMSG; } last = p; if (!contains_uint64(f->mmap, entry_fd, n_entries, p)) { - log_error("Invalid array entry at %llu of %llu", - (unsigned long long) i, (unsigned long long) n); + log_error("Invalid array entry at %"PRIu64" of %"PRIu64, + i, n); return -EBADMSG; } @@ -753,7 +747,7 @@ int journal_file_verify( r = journal_file_move_to_object(f, -1, p, &o); if (r < 0) { - log_error("Invalid object at %llu", (unsigned long long) p); + log_error("Invalid object at %"PRIu64, p); goto fail; } @@ -770,12 +764,12 @@ int journal_file_verify( r = journal_file_object_verify(f, o); if (r < 0) { - log_error("Invalid object contents at %llu", (unsigned long long) p); + log_error("Invalid object contents at %"PRIu64, p); goto fail; } if ((o->object.flags & OBJECT_COMPRESSED) && !JOURNAL_HEADER_COMPRESSED(f->header)) { - log_error("Compressed object in file without compression at %llu", (unsigned long long) p); + log_error("Compressed object in file without compression at %"PRIu64, p); r = -EBADMSG; goto fail; } @@ -796,7 +790,7 @@ int journal_file_verify( case OBJECT_ENTRY: if (JOURNAL_HEADER_SEALED(f->header) && n_tags <= 0) { - log_error("First entry before first tag at %llu", (unsigned long long) p); + log_error("First entry before first tag at %"PRIu64, p); r = -EBADMSG; goto fail; } @@ -806,21 +800,21 @@ int journal_file_verify( goto fail; if (le64toh(o->entry.realtime) < last_tag_realtime) { - log_error("Older entry after newer tag at %llu", (unsigned long long) p); + log_error("Older entry after newer tag at %"PRIu64, p); r = -EBADMSG; goto fail; } if (!entry_seqnum_set && le64toh(o->entry.seqnum) != le64toh(f->header->head_entry_seqnum)) { - log_error("Head entry sequence number incorrect at %llu", (unsigned long long) p); + log_error("Head entry sequence number incorrect at %"PRIu64, p); r = -EBADMSG; goto fail; } if (entry_seqnum_set && entry_seqnum >= le64toh(o->entry.seqnum)) { - log_error("Entry sequence number out of synchronization at %llu", (unsigned long long) p); + log_error("Entry sequence number out of synchronization at %"PRIu64, p); r = -EBADMSG; goto fail; } @@ -831,7 +825,7 @@ int journal_file_verify( if (entry_monotonic_set && sd_id128_equal(entry_boot_id, o->entry.boot_id) && entry_monotonic > le64toh(o->entry.monotonic)) { - log_error("Entry timestamp out of synchronization at %llu", (unsigned long long) p); + log_error("Entry timestamp out of synchronization at %"PRIu64, p); r = -EBADMSG; goto fail; } @@ -855,7 +849,7 @@ int journal_file_verify( case OBJECT_DATA_HASH_TABLE: if (n_data_hash_tables > 1) { - log_error("More than one data hash table at %llu", (unsigned long long) p); + log_error("More than one data hash table at %"PRIu64, p); r = -EBADMSG; goto fail; } @@ -872,7 +866,7 @@ int journal_file_verify( case OBJECT_FIELD_HASH_TABLE: if (n_field_hash_tables > 1) { - log_error("More than one field hash table at %llu", (unsigned long long) p); + log_error("More than one field hash table at %"PRIu64, p); r = -EBADMSG; goto fail; } @@ -894,7 +888,7 @@ int journal_file_verify( if (p == le64toh(f->header->entry_array_offset)) { if (found_main_entry_array) { - log_error("More than one main entry array at %llu", (unsigned long long) p); + log_error("More than one main entry array at %"PRIu64, p); r = -EBADMSG; goto fail; } @@ -907,19 +901,19 @@ int journal_file_verify( case OBJECT_TAG: if (!JOURNAL_HEADER_SEALED(f->header)) { - log_error("Tag object in file without sealing at %llu", (unsigned long long) p); + log_error("Tag object in file without sealing at %"PRIu64, p); r = -EBADMSG; goto fail; } if (le64toh(o->tag.seqnum) != n_tags + 1) { - log_error("Tag sequence number out of synchronization at %llu", (unsigned long long) p); + log_error("Tag sequence number out of synchronization at %"PRIu64, p); r = -EBADMSG; goto fail; } if (le64toh(o->tag.epoch) < last_epoch) { - log_error("Epoch sequence out of synchronization at %llu", (unsigned long long) p); + log_error("Epoch sequence out of synchronization at %"PRIu64, p); r = -EBADMSG; goto fail; } @@ -928,11 +922,11 @@ int journal_file_verify( if (f->seal) { uint64_t q, rt; - log_debug("Checking tag %llu..", (unsigned long long) le64toh(o->tag.seqnum)); + log_debug("Checking tag %"PRIu64"...", le64toh(o->tag.seqnum)); rt = f->fss_start_usec + o->tag.epoch * f->fss_interval_usec; if (entry_realtime_set && entry_realtime >= rt + f->fss_interval_usec) { - log_error("Tag/entry realtime timestamp out of synchronization at %llu", (unsigned long long) p); + log_error("Tag/entry realtime timestamp out of synchronization at %"PRIu64, p); r = -EBADMSG; goto fail; } @@ -975,7 +969,7 @@ int journal_file_verify( goto fail; if (memcmp(o->tag.tag, gcry_md_read(f->hmac, 0), TAG_LENGTH) != 0) { - log_error("Tag failed verification at %llu", (unsigned long long) p); + log_error("Tag failed verification at %"PRIu64, p); r = -EBADMSG; goto fail; } @@ -1138,11 +1132,11 @@ fail: if (show_progress) flush_progress(); - log_error("File corruption detected at %s:%llu (of %llu, %llu%%).", + log_error("File corruption detected at %s:%"PRIu64" (of %llu bytes, %"PRIu64"%%).", f->path, - (unsigned long long) p, + p, (unsigned long long) f->last_stat.st_size, - (unsigned long long) (100 * p / f->last_stat.st_size)); + 100 * p / f->last_stat.st_size); if (data_fd >= 0) { mmap_cache_close_fd(f->mmap, data_fd); diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c index 2f536320f8..5fd87b8154 100644 --- a/src/journal/journald-kmsg.c +++ b/src/journal/journald-kmsg.c @@ -151,7 +151,8 @@ static void dev_kmsg_record(Server *s, char *p, size_t l) { /* Did we lose any? */ if (serial > *s->kernel_seqnum) - server_driver_message(s, SD_MESSAGE_JOURNAL_MISSED, "Missed %llu kernel messages", (unsigned long long) serial - *s->kernel_seqnum - 1); + server_driver_message(s, SD_MESSAGE_JOURNAL_MISSED, "Missed %"PRIu64" kernel messages", + serial - *s->kernel_seqnum - 1); /* Make sure we never read this one again. Note that * we always store the next message serial we expect diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index 8b9a589cd3..8986763e4d 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -979,11 +979,11 @@ _public_ int sd_journal_get_cursor(sd_journal *j, char **cursor) { sd_id128_to_string(o->entry.boot_id, bid); if (asprintf(cursor, - "s=%s;i=%llx;b=%s;m=%llx;t=%llx;x=%llx", - sid, (unsigned long long) le64toh(o->entry.seqnum), - bid, (unsigned long long) le64toh(o->entry.monotonic), - (unsigned long long) le64toh(o->entry.realtime), - (unsigned long long) le64toh(o->entry.xor_hash)) < 0) + "s=%s;i=%"PRIx64";b=%s;m=%"PRIx64";t=%"PRIx64";x=%"PRIx64, + sid, le64toh(o->entry.seqnum), + bid, le64toh(o->entry.monotonic), + le64toh(o->entry.realtime), + le64toh(o->entry.xor_hash)) < 0) return -ENOMEM; return 0; diff --git a/src/journal/test-journal-verify.c b/src/journal/test-journal-verify.c index ad2e2d4c3b..6b7414a4b1 100644 --- a/src/journal/test-journal-verify.c +++ b/src/journal/test-journal-verify.c @@ -130,10 +130,10 @@ int main(int argc, char *argv[]) { for (p = 38448*8+0; p < ((uint64_t) st.st_size * 8); p ++) { bit_toggle("test.journal", p); - log_info("[ %llu+%llu]", (unsigned long long) p / 8, (unsigned long long) p % 8); + log_info("[ %"PRIu64"+%"PRIu64"]", p / 8, p % 8); if (raw_verify("test.journal", verification_key) >= 0) - log_notice(ANSI_HIGHLIGHT_RED_ON ">>>> %llu (bit %llu) can be toggled without detection." ANSI_HIGHLIGHT_OFF, (unsigned long long) p / 8, (unsigned long long) p % 8); + log_notice(ANSI_HIGHLIGHT_RED_ON ">>>> %"PRIu64" (bit %"PRIu64") can be toggled without detection." ANSI_HIGHLIGHT_OFF, p / 8, p % 8); bit_toggle("test.journal", p); } diff --git a/src/libudev/libudev-hwdb.c b/src/libudev/libudev-hwdb.c index 42ab6d9a6b..a56ad753e4 100644 --- a/src/libudev/libudev-hwdb.c +++ b/src/libudev/libudev-hwdb.c @@ -300,11 +300,11 @@ _public_ struct udev_hwdb *udev_hwdb_new(struct udev *udev) { } log_debug("=== trie on-disk ===\n"); - log_debug("tool version: %llu", (unsigned long long)le64toh(hwdb->head->tool_version)); - log_debug("file size: %8llu bytes\n", (unsigned long long)hwdb->st.st_size); - log_debug("header size %8llu bytes\n", (unsigned long long)le64toh(hwdb->head->header_size)); - log_debug("strings %8llu bytes\n", (unsigned long long)le64toh(hwdb->head->strings_len)); - log_debug("nodes %8llu bytes\n", (unsigned long long)le64toh(hwdb->head->nodes_len)); + log_debug("tool version: %"PRIu64, le64toh(hwdb->head->tool_version)); + log_debug("file size: %8llu bytes\n", (unsigned long long) hwdb->st.st_size); + log_debug("header size %8"PRIu64" bytes\n", le64toh(hwdb->head->header_size)); + log_debug("strings %8"PRIu64" bytes\n", le64toh(hwdb->head->strings_len)); + log_debug("nodes %8"PRIu64" bytes\n", le64toh(hwdb->head->nodes_len)); return hwdb; } diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 662273b07f..4fd3985811 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -108,9 +108,9 @@ void session_free(Session *s) { } int session_save(Session *s) { - FILE *f; + _cleanup_fclose_ FILE *f = NULL; + _cleanup_free_ char *temp_path = NULL; int r = 0; - char *temp_path; assert(s); @@ -145,69 +145,43 @@ int session_save(Session *s) { s->kill_processes); if (s->type >= 0) - fprintf(f, - "TYPE=%s\n", - session_type_to_string(s->type)); + fprintf(f, "TYPE=%s\n", session_type_to_string(s->type)); if (s->class >= 0) - fprintf(f, - "CLASS=%s\n", - session_class_to_string(s->class)); + fprintf(f, "CLASS=%s\n", session_class_to_string(s->class)); if (s->cgroup_path) - fprintf(f, - "CGROUP=%s\n", - s->cgroup_path); + fprintf(f, "CGROUP=%s\n", s->cgroup_path); if (s->fifo_path) - fprintf(f, - "FIFO=%s\n", - s->fifo_path); + fprintf(f, "FIFO=%s\n", s->fifo_path); if (s->seat) - fprintf(f, - "SEAT=%s\n", - s->seat->id); + fprintf(f, "SEAT=%s\n", s->seat->id); if (s->tty) - fprintf(f, - "TTY=%s\n", - s->tty); + fprintf(f, "TTY=%s\n", s->tty); if (s->display) - fprintf(f, - "DISPLAY=%s\n", - s->display); + fprintf(f, "DISPLAY=%s\n", s->display); if (s->remote_host) - fprintf(f, - "REMOTE_HOST=%s\n", - s->remote_host); + fprintf(f, "REMOTE_HOST=%s\n", s->remote_host); if (s->remote_user) - fprintf(f, - "REMOTE_USER=%s\n", - s->remote_user); + fprintf(f, "REMOTE_USER=%s\n", s->remote_user); if (s->service) - fprintf(f, - "SERVICE=%s\n", - s->service); + fprintf(f, "SERVICE=%s\n", s->service); if (s->seat && seat_can_multi_session(s->seat)) - fprintf(f, - "VTNR=%i\n", - s->vtnr); + fprintf(f, "VTNR=%i\n", s->vtnr); if (s->leader > 0) - fprintf(f, - "LEADER=%lu\n", - (unsigned long) s->leader); + fprintf(f, "LEADER=%lu\n", (unsigned long) s->leader); if (s->audit_id > 0) - fprintf(f, - "AUDIT=%llu\n", - (unsigned long long) s->audit_id); + fprintf(f, "AUDIT=%"PRIu32"\n", s->audit_id); fflush(f); @@ -217,9 +191,6 @@ int session_save(Session *s) { unlink(temp_path); } - fclose(f); - free(temp_path); - finish: if (r < 0) log_error("Failed to save session data for %s: %s", s->id, strerror(-r)); -- cgit v1.2.1 From 2765b7bb6924e2c26c7bf60bd692a4bc121d9582 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 5 Jun 2013 18:40:44 -0400 Subject: journalctl: print proper IDs with --header The same buffer was used for two different IDs, messing up the output. --- src/journal/journal-file.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index 3cb8f79947..7f855743b8 100644 --- a/src/journal/journal-file.c +++ b/src/journal/journal-file.c @@ -2271,7 +2271,7 @@ fail: } void journal_file_print_header(JournalFile *f) { - char a[33], b[33], c[33]; + char a[33], b[33], c[33], d[33]; char x[FORMAT_TIMESTAMP_MAX], y[FORMAT_TIMESTAMP_MAX]; struct stat st; char bytes[FORMAT_BYTES_MAX]; @@ -2301,7 +2301,7 @@ void journal_file_print_header(JournalFile *f) { sd_id128_to_string(f->header->file_id, a), sd_id128_to_string(f->header->machine_id, b), sd_id128_to_string(f->header->boot_id, c), - sd_id128_to_string(f->header->seqnum_id, c), + sd_id128_to_string(f->header->seqnum_id, d), f->header->state == STATE_OFFLINE ? "OFFLINE" : f->header->state == STATE_ONLINE ? "ONLINE" : f->header->state == STATE_ARCHIVED ? "ARCHIVED" : "UNKNOWN", -- cgit v1.2.1 From ed375bebf46c1251f4baa170b39ee93761dbdb19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 5 Jun 2013 19:15:43 -0400 Subject: journalctl: print monotonic timestamp in --header --- src/journal/journal-file.c | 7 ++++--- src/journal/journald-server.c | 19 +++---------------- 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index 7f855743b8..ca217f93fe 100644 --- a/src/journal/journal-file.c +++ b/src/journal/journal-file.c @@ -2272,7 +2272,7 @@ fail: void journal_file_print_header(JournalFile *f) { char a[33], b[33], c[33], d[33]; - char x[FORMAT_TIMESTAMP_MAX], y[FORMAT_TIMESTAMP_MAX]; + char x[FORMAT_TIMESTAMP_MAX], y[FORMAT_TIMESTAMP_MAX], z[FORMAT_TIMESTAMP_MAX]; struct stat st; char bytes[FORMAT_BYTES_MAX]; @@ -2295,6 +2295,7 @@ void journal_file_print_header(JournalFile *f) { "Tail Sequential Number: %"PRIu64"\n" "Head Realtime Timestamp: %s\n" "Tail Realtime Timestamp: %s\n" + "Tail Monotonic Timestamp: %s\n" "Objects: %"PRIu64"\n" "Entry Objects: %"PRIu64"\n", f->path, @@ -2318,6 +2319,7 @@ void journal_file_print_header(JournalFile *f) { le64toh(f->header->tail_entry_seqnum), format_timestamp(x, sizeof(x), le64toh(f->header->head_entry_realtime)), format_timestamp(y, sizeof(y), le64toh(f->header->tail_entry_realtime)), + format_timespan(z, sizeof(z), le64toh(f->header->tail_entry_monotonic), USEC_PER_MSEC), le64toh(f->header->n_objects), le64toh(f->header->n_entries)); @@ -2596,7 +2598,7 @@ int journal_file_open_reliably( int r; size_t l; - char *p; + _cleanup_free_ char *p = NULL; r = journal_file_open(fname, flags, mode, compress, seal, metrics, mmap_cache, template, ret); @@ -2627,7 +2629,6 @@ int journal_file_open_reliably( return -ENOMEM; r = rename(fname, p); - free(p); if (r < 0) return -errno; diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 0bf557c809..6c99f4b690 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -245,7 +245,7 @@ finish: } static JournalFile* find_journal(Server *s, uid_t uid) { - char *p; + _cleanup_free_ char *p = NULL; int r; JournalFile *f; sd_id128_t machine; @@ -283,8 +283,6 @@ static JournalFile* find_journal(Server *s, uid_t uid) { } r = journal_file_open_reliably(p, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, s->system_journal, &f); - free(p); - if (r < 0) return s->system_journal; @@ -372,7 +370,6 @@ void server_sync(Server *s) { } void server_vacuum(Server *s) { - char *p; char ids[33]; sd_id128_t machine; int r; @@ -390,29 +387,19 @@ void server_vacuum(Server *s) { sd_id128_to_string(machine, ids); if (s->system_journal) { - p = strappend("/var/log/journal/", ids); - if (!p) { - log_oom(); - return; - } + char *p = strappenda("/var/log/journal/", ids); r = journal_directory_vacuum(p, s->system_metrics.max_use, s->system_metrics.keep_free, s->max_retention_usec, &s->oldest_file_usec); if (r < 0 && r != -ENOENT) log_error("Failed to vacuum %s: %s", p, strerror(-r)); - free(p); } if (s->runtime_journal) { - p = strappend("/run/log/journal/", ids); - if (!p) { - log_oom(); - return; - } + char *p = strappenda("/run/log/journal/", ids); r = journal_directory_vacuum(p, s->runtime_metrics.max_use, s->runtime_metrics.keep_free, s->max_retention_usec, &s->oldest_file_usec); if (r < 0 && r != -ENOENT) log_error("Failed to vacuum %s: %s", p, strerror(-r)); - free(p); } s->cached_available_space_timestamp = 0; -- cgit v1.2.1 From 6eb7a9a0010d035e5bdbbf70227088ce02b2120e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 5 Jun 2013 19:17:56 -0400 Subject: tests: add test for empty journal files The headers are currently not printed properly: some "(null)"s appear. --- TODO | 2 ++ src/journal/test-journal.c | 60 ++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/TODO b/TODO index fc8044b434..0dd19a05c2 100644 --- a/TODO +++ b/TODO @@ -11,6 +11,8 @@ Bugfixes: * properly handle .mount unit state tracking when two mount points are stacked one on top of another on the exact same mount point. +* fix --header to files without entries (see test-journal output). + Fedora 19: * external: maybe it is time to patch procps so that "ps" links to diff --git a/src/journal/test-journal.c b/src/journal/test-journal.c index f4dc52cd81..534fd28fa6 100644 --- a/src/journal/test-journal.c +++ b/src/journal/test-journal.c @@ -29,7 +29,9 @@ #include "journal-authenticate.h" #include "journal-vacuum.h" -int main(int argc, char *argv[]) { +static bool arg_keep = false; + +static void test_non_empty(void) { dual_timestamp ts; JournalFile *f; struct iovec iovec; @@ -119,11 +121,61 @@ int main(int argc, char *argv[]) { journal_file_close(f); - journal_directory_vacuum(".", 3000000, 0, 0, NULL); + log_info("Done..."); + + if (arg_keep) + log_info("Not removing %s", t); + else { + journal_directory_vacuum(".", 3000000, 0, 0, NULL); + + assert_se(rm_rf_dangerous(t, false, true, false) >= 0); + } + + puts("------------------------------------------------------------"); +} + +static void test_empty(void) { + JournalFile *f1, *f2, *f3, *f4; + char t[] = "/tmp/journal-XXXXXX"; + + log_set_max_level(LOG_DEBUG); - log_error("Exiting..."); + assert_se(mkdtemp(t)); + assert_se(chdir(t) >= 0); + + assert_se(journal_file_open("test.journal", O_RDWR|O_CREAT, 0666, false, false, NULL, NULL, NULL, &f1) == 0); + + assert_se(journal_file_open("test-compress.journal", O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, &f2) == 0); + + assert_se(journal_file_open("test-seal.journal", O_RDWR|O_CREAT, 0666, false, true, NULL, NULL, NULL, &f3) == 0); + + assert_se(journal_file_open("test-seal-compress.journal", O_RDWR|O_CREAT, 0666, true, true, NULL, NULL, NULL, &f4) == 0); + + journal_file_print_header(f1); + puts(""); + journal_file_print_header(f2); + puts(""); + journal_file_print_header(f3); + puts(""); + journal_file_print_header(f4); + puts(""); + + log_info("Done..."); + + if (arg_keep) + log_info("Not removing %s", t); + else { + journal_directory_vacuum(".", 3000000, 0, 0, NULL); + + assert_se(rm_rf_dangerous(t, false, true, false) >= 0); + } +} + +int main(int argc, char *argv[]) { + arg_keep = argc > 1; - assert_se(rm_rf_dangerous(t, false, true, false) >= 0); + test_non_empty(); + test_empty(); return 0; } -- cgit v1.2.1 From 5302ebe15ff3a11eceb75e095e5a09d2a676de2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 5 Jun 2013 19:39:26 -0400 Subject: journal: add sd_journal_open_files This allows the caller to explicitly specify which journal files should be opened. The same functionality could be achieved before by creating a directory and playing around with symlinks. It is useful to debug stuff and explore the journal, and has been requested before. Waiting is supported, the journal will notice modifications on the files supplied when opening the journal, but will not add any new files. --- Makefile-man.am | 5 ++ man/sd_journal_open.xml | 23 +++++++- src/journal/journal-internal.h | 1 + src/journal/libsystemd-journal.sym | 5 ++ src/journal/sd-journal.c | 117 +++++++++++++++++++++++++++++++------ src/systemd/sd-journal.h | 1 + 6 files changed, 130 insertions(+), 22 deletions(-) diff --git a/Makefile-man.am b/Makefile-man.am index a31427e9b9..807ad783fb 100644 --- a/Makefile-man.am +++ b/Makefile-man.am @@ -148,6 +148,7 @@ MANPAGES_ALIAS += \ man/sd_journal_get_timeout.3 \ man/sd_journal_next_skip.3 \ man/sd_journal_open_directory.3 \ + man/sd_journal_open_files.3 \ man/sd_journal_perror.3 \ man/sd_journal_previous.3 \ man/sd_journal_previous_skip.3 \ @@ -248,6 +249,7 @@ man/sd_journal_get_monotonic_usec.3: man/sd_journal_get_realtime_usec.3 man/sd_journal_get_timeout.3: man/sd_journal_get_fd.3 man/sd_journal_next_skip.3: man/sd_journal_next.3 man/sd_journal_open_directory.3: man/sd_journal_open.3 +man/sd_journal_open_files.3: man/sd_journal_open.3 man/sd_journal_perror.3: man/sd_journal_print.3 man/sd_journal_previous.3: man/sd_journal_next.3 man/sd_journal_previous_skip.3: man/sd_journal_next.3 @@ -452,6 +454,9 @@ man/sd_journal_next_skip.html: man/sd_journal_next.html man/sd_journal_open_directory.html: man/sd_journal_open.html $(html-alias) +man/sd_journal_open_files.html: man/sd_journal_open.html + $(html-alias) + man/sd_journal_perror.html: man/sd_journal_print.html $(html-alias) diff --git a/man/sd_journal_open.xml b/man/sd_journal_open.xml index dd2f32d81a..4ac94c4ce3 100644 --- a/man/sd_journal_open.xml +++ b/man/sd_journal_open.xml @@ -45,6 +45,7 @@ sd_journal_open sd_journal_open_directory + sd_journal_open_files sd_journal_close sd_journal SD_JOURNAL_LOCAL_ONLY @@ -71,6 +72,13 @@ int flags + + int sd_journal_open_files + sd_journal** ret + const char** paths + int flags + + void sd_journal_close sd_journal* j @@ -111,6 +119,14 @@ flags argument, but it must be passed as 0 as no flags are currently understood for this call. + sd_journal_open_files() + is similar to sd_journal_open() + but takes a NULL-terminated list + of file paths to open. All files will be opened and + interleaved automatically. This call also takes a + flags argument, but it must be passed as 0 as no flags + are currently understood for this call. + sd_journal_close() will close the journal context allocated with sd_journal_open() or @@ -188,9 +204,10 @@ sd_journal_open_directory() was added in systemd-187. - SD_JOURNAL_SYSTEM and - SD_JOURNAL_CURRENT_USER were added - in systemd-205. + SD_JOURNAL_SYSTEM, + SD_JOURNAL_CURRENT_USER, + and sd_journal_open_files() + were added in systemd-205. SD_JOURNAL_SYSTEM_ONLY was deprecated. diff --git a/src/journal/journal-internal.h b/src/journal/journal-internal.h index f576a0073d..5b717f86f7 100644 --- a/src/journal/journal-internal.h +++ b/src/journal/journal-internal.h @@ -123,6 +123,7 @@ struct sd_journal { uint64_t unique_offset; bool on_network; + bool no_new_files; size_t data_threshold; diff --git a/src/journal/libsystemd-journal.sym b/src/journal/libsystemd-journal.sym index 449f37c4da..4eb15910d2 100644 --- a/src/journal/libsystemd-journal.sym +++ b/src/journal/libsystemd-journal.sym @@ -104,3 +104,8 @@ LIBSYSTEMD_JOURNAL_202 { global: sd_journal_add_conjunction; } LIBSYSTEMD_JOURNAL_201; + +LIBSYSTEMD_JOURNAL_205 { +global: + sd_journal_open_files; +} LIBSYSTEMD_JOURNAL_202; diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index 8986763e4d..3aa9ed4b32 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -33,6 +33,7 @@ #include "journal-file.h" #include "hashmap.h" #include "list.h" +#include "strv.h" #include "path-util.h" #include "lookup3.h" #include "compress.h" @@ -1278,37 +1279,24 @@ static bool file_type_wanted(int flags, const char *filename) { return false; } -static int add_file(sd_journal *j, const char *prefix, const char *filename) { - _cleanup_free_ char *path = NULL; - int r; +static int add_any_file(sd_journal *j, const char *path) { JournalFile *f; + int r; assert(j); - assert(prefix); - assert(filename); - - if (!file_type_wanted(j->flags, filename)) - return 0; - - path = strjoin(prefix, "/", filename, NULL); - if (!path) - return -ENOMEM; + assert(path); if (hashmap_get(j->files, path)) return 0; if (hashmap_size(j->files) >= JOURNAL_FILES_MAX) { - log_debug("Too many open journal files, not adding %s, ignoring.", path); + log_warning("Too many open journal files, not adding %s.", path); return set_put_error(j, -ETOOMANYREFS); } r = journal_file_open(path, O_RDONLY, 0, false, false, NULL, j->mmap, NULL, &f); - if (r < 0) { - if (errno == ENOENT) - return 0; - + if (r < 0) return r; - } /* journal_file_dump(f); */ @@ -1327,6 +1315,28 @@ static int add_file(sd_journal *j, const char *prefix, const char *filename) { return 0; } +static int add_file(sd_journal *j, const char *prefix, const char *filename) { + _cleanup_free_ char *path = NULL; + int r; + + assert(j); + assert(prefix); + assert(filename); + + if (j->no_new_files || + !file_type_wanted(j->flags, filename)) + return 0; + + path = strjoin(prefix, "/", filename, NULL); + if (!path) + return -ENOMEM; + + r = add_any_file(j, path); + if (r == -ENOENT) + return 0; + return 0; +} + static int remove_file(sd_journal *j, const char *prefix, const char *filename) { char *path; JournalFile *f; @@ -1507,6 +1517,9 @@ static int add_root_directory(sd_journal *j, const char *p) { inotify_rm_watch(j->inotify_fd, m->wd); } + if (j->no_new_files) + return 0; + for (;;) { struct dirent *de; union dirent_storage buf; @@ -1587,6 +1600,36 @@ static int add_search_paths(sd_journal *j) { return 0; } +static int add_current_paths(sd_journal *j) { + Iterator i; + JournalFile *f; + + assert(j); + assert(j->no_new_files); + + /* Simply adds all directories for files we have open as + * "root" directories. We don't expect errors here, so we + * treat them as fatal. */ + + HASHMAP_FOREACH(f, j->files, i) { + int r; + _cleanup_free_ char *dir; + + dir = dirname_malloc(f->path); + if (!dir) + return -ENOMEM; + + r = add_root_directory(j, dir); + if (r < 0) { + set_put_error(j, r); + return r; + } + } + + return 0; +} + + static int allocate_inotify(sd_journal *j) { assert(j); @@ -1697,6 +1740,40 @@ fail: return r; } +_public_ int sd_journal_open_files(sd_journal **ret, const char **paths, int flags) { + sd_journal *j; + const char **path; + int r; + + if (!ret) + return -EINVAL; + + if (flags != 0) + return -EINVAL; + + j = journal_new(flags, NULL); + if (!j) + return -ENOMEM; + + STRV_FOREACH(path, paths) { + r = add_any_file(j, *path); + if (r < 0) { + log_error("Failed to open %s: %s", *path, strerror(-r)); + goto fail; + } + } + + j->no_new_files = true; + + *ret = j; + return 0; + +fail: + sd_journal_close(j); + + return r; +} + _public_ void sd_journal_close(sd_journal *j) { Directory *d; JournalFile *f; @@ -2017,7 +2094,9 @@ _public_ int sd_journal_get_fd(sd_journal *j) { /* Iterate through all dirs again, to add them to the * inotify */ - if (j->path) + if (j->no_new_files) + r = add_current_paths(j); + else if (j->path) r = add_root_directory(j, j->path); else r = add_search_paths(j); diff --git a/src/systemd/sd-journal.h b/src/systemd/sd-journal.h index cf105cde72..72ea328b28 100644 --- a/src/systemd/sd-journal.h +++ b/src/systemd/sd-journal.h @@ -100,6 +100,7 @@ enum { int sd_journal_open(sd_journal **ret, int flags); int sd_journal_open_directory(sd_journal **ret, const char *path, int flags); +int sd_journal_open_files(sd_journal **ret, const char **paths, int flags); void sd_journal_close(sd_journal *j); int sd_journal_previous(sd_journal *j); -- cgit v1.2.1 From 8d98da3f1107529d5ba49aea1fa285f7264b7cba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 5 Jun 2013 19:30:17 -0400 Subject: journalctl: allow the user to specify the file(s) to use This is useful for debugging and feels pretty natural. For example answering the question "is this big .journal file worth keeping?" is made easier. --- man/journalctl.xml | 32 +++++++++++++++++++++++--------- src/journal/journalctl.c | 35 ++++++++++++++++++++++++++++++----- src/shared/util.c | 34 ++++++++++++++++++++++++++++------ src/shared/util.h | 1 + 4 files changed, 82 insertions(+), 20 deletions(-) diff --git a/man/journalctl.xml b/man/journalctl.xml index 66100816ae..f399868178 100644 --- a/man/journalctl.xml +++ b/man/journalctl.xml @@ -462,15 +462,29 @@ - - - - Takes a - directory path as argument. If - specified journalctl will operate on the - specified journal directory instead of - the default runtime and system journal - paths. + + + + Takes a directory path + as argument. If specified journalctl + will operate on the specified journal + directory + DIR instead + of the default runtime and system + journal paths. + + + + + + Takes a file glob as + argument. If specified journalctl will + operate on the specified journal files + matching GLOB + instead of the default runtime and + system journal paths. May be specified + multiple times, in which case files will + be suitably interleaved. diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index af0f4ba3c8..1a441dd0d6 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -74,6 +74,7 @@ static bool arg_this_boot = false; static bool arg_dmesg = false; static const char *arg_cursor = NULL; static const char *arg_directory = NULL; +static char **arg_file = NULL; static int arg_priorities = 0xFF; static const char *arg_verify_key = NULL; #ifdef HAVE_GCRYPT @@ -130,6 +131,7 @@ static int help(void) { " --no-pager Do not pipe output into a pager\n" " -m --merge Show entries from all available journals\n" " -D --directory=PATH Show journal files from directory\n" + " --file=PATH Show journal file\n" " --root=ROOT Operate on catalog files underneath the root ROOT\n" #ifdef HAVE_GCRYPT " --interval=TIME Time interval for changing the FSS sealing key\n" @@ -167,6 +169,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_HEADER, ARG_FULL, ARG_SETUP_KEYS, + ARG_FILE, ARG_INTERVAL, ARG_VERIFY, ARG_VERIFY_KEY, @@ -198,6 +201,7 @@ static int parse_argv(int argc, char *argv[]) { { "system", no_argument, NULL, ARG_SYSTEM }, { "user", no_argument, NULL, ARG_USER }, { "directory", required_argument, NULL, 'D' }, + { "file", required_argument, NULL, ARG_FILE }, { "root", required_argument, NULL, ARG_ROOT }, { "header", no_argument, NULL, ARG_HEADER }, { "priority", required_argument, NULL, 'p' }, @@ -343,6 +347,14 @@ static int parse_argv(int argc, char *argv[]) { arg_directory = optarg; break; + case ARG_FILE: + r = glob_extend(&arg_file, optarg); + if (r < 0) { + log_error("Failed to add paths: %s", strerror(-r)); + return r; + }; + break; + case ARG_ROOT: arg_root = optarg; break; @@ -506,6 +518,11 @@ static int parse_argv(int argc, char *argv[]) { if (arg_follow && !arg_no_tail && arg_lines < 0) arg_lines = 10; + if (arg_directory && arg_file) { + log_error("Please specify either -D/--directory= or --file=, not both."); + return -EINVAL; + } + if (arg_since_set && arg_until_set && arg_since > arg_until) { log_error("--since= must be before --until=."); return -EINVAL; @@ -1110,10 +1127,14 @@ int main(int argc, char *argv[]) { if (arg_directory) r = sd_journal_open_directory(&j, arg_directory, arg_journal_type); + else if (arg_file) + r = sd_journal_open_files(&j, (const char**) arg_file, 0); else r = sd_journal_open(&j, !arg_merge*SD_JOURNAL_LOCAL_ONLY + arg_journal_type); if (r < 0) { - log_error("Failed to open journal: %s", strerror(-r)); + log_error("Failed to open %s: %s", + arg_directory ? arg_directory : arg_file ? "files" : "journal", + strerror(-r)); return EXIT_FAILURE; } @@ -1167,10 +1188,7 @@ int main(int argc, char *argv[]) { if (r < 0) return EXIT_FAILURE; - /* Opening the fd now means the first sd_journal_wait() will actually wait */ - r = sd_journal_get_fd(j); - if (r < 0) - return EXIT_FAILURE; + log_debug("Journal filter: %s", j->level0 ? journal_make_match_string(j) : "none"); if (arg_field) { const void *data; @@ -1206,6 +1224,13 @@ int main(int argc, char *argv[]) { return EXIT_SUCCESS; } + /* Opening the fd now means the first sd_journal_wait() will actually wait */ + if (arg_follow) { + r = sd_journal_get_fd(j); + if (r < 0) + return EXIT_FAILURE; + } + if (arg_cursor) { r = sd_journal_seek_cursor(j, arg_cursor); if (r < 0) { diff --git a/src/shared/util.c b/src/shared/util.c index 17928ec36e..04811ff26b 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -4353,7 +4353,7 @@ int in_group(const char *name) { int glob_exists(const char *path) { _cleanup_globfree_ glob_t g = {}; - int r, k; + int k; assert(path); @@ -4361,15 +4361,37 @@ int glob_exists(const char *path) { k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g); if (k == GLOB_NOMATCH) - r = 0; + return 0; else if (k == GLOB_NOSPACE) - r = -ENOMEM; + return -ENOMEM; else if (k == 0) - r = !strv_isempty(g.gl_pathv); + return !strv_isempty(g.gl_pathv); else - r = errno ? -errno : -EIO; + return errno ? -errno : -EIO; +} - return r; +int glob_extend(char ***strv, const char *path) { + _cleanup_globfree_ glob_t g = {}; + int k; + char **p; + + errno = 0; + k = glob(optarg, GLOB_NOSORT|GLOB_BRACE, NULL, &g); + + if (k == GLOB_NOMATCH) + return -ENOENT; + else if (k == GLOB_NOSPACE) + return -ENOMEM; + else if (k != 0 || strv_isempty(g.gl_pathv)) + return errno ? -errno : -EIO; + + STRV_FOREACH(p, g.gl_pathv) { + k = strv_extend(strv, *p); + if (k < 0) + break; + } + + return k; } int dirent_ensure_type(DIR *d, struct dirent *de) { diff --git a/src/shared/util.h b/src/shared/util.h index e6f9312e95..ddb21b4a9c 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -439,6 +439,7 @@ char* uid_to_name(uid_t uid); char* gid_to_name(gid_t gid); int glob_exists(const char *path); +int glob_extend(char ***strv, const char *path); int dirent_ensure_type(DIR *d, struct dirent *de); -- cgit v1.2.1 From 87011c25d96e9fbcd8a465ba758fa037c7d08203 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 6 Jun 2013 22:28:05 -0400 Subject: journal: remember last direction of search and keep offset cache The fields in JournalFile are moved around to avoid wasting 7 bytes because of alignment. --- TODO | 3 --- src/journal/journal-file.h | 18 +++++++++++------- src/journal/sd-journal.c | 11 +++++------ 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/TODO b/TODO index 0dd19a05c2..1dc585cca8 100644 --- a/TODO +++ b/TODO @@ -77,9 +77,6 @@ Features: * investigate endianess issues of UUID vs. GUID -* see if we can fix https://bugs.freedesktop.org/show_bug.cgi?id=63672 - without dropping the location cache entirely. - * dbus: when a unit failed to load (i.e. is in UNIT_ERROR state), we should be able to safely try another attempt when the bus call LoadUnit() is invoked. diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h index 7b1cd42854..5cc2c2d28d 100644 --- a/src/journal/journal-file.h +++ b/src/journal/journal-file.h @@ -42,10 +42,14 @@ typedef struct JournalMetrics { uint64_t keep_free; } JournalMetrics; +typedef enum direction { + DIRECTION_UP, + DIRECTION_DOWN +} direction_t; + typedef struct JournalFile { int fd; - char *path; - struct stat last_stat; + mode_t mode; int flags; @@ -56,6 +60,11 @@ typedef struct JournalFile { bool tail_entry_monotonic_valid; + direction_t last_direction; + + char *path; + struct stat last_stat; + Header *header; HashItem *data_hash_table; HashItem *field_hash_table; @@ -90,11 +99,6 @@ typedef struct JournalFile { #endif } JournalFile; -typedef enum direction { - DIRECTION_UP, - DIRECTION_DOWN -} direction_t; - int journal_file_open( const char *fname, int flags, diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index 3aa9ed4b32..4c4cc2d21c 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -102,7 +102,8 @@ static void init_location(Location *l, LocationType type, JournalFile *f, Object l->seqnum_set = l->realtime_set = l->monotonic_set = l->xor_hash_set = true; } -static void set_location(sd_journal *j, LocationType type, JournalFile *f, Object *o, uint64_t offset) { +static void set_location(sd_journal *j, LocationType type, JournalFile *f, Object *o, + direction_t direction, uint64_t offset) { assert(j); assert(type == LOCATION_DISCRETE || type == LOCATION_SEEK); assert(f); @@ -110,12 +111,10 @@ static void set_location(sd_journal *j, LocationType type, JournalFile *f, Objec init_location(&j->current_location, type, f, o); - if (j->current_file) - j->current_file->current_offset = 0; - j->current_file = f; j->current_field = 0; + f->last_direction = direction; f->current_offset = offset; } @@ -811,7 +810,7 @@ static int next_beyond_location(sd_journal *j, JournalFile *f, direction_t direc assert(j); assert(f); - if (f->current_offset > 0) { + if (f->last_direction == direction && f->current_offset > 0) { cp = f->current_offset; r = journal_file_move_to_object(f, OBJECT_ENTRY, cp, &c); @@ -908,7 +907,7 @@ static int real_journal_next(sd_journal *j, direction_t direction) { if (r < 0) return r; - set_location(j, LOCATION_DISCRETE, new_file, o, new_offset); + set_location(j, LOCATION_DISCRETE, new_file, o, direction, new_offset); return 1; } -- cgit v1.2.1 From bc3029268ca0077f2e176724d7d124cec4265575 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 6 Jun 2013 23:30:46 -0400 Subject: journal: change direction tests to use the same convention (cp np) The order was different in various places, which makes it harder to read to code. Also consistently use ternany for all direction checks. Remove one free(NULL). --- src/journal/sd-journal.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index 4c4cc2d21c..1e70739295 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -163,7 +163,7 @@ static bool same_field(const void *_a, size_t s, const void *_b, size_t t) { return true; } - return true; + assert_not_reached("\"=\" not found"); } static Match *match_new(Match *p, MatchType t) { @@ -371,10 +371,8 @@ static char *match_make_string(Match *m) { p = k; enclose = true; - } else { - free(p); + } else p = t; - } } if (enclose) { @@ -587,11 +585,14 @@ static int next_for_match( if (r < 0) return r; else if (r > 0) { - if (np == 0 || (direction == DIRECTION_DOWN ? np > cp : np < cp)) + if (np == 0 || (direction == DIRECTION_DOWN ? cp < np : cp > np)) np = cp; } } + if (np == 0) + return 0; + } else if (m->type == MATCH_AND_TERM) { Match *i, *last_moved; @@ -624,8 +625,7 @@ static int next_for_match( } } - if (np == 0) - return 0; + assert(np > 0); r = journal_file_move_to_object(f, OBJECT_ENTRY, np, &n); if (r < 0) @@ -730,7 +730,7 @@ static int find_location_for_match( if (r <= 0) return r; - if (np == 0 || (direction == DIRECTION_DOWN ? np < cp : np > cp)) + if (np == 0 || (direction == DIRECTION_DOWN ? cp > np : cp < np)) np = cp; } @@ -826,7 +826,7 @@ static int next_beyond_location(sd_journal *j, JournalFile *f, direction_t direc return r; } - /* OK, we found the spot, now let's advance until to an entry + /* OK, we found the spot, now let's advance until an entry * that is actually different from what we were previously * looking at. This is necessary to handle entries which exist * in two (or more) journal files, and which shall all be @@ -888,10 +888,7 @@ static int real_journal_next(sd_journal *j, direction_t direction) { k = compare_entry_order(f, o, new_file, new_offset); - if (direction == DIRECTION_DOWN) - found = k < 0; - else - found = k > 0; + found = direction == DIRECTION_DOWN ? k < 0 : k > 0; } if (found) { -- cgit v1.2.1 From 7a050b54b7c78717d5efb2e380623ccad2a70148 Mon Sep 17 00:00:00 2001 From: Marius Vollmer Date: Fri, 7 Jun 2013 00:50:21 -0400 Subject: tests: add testcase for skipping-entries-on-direction-change-bug This test case failed until a3e6f050de8. Taken from https://bugs.freedesktop.org/show_bug.cgi?id=65255. --- Makefile.am | 9 ++ src/journal/test-journal-interleaving.c | 198 ++++++++++++++++++++++++++++++++ 2 files changed, 207 insertions(+) create mode 100644 src/journal/test-journal-interleaving.c diff --git a/Makefile.am b/Makefile.am index 70da1e4a2c..28ae7edea0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2781,6 +2781,14 @@ test_journal_verify_LDADD = \ libsystemd-journal-internal.la \ libsystemd-id128-internal.la +test_journal_interleaving_SOURCES = \ + src/journal/test-journal-interleaving.c + +test_journal_interleaving_LDADD = \ + libsystemd-shared.la \ + libsystemd-journal-internal.la \ + libsystemd-id128-internal.la + test_mmap_cache_SOURCES = \ src/journal/test-mmap-cache.c @@ -2956,6 +2964,7 @@ tests += \ test-journal-match \ test-journal-stream \ test-journal-verify \ + test-journal-interleaving \ test-mmap-cache \ test-catalog diff --git a/src/journal/test-journal-interleaving.c b/src/journal/test-journal-interleaving.c new file mode 100644 index 0000000000..c83a1ea981 --- /dev/null +++ b/src/journal/test-journal-interleaving.c @@ -0,0 +1,198 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Marius Vollmer + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include + +#include "journal-file.h" +#include "journal-internal.h" +#include "util.h" +#include "log.h" + +/* This program tests skipping around in a multi-file journal. + */ + +static void log_assert_errno(const char *text, int eno, const char *file, int line, const char *func) { + log_meta(LOG_CRIT, file, line, func, + "'%s' failed at %s:%u (%s): %s.", + text, file, line, func, strerror(eno)); + abort(); +} + +#define assert_ret(expr) \ + do { \ + int _r_ = (expr); \ + if (_unlikely_(_r_ < 0)) \ + log_assert_errno(#expr, -_r_, __FILE__, __LINE__, __PRETTY_FUNCTION__); \ + } while (false) + +static JournalFile *test_open (const char *name) +{ + JournalFile *f; + assert_ret(journal_file_open(name, O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, &f)); + return f; +} + +static void test_close (JournalFile *f) +{ + journal_file_close (f); +} + +static void test_append_number(JournalFile *f, int n) +{ + char *p; + dual_timestamp ts; + struct iovec iovec[1]; + + dual_timestamp_get(&ts); + + assert_se(asprintf(&p, "NUMBER=%d", n) >= 0); + iovec[0].iov_base = p; + iovec[0].iov_len = strlen(p); + assert_ret(journal_file_append_entry(f, &ts, iovec, 1, NULL, NULL, NULL)); + free (p); +} + +static void test_check_number (sd_journal *j, int n) +{ + const void *d; + char *k; + size_t l; + int x; + + assert_ret(sd_journal_get_data(j, "NUMBER", &d, &l)); + assert_se(k = strndup(d, l)); + printf("%s\n", k); + + assert_se(safe_atoi(k + 7, &x) >= 0); + assert_se(n == x); +} + +static void test_check_numbers_down (sd_journal *j, int count) +{ + for (int i = 1; i <= count; i++) { + int r; + test_check_number(j, i); + assert_ret(r = sd_journal_next(j)); + if (i == count) + assert_se(r == 0); + else + assert_se(r == 1); + } + +} + +static void test_check_numbers_up (sd_journal *j, int count) +{ + for (int i = count; i >= 1; i--) { + int r; + test_check_number(j, i); + assert_ret(r = sd_journal_previous(j)); + if (i == 1) + assert_se(r == 0); + else + assert_se(r == 1); + } + +} + +static void setup_sequential(void) { + JournalFile *one, *two; + one = test_open("one.journal"); + two = test_open("two.journal"); + test_append_number(one, 1); + test_append_number(one, 2); + test_append_number(two, 3); + test_append_number(two, 4); + test_close(one); + test_close(two); +} + +static void setup_interleaved(void) { + JournalFile *one, *two; + one = test_open("one.journal"); + two = test_open("two.journal"); + test_append_number(one, 1); + test_append_number(two, 2); + test_append_number(one, 3); + test_append_number(two, 4); + test_close(one); + test_close(two); +} + +static void test_skip(void (*setup)(void)) +{ + char t[] = "/tmp/journal-skip-XXXXXX"; + sd_journal *j; + int r; + + log_set_max_level(LOG_DEBUG); + + assert_se(mkdtemp(t)); + assert_se(chdir(t) >= 0); + + setup(); + + /* Seek to head, iterate down. + */ + assert_ret(sd_journal_open_directory(&j, t, 0)); + assert_ret(sd_journal_seek_head(j)); + assert_ret(sd_journal_next(j)); + test_check_numbers_down(j, 4); + sd_journal_close(j); + + /* Seek to tail, iterate up. + */ + assert_ret(sd_journal_open_directory(&j, t, 0)); + assert_ret(sd_journal_seek_tail(j)); + assert_ret(sd_journal_previous(j)); + test_check_numbers_up(j, 4); + sd_journal_close(j); + + /* Seek to tail, skip to head, iterate down. + */ + assert_ret(sd_journal_open_directory(&j, t, 0)); + assert_ret(sd_journal_seek_tail(j)); + assert_ret(r = sd_journal_previous_skip(j, 4)); + assert_se(r == 4); + test_check_numbers_down(j, 4); + sd_journal_close(j); + + /* Seek to head, skip to tail, iterate up. + */ + assert_ret(sd_journal_open_directory(&j, t, 0)); + assert_ret(sd_journal_seek_head(j)); + assert_ret(r = sd_journal_next_skip(j, 4)); + assert_se(r == 4); + test_check_numbers_up(j, 4); + sd_journal_close(j); + + assert_ret(rm_rf_dangerous(t, false, true, false)); +} + +int main(int argc, char *argv[]) { + test_skip(setup_sequential); + test_skip(setup_interleaved); + + return 0; +} -- cgit v1.2.1 From 5cb24cd32bce87cc618b857c059f1187e03d2b24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 7 Jun 2013 21:54:20 -0400 Subject: tests: add testcase for duplicate seqnums --- src/journal/test-journal-interleaving.c | 129 ++++++++++++++++++++++++++++---- 1 file changed, 115 insertions(+), 14 deletions(-) diff --git a/src/journal/test-journal-interleaving.c b/src/journal/test-journal-interleaving.c index c83a1ea981..069d297a9f 100644 --- a/src/journal/test-journal-interleaving.c +++ b/src/journal/test-journal-interleaving.c @@ -4,6 +4,7 @@ This file is part of systemd. Copyright 2013 Marius Vollmer + Copyright 2013 Zbigniew Jędrzejewski-Szmek systemd is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -26,12 +27,15 @@ #include "journal-file.h" #include "journal-internal.h" +#include "journal-vacuum.h" #include "util.h" #include "log.h" /* This program tests skipping around in a multi-file journal. */ +static bool arg_keep = false; + static void log_assert_errno(const char *text, int eno, const char *file, int line, const char *func) { log_meta(LOG_CRIT, file, line, func, "'%s' failed at %s:%u (%s): %s.", @@ -49,7 +53,7 @@ static void log_assert_errno(const char *text, int eno, const char *file, int li static JournalFile *test_open (const char *name) { JournalFile *f; - assert_ret(journal_file_open(name, O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, &f)); + assert_ret(journal_file_open(name, O_RDWR|O_CREAT, 0644, true, false, NULL, NULL, NULL, &f)); return f; } @@ -58,7 +62,7 @@ static void test_close (JournalFile *f) journal_file_close (f); } -static void test_append_number(JournalFile *f, int n) +static void append_number(JournalFile *f, int n, uint64_t *seqnum) { char *p; dual_timestamp ts; @@ -69,7 +73,7 @@ static void test_append_number(JournalFile *f, int n) assert_se(asprintf(&p, "NUMBER=%d", n) >= 0); iovec[0].iov_base = p; iovec[0].iov_len = strlen(p); - assert_ret(journal_file_append_entry(f, &ts, iovec, 1, NULL, NULL, NULL)); + assert_ret(journal_file_append_entry(f, &ts, iovec, 1, seqnum, NULL, NULL)); free (p); } @@ -120,10 +124,10 @@ static void setup_sequential(void) { JournalFile *one, *two; one = test_open("one.journal"); two = test_open("two.journal"); - test_append_number(one, 1); - test_append_number(one, 2); - test_append_number(two, 3); - test_append_number(two, 4); + append_number(one, 1, NULL); + append_number(one, 2, NULL); + append_number(two, 3, NULL); + append_number(two, 4, NULL); test_close(one); test_close(two); } @@ -132,10 +136,10 @@ static void setup_interleaved(void) { JournalFile *one, *two; one = test_open("one.journal"); two = test_open("two.journal"); - test_append_number(one, 1); - test_append_number(two, 2); - test_append_number(one, 3); - test_append_number(two, 4); + append_number(one, 1, NULL); + append_number(two, 2, NULL); + append_number(one, 3, NULL); + append_number(two, 4, NULL); test_close(one); test_close(two); } @@ -146,8 +150,6 @@ static void test_skip(void (*setup)(void)) sd_journal *j; int r; - log_set_max_level(LOG_DEBUG); - assert_se(mkdtemp(t)); assert_se(chdir(t) >= 0); @@ -187,12 +189,111 @@ static void test_skip(void (*setup)(void)) test_check_numbers_up(j, 4); sd_journal_close(j); - assert_ret(rm_rf_dangerous(t, false, true, false)); + log_info("Done..."); + + if (arg_keep) + log_info("Not removing %s", t); + else { + journal_directory_vacuum(".", 3000000, 0, 0, NULL); + + assert_se(rm_rf_dangerous(t, false, true, false) >= 0); + } + + puts("------------------------------------------------------------"); +} + +static void test_sequence_numbers(void) { + + char t[] = "/tmp/journal-seq-XXXXXX"; + JournalFile *one, *two; + uint64_t seqnum = 0; + sd_id128_t seqnum_id; + + assert_se(mkdtemp(t)); + assert_se(chdir(t) >= 0); + + assert_se(journal_file_open("one.journal", O_RDWR|O_CREAT, 0644, + true, false, NULL, NULL, NULL, &one) == 0); + + append_number(one, 1, &seqnum); + printf("seqnum=%"PRIu64"\n", seqnum); + assert(seqnum == 1); + append_number(one, 2, &seqnum); + printf("seqnum=%"PRIu64"\n", seqnum); + assert(seqnum == 2); + + assert(one->header->state == STATE_ONLINE); + assert(!sd_id128_equal(one->header->file_id, one->header->machine_id)); + assert(!sd_id128_equal(one->header->file_id, one->header->boot_id)); + assert(sd_id128_equal(one->header->file_id, one->header->seqnum_id)); + + memcpy(&seqnum_id, &one->header->seqnum_id, sizeof(sd_id128_t)); + + assert_se(journal_file_open("two.journal", O_RDWR|O_CREAT, 0644, + true, false, NULL, NULL, one, &two) == 0); + + assert(two->header->state == STATE_ONLINE); + assert(!sd_id128_equal(two->header->file_id, one->header->file_id)); + assert(sd_id128_equal(one->header->machine_id, one->header->machine_id)); + assert(sd_id128_equal(one->header->boot_id, one->header->boot_id)); + assert(sd_id128_equal(one->header->seqnum_id, one->header->seqnum_id)); + + append_number(two, 3, &seqnum); + printf("seqnum=%"PRIu64"\n", seqnum); + assert(seqnum == 3); + append_number(two, 4, &seqnum); + printf("seqnum=%"PRIu64"\n", seqnum); + assert(seqnum == 4); + + test_close(two); + + append_number(one, 5, &seqnum); + printf("seqnum=%"PRIu64"\n", seqnum); + assert(seqnum == 5); + + append_number(one, 6, &seqnum); + printf("seqnum=%"PRIu64"\n", seqnum); + assert(seqnum == 6); + + test_close(one); + + /* restart server */ + seqnum = 0; + + assert_se(journal_file_open("two.journal", O_RDWR, 0, + true, false, NULL, NULL, NULL, &two) == 0); + + assert(sd_id128_equal(two->header->seqnum_id, seqnum_id)); + + append_number(two, 7, &seqnum); + printf("seqnum=%"PRIu64"\n", seqnum); + assert(seqnum == 5); + + /* So..., here we have the same seqnum in two files with the + * same seqnum_id. */ + + test_close(two); + + log_info("Done..."); + + if (arg_keep) + log_info("Not removing %s", t); + else { + journal_directory_vacuum(".", 3000000, 0, 0, NULL); + + assert_se(rm_rf_dangerous(t, false, true, false) >= 0); + } } int main(int argc, char *argv[]) { + log_set_max_level(LOG_DEBUG); + + arg_keep = argc > 1; + test_skip(setup_sequential); test_skip(setup_interleaved); + test_sequence_numbers(); + return 0; } -- cgit v1.2.1 From cbd671772c9ce053a7050ddd29de170eb9efac7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 7 Jun 2013 22:01:03 -0400 Subject: journal: letting (interleaved) seqnums go In the following scenario: server creates system.journal server creates user-1000.journal both journals share the same seqnum_id. Then server writes to user-1000.journal first, and server writes to system.journal a bit later, and everything is fine. The server then terminates (crash, reboot, rsyslog testing, whatever), and user-1000.journal has entries which end with a lower seqnum than system.journal. Now server is restarted server opens user-1000.journal and writes entries to it... BAM! duplicate seqnums for the same seqnum_id. Now, we usually don't see that happen, because system.journal is closed last, and opened first. Since usually at least one message is written during boot and lands in the system.journal, the seqnum is initialized from it, and is set to a number higher than than anything found in user journals. Nevertheless, if system.journal is corrupted and is rotated, it can happen that an entry is written to the user journal with a seqnum that is a duplicate with an entry found in the corrupted system.journal~. When browsing the journal, journalctl can fall into a loop where it tries to follow the seqnums, and tries to go the next location by seqnum, and is transported back in time to to the older duplicate seqnum. There is not way to find out the maximum seqnum used in a multiple files, without actually looking at all of them. But we don't want to do that because it would be slow, and actually it isn't really possible, because a file might e.g. be temporarily unaccessible. Fix the problem by using different seqnum series for user journals. Using the same seqnum series for rotated journals is still fine, because we know that nothing will write to the rotated journal anymore. Likely related: https://bugs.freedesktop.org/show_bug.cgi?id=64566 https://bugs.freedesktop.org/show_bug.cgi?id=59856 https://bugs.freedesktop.org/show_bug.cgi?id=64296 https://bugs.archlinux.org/task/35581 https://bugzilla.novell.com/show_bug.cgi?id=817778 Possibly related: https://bugs.freedesktop.org/show_bug.cgi?id=64293 --- src/journal/journald-server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 6c99f4b690..a2b5ac7513 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -282,7 +282,7 @@ static JournalFile* find_journal(Server *s, uid_t uid) { journal_file_close(f); } - r = journal_file_open_reliably(p, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, s->system_journal, &f); + r = journal_file_open_reliably(p, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, NULL, &f); if (r < 0) return s->system_journal; -- cgit v1.2.1 From 7699b6eb9859ef7fecb1a0e2e156d65ed7d86b2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 10 Jun 2013 10:22:08 -0400 Subject: man: add note that sd_journal_open_files is racy --- man/sd_journal_open.xml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/man/sd_journal_open.xml b/man/sd_journal_open.xml index 4ac94c4ce3..182840e1df 100644 --- a/man/sd_journal_open.xml +++ b/man/sd_journal_open.xml @@ -125,7 +125,11 @@ of file paths to open. All files will be opened and interleaved automatically. This call also takes a flags argument, but it must be passed as 0 as no flags - are currently understood for this call. + are currently understood for this call. Please note + that in case of a live journal, this function is only + useful for debugging, because individual journal files + can be rotated at any moment, and the opening of + specific files in inherently racy. sd_journal_close() will close the journal context allocated with -- cgit v1.2.1 From d783cd0423459ff703122f523b86c9d094be2851 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 10 Jun 2013 15:08:02 -0400 Subject: build-sys: remove SD_JOURNAL_SYSTEM_ONLY(3) from Makefile --- Makefile-man.am | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Makefile-man.am b/Makefile-man.am index 807ad783fb..ba34d1e3df 100644 --- a/Makefile-man.am +++ b/Makefile-man.am @@ -118,7 +118,6 @@ MANPAGES_ALIAS += \ man/SD_JOURNAL_RUNTIME_ONLY.3 \ man/SD_JOURNAL_SUPPRESS_LOCATION.3 \ man/SD_JOURNAL_SYSTEM.3 \ - man/SD_JOURNAL_SYSTEM_ONLY.3 \ man/SD_LISTEN_FDS_START.3 \ man/SD_NOTICE.3 \ man/SD_WARNING.3 \ @@ -219,7 +218,6 @@ man/SD_JOURNAL_NOP.3: man/sd_journal_get_fd.3 man/SD_JOURNAL_RUNTIME_ONLY.3: man/sd_journal_open.3 man/SD_JOURNAL_SUPPRESS_LOCATION.3: man/sd_journal_print.3 man/SD_JOURNAL_SYSTEM.3: man/sd_journal_open.3 -man/SD_JOURNAL_SYSTEM_ONLY.3: man/sd_journal_open.3 man/SD_LISTEN_FDS_START.3: man/sd_listen_fds.3 man/SD_NOTICE.3: man/sd-daemon.3 man/SD_WARNING.3: man/sd-daemon.3 @@ -364,9 +362,6 @@ man/SD_JOURNAL_SUPPRESS_LOCATION.html: man/sd_journal_print.html man/SD_JOURNAL_SYSTEM.html: man/sd_journal_open.html $(html-alias) -man/SD_JOURNAL_SYSTEM_ONLY.html: man/sd_journal_open.html - $(html-alias) - man/SD_LISTEN_FDS_START.html: man/sd_listen_fds.html $(html-alias) -- cgit v1.2.1 From 49998b38321fca8f431258019e16a9824c643c09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 10 Jun 2013 18:10:12 -0400 Subject: journald: do not overwrite syslog facility when parsing priority https://bugs.freedesktop.org/show_bug.cgi?id=65610 --- src/journal/journald-syslog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c index 000f5acc10..4aeb9a35f0 100644 --- a/src/journal/journald-syslog.c +++ b/src/journal/journald-syslog.c @@ -268,7 +268,7 @@ void syslog_parse_priority(char **p, int *priority) { if (a < 0 || b < 0 || c < 0) return; - *priority = a*100+b*10+c; + *priority = (*priority & LOG_FACMASK) | (a*100 + b*10 + c); *p += k; } -- cgit v1.2.1 From 1f263d4dc23b9807ac6138eb5014d3d94c5fe51a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 11 Jun 2013 08:55:42 +0200 Subject: update TODO --- TODO | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/TODO b/TODO index 1dc585cca8..df3725ffe4 100644 --- a/TODO +++ b/TODO @@ -28,6 +28,12 @@ Fedora 19: Features: +* document logic of auto/noauto and fail/nofail in fstab in systemd.mount or systemd-fstab-generator man page + +* we should properly escape hostnames we add into dbus server strings + +* something pulls in pcre as so dep into our daemons such as hostnamed. + * cgroup-agent: downgrade error messages * document systemd-journal-flush.service properly -- cgit v1.2.1 From 3c527fd195ed9acddedb6dd6f50be6bffc94e9ae Mon Sep 17 00:00:00 2001 From: "Jason St. John" Date: Tue, 11 Jun 2013 18:26:03 +0200 Subject: bootchart: fix typos in copyright notices "Corporation" was misspelled as "Coproration" --- src/bootchart/bootchart.c | 2 +- src/bootchart/bootchart.h | 2 +- src/bootchart/store.c | 2 +- src/bootchart/store.h | 2 +- src/bootchart/svg.c | 2 +- src/bootchart/svg.h | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/bootchart/bootchart.c b/src/bootchart/bootchart.c index 8be5a27afa..14ccd3efe5 100644 --- a/src/bootchart/bootchart.c +++ b/src/bootchart/bootchart.c @@ -3,7 +3,7 @@ /*** This file is part of systemd. - Copyright (C) 2009-2013 Intel Coproration + Copyright (C) 2009-2013 Intel Corporation Authors: Auke Kok diff --git a/src/bootchart/bootchart.h b/src/bootchart/bootchart.h index d0273421de..968c38da26 100644 --- a/src/bootchart/bootchart.h +++ b/src/bootchart/bootchart.h @@ -5,7 +5,7 @@ /*** This file is part of systemd. - Copyright (C) 2009-2013 Intel Coproration + Copyright (C) 2009-2013 Intel Corporation Authors: Auke Kok diff --git a/src/bootchart/store.c b/src/bootchart/store.c index b2afb8d13b..f8c97c2324 100755 --- a/src/bootchart/store.c +++ b/src/bootchart/store.c @@ -3,7 +3,7 @@ /*** This file is part of systemd. - Copyright (C) 2009-2013 Intel Coproration + Copyright (C) 2009-2013 Intel Corporation Authors: Auke Kok diff --git a/src/bootchart/store.h b/src/bootchart/store.h index 7c8ad284da..f211b6f53b 100644 --- a/src/bootchart/store.h +++ b/src/bootchart/store.h @@ -5,7 +5,7 @@ /*** This file is part of systemd. - Copyright (C) 2009-2013 Intel Coproration + Copyright (C) 2009-2013 Intel Corporation Authors: Auke Kok diff --git a/src/bootchart/svg.c b/src/bootchart/svg.c index 859cf81c22..5eee2d1987 100644 --- a/src/bootchart/svg.c +++ b/src/bootchart/svg.c @@ -3,7 +3,7 @@ /*** This file is part of systemd. - Copyright (C) 2009-2013 Intel Coproration + Copyright (C) 2009-2013 Intel Corporation Authors: Auke Kok diff --git a/src/bootchart/svg.h b/src/bootchart/svg.h index e7369f5111..df3a7bf8ef 100644 --- a/src/bootchart/svg.h +++ b/src/bootchart/svg.h @@ -5,7 +5,7 @@ /*** This file is part of systemd. - Copyright (C) 2009-2013 Intel Coproration + Copyright (C) 2009-2013 Intel Corporation Authors: Auke Kok -- cgit v1.2.1 From 622004565eca385c685086cd478aa79afe73b785 Mon Sep 17 00:00:00 2001 From: Ross Burton Date: Tue, 11 Jun 2013 17:16:37 +0100 Subject: build-sys: don't install quotaon.service twice quotaon.service is already installed through dist_systemunit_DATA, so it doesn't need to be added to nodist_systemunit_DATA. Installing the same file twice results in a race condition where the install process can fail. https://bugs.freedesktop.org/show_bug.cgi?id=65659 [zj: actually remove quotaon.service from the other list.] --- Makefile.am | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 28ae7edea0..3219762654 100644 --- a/Makefile.am +++ b/Makefile.am @@ -389,7 +389,6 @@ dist_systemunit_DATA = \ units/sound.target \ units/bluetooth.target \ units/smartcard.target \ - units/quotaon.service \ units/systemd-ask-password-wall.path \ units/systemd-ask-password-console.path \ units/systemd-udevd-control.socket \ -- cgit v1.2.1 From 3a0e7bf5414ebbe160163d14452470ea85b41b64 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Wed, 12 Jun 2013 13:05:15 +0200 Subject: gitignore: Add test-journal-interleaving --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 7534ac1c07..d1e2ae9915 100644 --- a/.gitignore +++ b/.gitignore @@ -109,6 +109,7 @@ /test-job-type /test-journal /test-journal-enum +/test-journal-interleaving /test-journal-match /test-journal-send /test-journal-stream -- cgit v1.2.1 From 330fe879ba128467a223285302bf746851ddb957 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 12 Jun 2013 13:40:54 -0400 Subject: build-sys: add 'man' target Useful when working just on the documentation. --- Makefile.am | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile.am b/Makefile.am index 3219762654..a74c19df7b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -511,6 +511,9 @@ MANPAGES_ALIAS = include Makefile-man.am +.PHONY: man +man: $(MANPAGES) $(MANPAGES_ALIAS) $(HTML_FILES) $(HTML_ALIAS) + XML_FILES = \ ${patsubst %.1,%.xml,${patsubst %.3,%.xml,${patsubst %.5,%.xml,${patsubst %.7,%.xml,${patsubst %.8,%.xml,$(MANPAGES)}}}}} HTML_FILES = \ -- cgit v1.2.1 From 6e5abe1564070a760196b97031eca9cf5e95e8a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 13 Jun 2013 23:32:14 -0400 Subject: journal: use initialization instead of zeroing --- src/journal/journal-send.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/journal/journal-send.c b/src/journal/journal-send.c index 14c437da78..da1f892685 100644 --- a/src/journal/journal-send.c +++ b/src/journal/journal-send.c @@ -204,8 +204,14 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int n) { struct iovec *w; uint64_t *l; int i, j = 0; - struct msghdr mh; - struct sockaddr_un sa; + struct sockaddr_un sa = { + .sun_family = AF_UNIX, + .sun_path = "/run/systemd/journal/socket", + }; + struct msghdr mh = { + .msg_name = &sa, + .msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(sa.sun_path), + }; ssize_t k; union { struct cmsghdr cmsghdr; @@ -292,13 +298,6 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int n) { if (_unlikely_(fd < 0)) return fd; - zero(sa); - sa.sun_family = AF_UNIX; - strncpy(sa.sun_path, "/run/systemd/journal/socket", sizeof(sa.sun_path)); - - zero(mh); - mh.msg_name = &sa; - mh.msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(sa.sun_path); mh.msg_iov = w; mh.msg_iovlen = j; @@ -402,7 +401,10 @@ _public_ int sd_journal_perror(const char *message) { } _public_ int sd_journal_stream_fd(const char *identifier, int priority, int level_prefix) { - union sockaddr_union sa; + union sockaddr_union sa = { + .un.sun_family = AF_UNIX, + .un.sun_path = "/run/systemd/journal/stdout", + }; int fd; char *header; size_t l; @@ -415,10 +417,6 @@ _public_ int sd_journal_stream_fd(const char *identifier, int priority, int leve if (fd < 0) return -errno; - zero(sa); - sa.un.sun_family = AF_UNIX; - strncpy(sa.un.sun_path, "/run/systemd/journal/stdout", sizeof(sa.un.sun_path)); - r = connect(fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path)); if (r < 0) { close_nointr_nofail(fd); -- cgit v1.2.1 From e40ec7aec5e64cd0cfa5fc556d6a9747229b5794 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 13 Jun 2013 23:32:14 -0400 Subject: journald: do not calculate free space too early Since the system journal wasn't open yet, available_space() returned 0. Before: systemd-journal[22170]: Allowing system journal files to grow to 4.0G. systemd-journal[22170]: Journal size currently limited to 0B due to SystemKeepFree. After: systemd-journal[22178]: Allowing system journal files to grow to 4.0G. systemd-journal[22178]: Journal size currently limited to 3.0G due to SystemKeepFree. Also, when failing to write a message, show how much space was needed: "Failed to write entry (26 items, 260123456 bytes) despite vacuuming, ignoring: ...". --- src/journal/journald-server.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index a2b5ac7513..de96040242 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -465,7 +465,12 @@ static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned } if (vacuumed || !shall_try_append_again(f, r)) { - log_error("Failed to write entry, ignoring: %s", strerror(-r)); + size_t size = 0; + unsigned i; + for (i = 0; i < n; i++) + size += iovec[i].iov_len; + + log_error("Failed to write entry (%d items, %zu bytes), ignoring: %s", n, size, strerror(-r)); return; } @@ -478,8 +483,14 @@ static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned log_debug("Retrying write."); r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL); - if (r < 0) - log_error("Failed to write entry, ignoring: %s", strerror(-r)); + if (r < 0) { + size_t size = 0; + unsigned i; + for (i = 0; i < n; i++) + size += iovec[i].iov_len; + + log_error("Failed to write entry (%d items, %zu bytes) despite vacuuming, ignoring: %s", n, size, strerror(-r)); + } } static void dispatch_message_real( @@ -767,9 +778,6 @@ static int system_journal_open(Server *s) { char *fn; sd_id128_t machine; char ids[33]; - uint64_t avail; - - avail = available_space(s); r = sd_id128_get_machine(&machine); if (r < 0) @@ -790,27 +798,23 @@ static int system_journal_open(Server *s) { if (s->storage == STORAGE_PERSISTENT) (void) mkdir("/var/log/journal/", 0755); - fn = strappend("/var/log/journal/", ids); - if (!fn) - return -ENOMEM; - + fn = strappenda("/var/log/journal/", ids); (void) mkdir(fn, 0755); - free(fn); - - fn = strjoin("/var/log/journal/", ids, "/system.journal", NULL); - if (!fn) - return -ENOMEM; + fn = strappenda(fn, "/system.journal"); r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, NULL, &s->system_journal); - free(fn); if (r >= 0) { char fb[FORMAT_BYTES_MAX]; + uint64_t avail; server_fix_perms(s, s->system_journal, 0); + server_driver_message(s, SD_ID128_NULL, "Allowing system journal files to grow to %s.", format_bytes(fb, sizeof(fb), s->system_metrics.max_use)); + avail = available_space(s); + if (s->system_metrics.max_use > avail) server_driver_message(s, SD_ID128_NULL, "Journal size currently limited to %s due to SystemKeepFree.", format_bytes(fb, sizeof(fb), avail)); @@ -864,11 +868,14 @@ static int system_journal_open(Server *s) { if (s->runtime_journal) { char fb[FORMAT_BYTES_MAX]; + uint64_t avail; server_fix_perms(s, s->runtime_journal, 0); server_driver_message(s, SD_ID128_NULL, "Allowing runtime journal files to grow to %s.", format_bytes(fb, sizeof(fb), s->runtime_metrics.max_use)); + avail = available_space(s); + if (s->system_metrics.max_use > avail) server_driver_message(s, SD_ID128_NULL, "Journal size currently limited to %s due to RuntimeKeepFree.", format_bytes(fb, sizeof(fb), avail)); -- cgit v1.2.1 From 5e9dfd2ef99bad1000a6246a160c096c4dbd2158 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 13 Jun 2013 23:32:15 -0400 Subject: man: add sd_j_open_files to return values section --- man/sd_journal_open.xml | 5 +++-- man/systemd.special.xml | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/man/sd_journal_open.xml b/man/sd_journal_open.xml index 182840e1df..0f4178274e 100644 --- a/man/sd_journal_open.xml +++ b/man/sd_journal_open.xml @@ -175,8 +175,9 @@ Return Value - The sd_journal_open() and - sd_journal_open_directory() calls + The sd_journal_open(), + sd_journal_open_directory(), and + sd_journal_open_files() calls return 0 on success or a negative errno-style error code. sd_journal_close() returns nothing. diff --git a/man/systemd.special.xml b/man/systemd.special.xml index 7164b1e614..4588f58999 100644 --- a/man/systemd.special.xml +++ b/man/systemd.special.xml @@ -314,7 +314,7 @@ dependencies of type Before= to sysroot-usr.mount - and all mount points fround in + and all mount points found in /etc/fstab that have the and -- cgit v1.2.1 From 3ae83f9896bff49679c8a60e6ff9520557df8b16 Mon Sep 17 00:00:00 2001 From: "Jason St. John" Date: Wed, 12 Jun 2013 19:45:14 +0200 Subject: man: improve readability of "_TRANSPORT=" section in systemd.journal-fields(7) The list and descriptions of valid transports was difficult to read, so break the long sentence up into discrete man page list items to improve readability. --- man/systemd.journal-fields.xml | 84 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 68 insertions(+), 16 deletions(-) diff --git a/man/systemd.journal-fields.xml b/man/systemd.journal-fields.xml index a0f1bfda13..beb2fd6584 100644 --- a/man/systemd.journal-fields.xml +++ b/man/systemd.journal-fields.xml @@ -286,23 +286,75 @@ How the entry was received by the journal - service. One of - driver, - syslog, - journal, - stdout, - kernel for - internally generated messages, - for those received via the - local syslog socket with the - syslog protocol, for those - received via the native - journal protocol, for the - those read from a services' - standard output or error - output, or for those read - from the kernel, respectively. + service. Valid transports are: + + + + + + + for + internally + generated + messages + + + + + + + + + + for those + received via the + local syslog + socket with the + syslog protocol + + + + + + + + + + for those + received via the + native journal + protocol + + + + + + + + + + for those + read from a + service's + standard output + or error output + + + + + + + + + + for those + read from the + kernel + + + + -- cgit v1.2.1 From 805bf39ce79f352f98eb3d144840c8ad6497d3e9 Mon Sep 17 00:00:00 2001 From: Gabriel de Perthuis Date: Tue, 11 Jun 2013 22:29:32 +0200 Subject: systemd-analyze: Show critical chains for listed units --- src/analyze/systemd-analyze.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/analyze/systemd-analyze.c b/src/analyze/systemd-analyze.c index fe1abdc6bd..ffdcd14700 100644 --- a/src/analyze/systemd-analyze.c +++ b/src/analyze/systemd-analyze.c @@ -826,7 +826,7 @@ static int list_dependencies_one(DBusConnection *bus, const char *name, unsigned return 0; } -static int list_dependencies(DBusConnection *bus) { +static int list_dependencies(DBusConnection *bus, const char *name) { _cleanup_strv_free_ char **units = NULL; char ts[FORMAT_TIMESPAN_MAX]; struct unit_times *times; @@ -841,7 +841,7 @@ static int list_dependencies(DBusConnection *bus) { assert(bus); - path = unit_dbus_path_from_name(SPECIAL_DEFAULT_TARGET); + path = unit_dbus_path_from_name(name); if (path == NULL) return -EINVAL; @@ -890,10 +890,10 @@ static int list_dependencies(DBusConnection *bus) { printf("%s\n", id); } - return list_dependencies_one(bus, SPECIAL_DEFAULT_TARGET, 0, &units, 0); + return list_dependencies_one(bus, name, 0, &units, 0); } -static int analyze_critical_chain(DBusConnection *bus) { +static int analyze_critical_chain(DBusConnection *bus, char *names[]) { struct unit_times *times; int n, r; unsigned int i; @@ -917,7 +917,13 @@ static int analyze_critical_chain(DBusConnection *bus) { puts("The time after the unit is active or started is printed after the \"@\" character.\n" "The time the unit takes to start is printed after the \"+\" character.\n"); - list_dependencies(bus); + if (!strv_isempty(names)) { + char **name; + STRV_FOREACH(name, names) + list_dependencies(bus, *name); + } else { + list_dependencies(bus, SPECIAL_DEFAULT_TARGET); + } hashmap_free(h); free_unit_times(times, (unsigned) n); @@ -1301,7 +1307,7 @@ int main(int argc, char *argv[]) { else if (streq(argv[optind], "blame")) r = analyze_blame(bus); else if (streq(argv[optind], "critical-chain")) - r = analyze_critical_chain(bus); + r = analyze_critical_chain(bus, argv+optind+1); else if (streq(argv[optind], "plot")) r = analyze_plot(bus); else if (streq(argv[optind], "dot")) -- cgit v1.2.1 From fa3868c6d317b88715c55422b898f9070afe6575 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 14 Jun 2013 08:53:15 -0400 Subject: man: update systemd-analyze invocation --- man/systemd-analyze.xml | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml index ae45bfcf31..ae7a3377c6 100644 --- a/man/systemd-analyze.xml +++ b/man/systemd-analyze.xml @@ -55,19 +55,32 @@ - systemd-analyze OPTIONS time + systemd-analyze + OPTIONS + time - systemd-analyze OPTIONS blame + systemd-analyze + OPTIONS + blame - systemd-analyze OPTIONS critical-chain + systemd-analyze + OPTIONS + critical-chain + UNIT - systemd-analyze OPTIONS plot > file.svg + systemd-analyze + OPTIONS + plot + > file.svg - systemd-analyze OPTIONS dot pattern... + systemd-analyze + OPTIONS + dot + PATTERN @@ -97,8 +110,10 @@ be slow simply because it waits for the initialization of another service to complete. - systemd-analyze critical-chain - prints a tree of the time critical chain of units. + systemd-analyze critical-chain [UNIT...] + prints a tree of the time critical chain of units + (for each of the specified UNITs + or for the default target otherwise). The time after the unit is active or started is printed after the "@" character. The time the unit takes to start is printed after the "+" character. -- cgit v1.2.1 From 98a6e132b5b85999f7e3dce158e826ffeecc1553 Mon Sep 17 00:00:00 2001 From: Daniel Albers Date: Mon, 17 Jun 2013 11:36:35 +0200 Subject: journalctl,loginctl,systemctl,systemd-cgls: add -l as alias for --full https://bugs.freedesktop.org/show_bug.cgi?id=65850 --- man/journalctl.xml | 1 + man/loginctl.xml | 1 + man/systemctl.xml | 1 + man/systemd-cgls.xml | 1 + shell-completion/bash/systemctl | 2 +- shell-completion/systemd-zsh-completion.zsh | 4 ++-- src/cgls/cgls.c | 7 +++---- src/journal/journalctl.c | 9 ++++----- src/login/loginctl.c | 7 +++---- src/systemctl/systemctl.c | 7 +++---- 10 files changed, 20 insertions(+), 20 deletions(-) diff --git a/man/journalctl.xml b/man/journalctl.xml index f399868178..7a8d4b2dcc 100644 --- a/man/journalctl.xml +++ b/man/journalctl.xml @@ -138,6 +138,7 @@ + Show all (printable) fields in diff --git a/man/loginctl.xml b/man/loginctl.xml index 2c8d982eda..e76ee95902 100644 --- a/man/loginctl.xml +++ b/man/loginctl.xml @@ -111,6 +111,7 @@ + Do not ellipsize cgroup diff --git a/man/systemctl.xml b/man/systemctl.xml index 54573e8f5f..9ab5c8ba5f 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -175,6 +175,7 @@ along with systemd; If not, see . + diff --git a/man/systemd-cgls.xml b/man/systemd-cgls.xml index 6249d05a8c..53e7f7ddd8 100644 --- a/man/systemd-cgls.xml +++ b/man/systemd-cgls.xml @@ -113,6 +113,7 @@ + Do not ellipsize cgroup diff --git a/shell-completion/bash/systemctl b/shell-completion/bash/systemctl index a05b756980..ceca3348ed 100644 --- a/shell-completion/bash/systemctl +++ b/shell-completion/bash/systemctl @@ -70,7 +70,7 @@ _systemctl () { local i verb comps mode local -A OPTS=( - [STANDALONE]='--all -a --reverse --after --before --defaults --fail --ignore-dependencies --failed --force -f --full --global + [STANDALONE]='--all -a --reverse --after --before --defaults --fail --ignore-dependencies --failed --force -f --full -l --global --help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall --quiet -q --privileged -P --system --user --version --runtime' [ARG]='--host -H --kill-mode --kill-who --property -p --signal -s --type -t --root' diff --git a/shell-completion/systemd-zsh-completion.zsh b/shell-completion/systemd-zsh-completion.zsh index 6862891723..c85e00e384 100644 --- a/shell-completion/systemd-zsh-completion.zsh +++ b/shell-completion/systemd-zsh-completion.zsh @@ -16,7 +16,7 @@ _ctls() '--after[Show units ordered after]' \ '--before[Show units ordered before]' \ '--failed[Show only failed units]' \ - "--full[Don't ellipsize unit names on output]" \ + {-l,--full}"[Don't ellipsize unit names on output]" \ '--fail[When queueing a new job, fail if conflicting jobs are pending]' \ '--ignore-dependencies[When queueing a new job, ignore all its dependencies]' \ '--kill-who=[Who to send signal to]:killwho:(main control all)' \ @@ -81,7 +81,7 @@ _ctls() {-n,--lines=}'[Number of journal entries to show]:integer' \ '--no-tail[Show all lines, even in follow mode]' \ {-o,--output=}'[Change journal output mode]:output modes:_outputmodes' \ - '--full[Show long fields in full]' \ + {-l,--full}'[Show long fields in full]' \ {-a,--all}'[Show all fields, including long and unprintable]' \ {-q,--quiet}"[Don't show privilege warning]" \ '--no-pager[Do not pipe output into a pager]' \ diff --git a/src/cgls/cgls.c b/src/cgls/cgls.c index ef3e5672ab..f232731ab4 100644 --- a/src/cgls/cgls.c +++ b/src/cgls/cgls.c @@ -49,7 +49,7 @@ static void help(void) { " --version Show package version\n" " --no-pager Do not pipe output into a pager\n" " -a --all Show all groups, including empty\n" - " --full Do not ellipsize output\n" + " -l --full Do not ellipsize output\n" " -k Include kernel threads in output\n" " -M --machine Show container\n", program_invocation_short_name); @@ -60,7 +60,6 @@ static int parse_argv(int argc, char *argv[]) { enum { ARG_NO_PAGER = 0x100, ARG_VERSION, - ARG_FULL, }; static const struct option options[] = { @@ -68,7 +67,7 @@ static int parse_argv(int argc, char *argv[]) { { "version", no_argument, NULL, ARG_VERSION }, { "no-pager", no_argument, NULL, ARG_NO_PAGER }, { "all", no_argument, NULL, 'a' }, - { "full", no_argument, NULL, ARG_FULL }, + { "full", no_argument, NULL, 'l' }, { "machine", required_argument, NULL, 'M' }, { NULL, 0, NULL, 0 } }; @@ -99,7 +98,7 @@ static int parse_argv(int argc, char *argv[]) { arg_all = true; break; - case ARG_FULL: + case 'l': arg_full = true; break; diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 1a441dd0d6..7baea237cb 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -125,7 +125,7 @@ static int help(void) { " -o --output=STRING Change journal output mode (short, short-monotonic,\n" " verbose, export, json, json-pretty, json-sse, cat)\n" " -x --catalog Add message explanations where available\n" - " --full Do not ellipsize fields\n" + " -l --full Do not ellipsize fields\n" " -a --all Show all fields, including long and unprintable\n" " -q --quiet Don't show privilege warning\n" " --no-pager Do not pipe output into a pager\n" @@ -167,7 +167,6 @@ static int parse_argv(int argc, char *argv[]) { ARG_SYSTEM, ARG_ROOT, ARG_HEADER, - ARG_FULL, ARG_SETUP_KEYS, ARG_FILE, ARG_INTERVAL, @@ -190,7 +189,7 @@ static int parse_argv(int argc, char *argv[]) { { "follow", no_argument, NULL, 'f' }, { "output", required_argument, NULL, 'o' }, { "all", no_argument, NULL, 'a' }, - { "full", no_argument, NULL, ARG_FULL }, + { "full", no_argument, NULL, 'l' }, { "lines", optional_argument, NULL, 'n' }, { "no-tail", no_argument, NULL, ARG_NO_TAIL }, { "new-id128", no_argument, NULL, ARG_NEW_ID128 }, @@ -229,7 +228,7 @@ static int parse_argv(int argc, char *argv[]) { assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "hefo:an::qmbkD:p:c:u:F:xr", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "hefo:aln::qmbkD:p:c:u:F:xr", options, NULL)) >= 0) { switch (c) { @@ -274,7 +273,7 @@ static int parse_argv(int argc, char *argv[]) { break; - case ARG_FULL: + case 'l': arg_full = true; break; diff --git a/src/login/loginctl.c b/src/login/loginctl.c index b09aa37ff8..087e52d503 100644 --- a/src/login/loginctl.c +++ b/src/login/loginctl.c @@ -1297,7 +1297,7 @@ static int help(void) { " -p --property=NAME Show only properties by this name\n" " -a --all Show all properties, including empty ones\n" " --kill-who=WHO Who to send signal to\n" - " --full Do not ellipsize output\n" + " -l --full Do not ellipsize output\n" " -s --signal=SIGNAL Which signal to send\n" " --no-ask-password Don't prompt for password\n" " -H --host=[USER@]HOST Show information for remote host\n" @@ -1339,7 +1339,6 @@ static int parse_argv(int argc, char *argv[]) { ARG_NO_PAGER, ARG_KILL_WHO, ARG_NO_ASK_PASSWORD, - ARG_FULL, }; static const struct option options[] = { @@ -1353,7 +1352,7 @@ static int parse_argv(int argc, char *argv[]) { { "host", required_argument, NULL, 'H' }, { "privileged", no_argument, NULL, 'P' }, { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD }, - { "full", no_argument, NULL, ARG_FULL }, + { "full", no_argument, NULL, 'l' }, { NULL, 0, NULL, 0 } }; @@ -1425,7 +1424,7 @@ static int parse_argv(int argc, char *argv[]) { parse_user_at_host(optarg, &arg_user, &arg_host); break; - case ARG_FULL: + case 'l': arg_full = true; break; diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 3e4cefec76..a453598c72 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -4599,7 +4599,7 @@ static int systemctl_help(void) { " the 'list-unit-files' command instead.\n" " --reverse Show reverse dependencies with 'list-dependencies'\n" " --failed Show only failed units\n" - " --full Don't ellipsize unit names on output\n" + " -l --full Don't ellipsize unit names on output\n" " --fail When queueing a new job, fail if conflicting jobs are\n" " pending\n" " --irreversible Create jobs which cannot be implicitly cancelled\n" @@ -4819,7 +4819,6 @@ static int systemctl_parse_argv(int argc, char *argv[]) { ARG_NO_PAGER, ARG_NO_WALL, ARG_ROOT, - ARG_FULL, ARG_NO_RELOAD, ARG_KILL_WHO, ARG_NO_ASK_PASSWORD, @@ -4840,7 +4839,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { { "before", no_argument, NULL, ARG_BEFORE }, { "show-types", no_argument, NULL, ARG_SHOW_TYPES }, { "failed", no_argument, NULL, ARG_FAILED }, - { "full", no_argument, NULL, ARG_FULL }, + { "full", no_argument, NULL, 'l' }, { "fail", no_argument, NULL, ARG_FAIL }, { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, @@ -5021,7 +5020,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { arg_root = optarg; break; - case ARG_FULL: + case 'l': arg_full = true; break; -- cgit v1.2.1 From ed8086d119d8a996a0ad13d33eeb99b4d16d9492 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 17 Jun 2013 18:37:07 +0200 Subject: rpm: define a %_userunitdir macro --- src/core/macros.systemd.in | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/macros.systemd.in b/src/core/macros.systemd.in index f77082c2db..4ad8186fae 100644 --- a/src/core/macros.systemd.in +++ b/src/core/macros.systemd.in @@ -20,6 +20,7 @@ # RPM macros for packages installing systemd unit files %_unitdir @systemunitdir@ +%_userunitdir @userunitdir@ %_presetdir @systempresetdir@ %_udevhwdbdir @udevhwdbdir@ %_udevrulesdir @udevrulesdir@ -- cgit v1.2.1 From 602c0e740f8290cc9c4f13f2eb4b23fbbd7a8d2b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 17 Jun 2013 21:12:53 +0200 Subject: mount: when learning about the root mount from mountinfo, don't add conflicting dep for umount.target That way systemd won't try to umount it at shutdown. --- src/core/mount.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/mount.c b/src/core/mount.c index 10073b50be..0ad3d951a5 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -1538,9 +1538,11 @@ static int mount_add_one( if (r < 0) goto fail; - r = unit_add_dependency_by_name(u, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true); - if (r < 0) - goto fail; + if (!path_equal(where, "/")) { + r = unit_add_dependency_by_name(u, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true); + if (r < 0) + goto fail; + } unit_add_to_load_queue(u); } else { -- cgit v1.2.1 From c647f10918940b5d11870df6d008c6c3180bdc41 Mon Sep 17 00:00:00 2001 From: Ross Lagerwall Date: Thu, 13 Jun 2013 10:45:12 +0100 Subject: rules: only run systemd-sysctl when a network device is added Otherwise, when a network device is renamed, systemd-sysctl is run twice with the same network device name: once for ACTION="add" and once for ACTION="move". --- rules/99-systemd.rules.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/99-systemd.rules.in b/rules/99-systemd.rules.in index d17bdd9a0a..e9b2da7b39 100644 --- a/rules/99-systemd.rules.in +++ b/rules/99-systemd.rules.in @@ -49,7 +49,7 @@ SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{ID_USB_INTERFACES}=="*:0701??: # Apply sysctl variables to network devices (and only to those) as they appear. -SUBSYSTEM=="net", KERNEL!="lo", RUN+="@rootlibexecdir@/systemd-sysctl --prefix=/proc/sys/net/ipv4/conf/$name --prefix=/proc/sys/net/ipv4/neigh/$name --prefix=/proc/sys/net/ipv6/conf/$name --prefix=/proc/sys/net/ipv6/neigh/$name" +ACTION=="add", SUBSYSTEM=="net", KERNEL!="lo", RUN+="@rootlibexecdir@/systemd-sysctl --prefix=/proc/sys/net/ipv4/conf/$name --prefix=/proc/sys/net/ipv4/neigh/$name --prefix=/proc/sys/net/ipv6/conf/$name --prefix=/proc/sys/net/ipv6/neigh/$name" # Asynchronously mount file systems implemented by these modules as # soon as they are loaded. -- cgit v1.2.1 From a016b9228f338cb9b380ce7e00826ef462767d98 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 17 Jun 2013 21:33:26 +0200 Subject: core: add new .slice unit type for partitioning systems In order to prepare for the kernel cgroup rework, let's introduce a new unit type to systemd, the "slice". Slices can be arranged in a tree and are useful to partition resources freely and hierarchally by the user. Each service unit can now be assigned to one of these slices, and later on login users and machines may too. Slices translate pretty directly to the cgroup hierarchy, and the various objects can be assigned to any of the slices in the tree. --- Makefile.am | 4 + TODO | 11 ++ src/core/cgroup.c | 4 +- src/core/dbus-slice.c | 60 +++++++ src/core/dbus-slice.h | 30 ++++ src/core/load-fragment-gperf.gperf.m4 | 29 ++-- src/core/load-fragment.c | 43 +++++ src/core/load-fragment.h | 1 + src/core/mount.c | 4 + src/core/service.c | 4 + src/core/slice.c | 298 ++++++++++++++++++++++++++++++++++ src/core/slice.h | 44 +++++ src/core/socket.c | 7 +- src/core/special.h | 3 + src/core/swap.c | 4 + src/core/unit.c | 53 +++++- src/core/unit.h | 24 ++- src/shared/cgroup-util.c | 50 ++++++ src/shared/cgroup-util.h | 2 + src/shared/unit-name.c | 12 +- src/shared/unit-name.h | 3 +- src/systemctl/systemctl.c | 4 +- src/test/test-cgroup-util.c | 20 +++ 23 files changed, 679 insertions(+), 35 deletions(-) create mode 100644 src/core/dbus-slice.c create mode 100644 src/core/dbus-slice.h create mode 100644 src/core/slice.c create mode 100644 src/core/slice.h diff --git a/Makefile.am b/Makefile.am index a74c19df7b..5a285be343 100644 --- a/Makefile.am +++ b/Makefile.am @@ -843,6 +843,8 @@ libsystemd_core_la_SOURCES = \ src/core/timer.h \ src/core/path.c \ src/core/path.h \ + src/core/slice.c \ + src/core/slice.h \ src/core/load-dropin.c \ src/core/load-dropin.h \ src/core/execute.c \ @@ -881,6 +883,8 @@ libsystemd_core_la_SOURCES = \ src/core/dbus-kill.h \ src/core/dbus-path.c \ src/core/dbus-path.h \ + src/core/dbus-slice.c \ + src/core/dbus-slice.h \ src/core/cgroup.c \ src/core/cgroup.h \ src/core/selinux-access.c \ diff --git a/TODO b/TODO index df3725ffe4..cfd2763a40 100644 --- a/TODO +++ b/TODO @@ -28,6 +28,17 @@ Fedora 19: Features: +* when a service changes state make reflect that in the + RUNNING/LISTENING states of its socket + +* slices: + - fix libsystemd-login to handle slices properly + - add option to pam_systemd to move login session into a slice + - add call to logind's dbus intrface to register a machine (also, calls for listing them) + +* when recursively showing the cgroup hierarchy, optionally also show + the hierarchies of child processes + * document logic of auto/noauto and fail/nofail in fstab in systemd.mount or systemd-fstab-generator man page * we should properly escape hostnames we add into dbus server strings diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 83df0f3c9a..a995d1436d 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -340,14 +340,14 @@ int manager_setup_cgroup(Manager *m) { } if (m->running_as == SYSTEMD_SYSTEM) - suffix = "/system"; + suffix = NULL; else { sprintf(suffix_buffer, "/systemd-%lu", (unsigned long) getpid()); suffix = suffix_buffer; } free(m->cgroup_hierarchy); - if (endswith(current, suffix)) { + if (!suffix || endswith(current, suffix)) { /* We probably got reexecuted and can continue to use our root cgroup */ m->cgroup_hierarchy = current; current = NULL; diff --git a/src/core/dbus-slice.c b/src/core/dbus-slice.c new file mode 100644 index 0000000000..8a318faa55 --- /dev/null +++ b/src/core/dbus-slice.c @@ -0,0 +1,60 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include + +#include "dbus-unit.h" +#include "dbus-slice.h" +#include "dbus-common.h" +#include "selinux-access.h" + +#define BUS_SLICE_INTERFACE \ + " \n" \ + BUS_UNIT_CGROUP_INTERFACE \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_UNIT_INTERFACE \ + BUS_SLICE_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Slice\0" + +const char bus_slice_interface[] _introspect_("Slice") = BUS_SLICE_INTERFACE; + +DBusHandlerResult bus_slice_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { + const BusBoundProperties bps[] = { + { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Slice", bus_unit_cgroup_properties, u }, + { NULL, } + }; + + SELINUX_UNIT_ACCESS_CHECK(u, c, message, "status"); + + return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps); +} diff --git a/src/core/dbus-slice.h b/src/core/dbus-slice.h new file mode 100644 index 0000000000..7e7e29982d --- /dev/null +++ b/src/core/dbus-slice.h @@ -0,0 +1,30 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include + +#include "unit.h" + +DBusHandlerResult bus_slice_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); + +extern const char bus_slice_interface[]; diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index 4e1454ee6c..9e5a408a30 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -66,16 +66,6 @@ $1.LimitMSGQUEUE, config_parse_limit, RLIMIT_MSGQ $1.LimitNICE, config_parse_limit, RLIMIT_NICE, offsetof($1, exec_context.rlimit) $1.LimitRTPRIO, config_parse_limit, RLIMIT_RTPRIO, offsetof($1, exec_context.rlimit) $1.LimitRTTIME, config_parse_limit, RLIMIT_RTTIME, offsetof($1, exec_context.rlimit) -$1.ControlGroup, config_parse_unit_cgroup, 0, 0 -$1.ControlGroupAttribute, config_parse_unit_cgroup_attr, 0, 0 -$1.CPUShares, config_parse_unit_cgroup_attr_pretty, 0, 0 -$1.MemoryLimit, config_parse_unit_cgroup_attr_pretty, 0, 0 -$1.MemorySoftLimit, config_parse_unit_cgroup_attr_pretty, 0, 0 -$1.DeviceAllow, config_parse_unit_cgroup_attr_pretty, 0, 0 -$1.DeviceDeny, config_parse_unit_cgroup_attr_pretty, 0, 0 -$1.BlockIOWeight, config_parse_unit_cgroup_attr_pretty, 0, 0 -$1.BlockIOReadBandwidth, config_parse_unit_cgroup_attr_pretty, 0, 0 -$1.BlockIOWriteBandwidth, config_parse_unit_cgroup_attr_pretty, 0, 0 $1.ReadWriteDirectories, config_parse_path_strv, 0, offsetof($1, exec_context.read_write_dirs) $1.ReadOnlyDirectories, config_parse_path_strv, 0, offsetof($1, exec_context.read_only_dirs) $1.InaccessibleDirectories, config_parse_path_strv, 0, offsetof($1, exec_context.inaccessible_dirs) @@ -94,6 +84,18 @@ m4_define(`KILL_CONTEXT_CONFIG_ITEMS', $1.KillMode, config_parse_kill_mode, 0, offsetof($1, kill_context.kill_mode) $1.KillSignal, config_parse_kill_signal, 0, offsetof($1, kill_context.kill_signal)' )m4_dnl +m4_define(`CGROUP_CONTEXT_CONFIG_ITEMS', +`$1.ControlGroup, config_parse_unit_cgroup, 0, 0 +$1.ControlGroupAttribute, config_parse_unit_cgroup_attr, 0, 0 +$1.CPUShares, config_parse_unit_cgroup_attr_pretty, 0, 0 +$1.MemoryLimit, config_parse_unit_cgroup_attr_pretty, 0, 0 +$1.MemorySoftLimit, config_parse_unit_cgroup_attr_pretty, 0, 0 +$1.DeviceAllow, config_parse_unit_cgroup_attr_pretty, 0, 0 +$1.DeviceDeny, config_parse_unit_cgroup_attr_pretty, 0, 0 +$1.BlockIOWeight, config_parse_unit_cgroup_attr_pretty, 0, 0 +$1.BlockIOReadBandwidth, config_parse_unit_cgroup_attr_pretty, 0, 0 +$1.BlockIOWriteBandwidth, config_parse_unit_cgroup_attr_pretty, 0, 0' +)m4_dnl Unit.Description, config_parse_unit_string_printf, 0, offsetof(Unit, description) Unit.Documentation, config_parse_documentation, 0, offsetof(Unit, documentation) Unit.SourcePath, config_parse_path, 0, offsetof(Unit, source_path) @@ -123,6 +125,7 @@ Unit.OnFailureIsolate, config_parse_bool, 0, Unit.IgnoreOnIsolate, config_parse_bool, 0, offsetof(Unit, ignore_on_isolate) Unit.IgnoreOnSnapshot, config_parse_bool, 0, offsetof(Unit, ignore_on_snapshot) Unit.JobTimeoutSec, config_parse_sec, 0, offsetof(Unit, job_timeout) +Unit.Slice, config_parse_unit_slice, 0, 0 Unit.ConditionPathExists, config_parse_unit_condition_path, CONDITION_PATH_EXISTS, 0 Unit.ConditionPathExistsGlob, config_parse_unit_condition_path, CONDITION_PATH_EXISTS_GLOB, 0 Unit.ConditionPathIsDirectory, config_parse_unit_condition_path, CONDITION_PATH_IS_DIRECTORY, 0 @@ -172,6 +175,7 @@ Service.NotifyAccess, config_parse_notify_access, 0, Service.Sockets, config_parse_service_sockets, 0, 0 Service.FsckPassNo, config_parse_fsck_passno, 0, offsetof(Service, fsck_passno) EXEC_CONTEXT_CONFIG_ITEMS(Service)m4_dnl +CGROUP_CONTEXT_CONFIG_ITEMS(Service)m4_dnl KILL_CONTEXT_CONFIG_ITEMS(Service)m4_dnl m4_dnl Socket.ListenStream, config_parse_socket_listen, SOCKET_SOCKET, 0 @@ -214,6 +218,7 @@ Socket.SmackLabel, config_parse_string, 0, Socket.SmackLabelIPIn, config_parse_string, 0, offsetof(Socket, smack_ip_in) Socket.SmackLabelIPOut, config_parse_string, 0, offsetof(Socket, smack_ip_out) EXEC_CONTEXT_CONFIG_ITEMS(Socket)m4_dnl +CGROUP_CONTEXT_CONFIG_ITEMS(Socket)m4_dnl KILL_CONTEXT_CONFIG_ITEMS(Socket)m4_dnl m4_dnl Mount.What, config_parse_string, 0, offsetof(Mount, parameters_fragment.what) @@ -224,6 +229,7 @@ Mount.FsckPassNo, config_parse_fsck_passno, 0, Mount.TimeoutSec, config_parse_sec, 0, offsetof(Mount, timeout_usec) Mount.DirectoryMode, config_parse_mode, 0, offsetof(Mount, directory_mode) EXEC_CONTEXT_CONFIG_ITEMS(Mount)m4_dnl +CGROUP_CONTEXT_CONFIG_ITEMS(Mount)m4_dnl KILL_CONTEXT_CONFIG_ITEMS(Mount)m4_dnl m4_dnl Automount.Where, config_parse_path, 0, offsetof(Automount, where) @@ -233,6 +239,7 @@ Swap.What, config_parse_path, 0, Swap.Priority, config_parse_int, 0, offsetof(Swap, parameters_fragment.priority) Swap.TimeoutSec, config_parse_sec, 0, offsetof(Swap, timeout_usec) EXEC_CONTEXT_CONFIG_ITEMS(Swap)m4_dnl +CGROUP_CONTEXT_CONFIG_ITEMS(Swap)m4_dnl KILL_CONTEXT_CONFIG_ITEMS(Swap)m4_dnl m4_dnl Timer.OnCalendar, config_parse_timer, 0, 0 @@ -251,6 +258,8 @@ Path.DirectoryNotEmpty, config_parse_path_spec, 0, Path.Unit, config_parse_trigger_unit, 0, 0 Path.MakeDirectory, config_parse_bool, 0, offsetof(Path, make_directory) Path.DirectoryMode, config_parse_mode, 0, offsetof(Path, directory_mode) +m4_dnl +CGROUP_CONTEXT_CONFIG_ITEMS(Slice)m4_dnl m4_dnl The [Install] section is ignored here. Install.Alias, NULL, 0, 0 Install.WantedBy, NULL, 0, 0 diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index e2015ed58f..4a835b6e8b 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -2058,6 +2058,48 @@ int config_parse_syscall_filter(const char *unit, return 0; } +int config_parse_unit_slice( + const char *unit, + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + _cleanup_free_ char *k = NULL; + Unit *u = userdata, *slice; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(u); + + k = unit_name_printf(u, rvalue); + if (!k) + log_syntax(unit, LOG_ERR, filename, line, EINVAL, + "Failed to resolve unit specifiers on %s. Ignoring.", rvalue); + + r = manager_load_unit(u->manager, k ? k : rvalue, NULL, NULL, &slice); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, -r, + "Failed to load slice unit %s. Ignoring.", k ? k : rvalue); + return 0; + } + + if (slice->type != UNIT_SLICE) { + log_syntax(unit, LOG_ERR, filename, line, EINVAL, + "Slice unit %s is not a slice. Ignoring.", k ? k : rvalue); + return 0; + } + + unit_ref_set(&u->slice, slice); + return 0; +} + #define FOLLOW_MAX 8 static int open_follow(char **filename, FILE **_f, Set *names, char **_final) { @@ -2446,6 +2488,7 @@ void unit_dump_config_items(FILE *f) { { config_parse_unit_condition_path, "CONDITION" }, { config_parse_unit_condition_string, "CONDITION" }, { config_parse_unit_condition_null, "CONDITION" }, + { config_parse_unit_slice, "SLICE" }, }; const char *prev = NULL; diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h index ff7f22a6f0..f9677baa0f 100644 --- a/src/core/load-fragment.h +++ b/src/core/load-fragment.h @@ -78,6 +78,7 @@ int config_parse_unit_cgroup_attr_pretty(const char *unit, const char *filename, int config_parse_unit_requires_mounts_for(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_syscall_filter(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_environ(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_slice(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); /* gperf prototypes */ const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, unsigned length); diff --git a/src/core/mount.c b/src/core/mount.c index 0ad3d951a5..e21e774d4d 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -647,6 +647,10 @@ static int mount_add_extras(Mount *m) { return r; } + r = unit_add_default_slice(u); + if (r < 0) + return r; + r = unit_add_default_cgroups(u); if (r < 0) return r; diff --git a/src/core/service.c b/src/core/service.c index dadd98123c..ac8cdb2c31 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -1225,6 +1225,10 @@ static int service_load(Unit *u) { if (r < 0) return r; + r = unit_add_default_slice(u); + if (r < 0) + return r; + r = unit_add_default_cgroups(u); if (r < 0) return r; diff --git a/src/core/slice.c b/src/core/slice.c new file mode 100644 index 0000000000..c1c33fe5c6 --- /dev/null +++ b/src/core/slice.c @@ -0,0 +1,298 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +#include "unit.h" +#include "slice.h" +#include "load-fragment.h" +#include "log.h" +#include "dbus-slice.h" +#include "special.h" +#include "unit-name.h" + +static const UnitActiveState state_translation_table[_SLICE_STATE_MAX] = { + [SLICE_DEAD] = UNIT_INACTIVE, + [SLICE_ACTIVE] = UNIT_ACTIVE +}; + +static void slice_set_state(Slice *t, SliceState state) { + SliceState old_state; + assert(t); + + old_state = t->state; + t->state = state; + + if (state != old_state) + log_debug("%s changed %s -> %s", + UNIT(t)->id, + slice_state_to_string(old_state), + slice_state_to_string(state)); + + unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state], true); +} + +static int slice_add_slice_link(Slice *s) { + char *a, *dash; + int r; + Unit *parent; + + assert(s); + + if (UNIT_DEREF(UNIT(s)->slice)) + return 0; + + a = strdupa(UNIT(s)->id); + + dash = strrchr(a, '-'); + if (!dash) + return 0; + + strcpy(dash, ".slice"); + + r = manager_load_unit(UNIT(s)->manager, a, NULL, NULL, &parent); + if (r < 0) + return r; + + unit_ref_set(&UNIT(s)->slice, parent); + return 0; +} + +static int slice_add_default_dependencies(Slice *s) { + int r; + + assert(s); + + /* Make sure slices are unloaded on shutdown */ + r = unit_add_dependency_by_name(UNIT(s), UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true); + if (r < 0) + return r; + + return 0; +} + +static int slice_verify(Slice *s) { + assert(s); + + if (UNIT(s)->load_state != UNIT_LOADED) + return 0; + + if (UNIT_DEREF(UNIT(s)->slice)) { + char *a, *dash; + + a = strdupa(UNIT(s)->id); + dash = strrchr(a, '-'); + if (dash) { + strcpy(dash, ".slice"); + + if (!unit_has_name(UNIT_DEREF(UNIT(s)->slice), a)) { + log_error_unit(UNIT(s)->id, + "%s located outside its parent slice. Refusing.", UNIT(s)->id); + return -EINVAL; + } + } + } + + return 0; +} + +static int slice_load(Unit *u) { + Slice *s = SLICE(u); + int r; + + assert(s); + + r = unit_load_fragment_and_dropin(u); + if (r < 0) + return r; + + /* This is a new unit? Then let's add in some extras */ + if (u->load_state == UNIT_LOADED) { + + r = slice_add_slice_link(s); + if (r < 0) + return r; + + if (u->default_dependencies) { + r = slice_add_default_dependencies(s); + if (r < 0) + return r; + } + + r = unit_add_default_cgroups(UNIT(s)); + if (r < 0) + return r; + } + + return slice_verify(s); +} + +static int slice_coldplug(Unit *u) { + Slice *t = SLICE(u); + + assert(t); + assert(t->state == SLICE_DEAD); + + if (t->deserialized_state != t->state) + slice_set_state(t, t->deserialized_state); + + return 0; +} + +static void slice_dump(Unit *u, FILE *f, const char *prefix) { + Slice *t = SLICE(u); + + assert(t); + assert(f); + + fprintf(f, + "%sSlice State: %s\n", + prefix, slice_state_to_string(t->state)); +} + +static int slice_start(Unit *u) { + Slice *t = SLICE(u); + int r; + + assert(t); + assert(t->state == SLICE_DEAD); + + r = cgroup_bonding_realize_list(u->cgroup_bondings); + if (r < 0) + return r; + + cgroup_attribute_apply_list(u->cgroup_attributes, u->cgroup_bondings); + + slice_set_state(t, SLICE_ACTIVE); + return 0; +} + +static int slice_stop(Unit *u) { + Slice *t = SLICE(u); + + assert(t); + assert(t->state == SLICE_ACTIVE); + + /* We do not need to trim the cgroup explicitly, unit_notify() + * will do that for us anyway. */ + + slice_set_state(t, SLICE_DEAD); + return 0; +} + +static int slice_kill(Unit *u, KillWho who, int signo, DBusError *error) { + return unit_kill_common(u, who, signo, -1, -1, error); +} + +static int slice_serialize(Unit *u, FILE *f, FDSet *fds) { + Slice *s = SLICE(u); + + assert(s); + assert(f); + assert(fds); + + unit_serialize_item(u, f, "state", slice_state_to_string(s->state)); + return 0; +} + +static int slice_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) { + Slice *s = SLICE(u); + + assert(u); + assert(key); + assert(value); + assert(fds); + + if (streq(key, "state")) { + SliceState state; + + state = slice_state_from_string(value); + if (state < 0) + log_debug("Failed to parse state value %s", value); + else + s->deserialized_state = state; + + } else + log_debug("Unknown serialization key '%s'", key); + + return 0; +} + +_pure_ static UnitActiveState slice_active_state(Unit *u) { + assert(u); + + return state_translation_table[SLICE(u)->state]; +} + +_pure_ static const char *slice_sub_state_to_string(Unit *u) { + assert(u); + + return slice_state_to_string(SLICE(u)->state); +} + +static const char* const slice_state_table[_SLICE_STATE_MAX] = { + [SLICE_DEAD] = "dead", + [SLICE_ACTIVE] = "active" +}; + +DEFINE_STRING_TABLE_LOOKUP(slice_state, SliceState); + +const UnitVTable slice_vtable = { + .object_size = sizeof(Slice), + .sections = + "Unit\0" + "Slice\0" + "Install\0", + + .no_alias = true, + .no_instances = true, + + .load = slice_load, + .coldplug = slice_coldplug, + + .dump = slice_dump, + + .start = slice_start, + .stop = slice_stop, + + .kill = slice_kill, + + .serialize = slice_serialize, + .deserialize_item = slice_deserialize_item, + + .active_state = slice_active_state, + .sub_state_to_string = slice_sub_state_to_string, + + .bus_interface = "org.freedesktop.systemd1.Slice", + .bus_message_handler = bus_slice_message_handler, + + .status_message_formats = { + .finished_start_job = { + [JOB_DONE] = "Installed slice %s.", + [JOB_DEPENDENCY] = "Dependency failed for %s.", + }, + .finished_stop_job = { + [JOB_DONE] = "Deinstalled slice %s.", + }, + }, +}; diff --git a/src/core/slice.h b/src/core/slice.h new file mode 100644 index 0000000000..4320a6354b --- /dev/null +++ b/src/core/slice.h @@ -0,0 +1,44 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +typedef struct Slice Slice; + +#include "unit.h" + +typedef enum SliceState { + SLICE_DEAD, + SLICE_ACTIVE, + _SLICE_STATE_MAX, + _SLICE_STATE_INVALID = -1 +} SliceState; + +struct Slice { + Unit meta; + + SliceState state, deserialized_state; +}; + +extern const UnitVTable slice_vtable; + +const char* slice_state_to_string(SliceState i) _const_; +SliceState slice_state_from_string(const char *s) _pure_; diff --git a/src/core/socket.c b/src/core/socket.c index 37ca228e6b..2b3b6813ca 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -395,7 +395,12 @@ static int socket_load(Unit *u) { if ((r = unit_add_exec_dependencies(u, &s->exec_context)) < 0) return r; - if ((r = unit_add_default_cgroups(u)) < 0) + r = unit_add_default_slice(u); + if (r < 0) + return r; + + r = unit_add_default_cgroups(u); + if (r < 0) return r; if (UNIT(s)->default_dependencies) diff --git a/src/core/special.h b/src/core/special.h index a9b50bce05..e183056a20 100644 --- a/src/core/special.h +++ b/src/core/special.h @@ -113,3 +113,6 @@ #define SPECIAL_RUNLEVEL3_TARGET "runlevel3.target" #define SPECIAL_RUNLEVEL4_TARGET "runlevel4.target" #define SPECIAL_RUNLEVEL5_TARGET "runlevel5.target" + +/* Where we add all our system units by default */ +#define SPECIAL_SYSTEM_SLICE "system.slice" diff --git a/src/core/swap.c b/src/core/swap.c index d503fe20df..d6721a6b31 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -287,6 +287,10 @@ static int swap_load(Unit *u) { if (r < 0) return r; + r = unit_add_default_slice(u); + if (r < 0) + return r; + r = unit_add_default_cgroups(u); if (r < 0) return r; diff --git a/src/core/unit.c b/src/core/unit.c index 9b36b225fa..b97158ff06 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -60,7 +60,8 @@ const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = { [UNIT_AUTOMOUNT] = &automount_vtable, [UNIT_SNAPSHOT] = &snapshot_vtable, [UNIT_SWAP] = &swap_vtable, - [UNIT_PATH] = &path_vtable + [UNIT_PATH] = &path_vtable, + [UNIT_SLICE] = &slice_vtable }; Unit *unit_new(Manager *m, size_t size) { @@ -853,6 +854,7 @@ int unit_add_default_target_dependency(Unit *u, Unit *target) { } static int unit_add_default_dependencies(Unit *u) { + static const UnitDependency deps[] = { UNIT_REQUIRED_BY, UNIT_REQUIRED_BY_OVERRIDABLE, @@ -868,9 +870,17 @@ static int unit_add_default_dependencies(Unit *u) { assert(u); for (k = 0; k < ELEMENTSOF(deps); k++) - SET_FOREACH(target, u->dependencies[deps[k]], i) - if ((r = unit_add_default_target_dependency(u, target)) < 0) + SET_FOREACH(target, u->dependencies[deps[k]], i) { + r = unit_add_default_target_dependency(u, target); + if (r < 0) return r; + } + + if (u->default_dependencies && UNIT_DEREF(u->slice)) { + r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_WANTS, UNIT_DEREF(u->slice), true); + if (r < 0) + return r; + } return 0; } @@ -1977,10 +1987,17 @@ static int unit_add_cgroup(Unit *u, CGroupBonding *b) { } char *unit_default_cgroup_path(Unit *u) { - _cleanup_free_ char *escaped_instance = NULL; + _cleanup_free_ char *escaped_instance = NULL, *slice = NULL; + int r; assert(u); + if (UNIT_DEREF(u->slice)) { + r = cg_slice_to_path(UNIT_DEREF(u->slice)->id, &slice); + if (r < 0) + return NULL; + } + escaped_instance = cg_escape(u->id); if (!escaped_instance) return NULL; @@ -1996,9 +2013,13 @@ char *unit_default_cgroup_path(Unit *u) { if (!escaped_template) return NULL; - return strjoin(u->manager->cgroup_hierarchy, "/", escaped_template, "/", escaped_instance, NULL); + return strjoin(u->manager->cgroup_hierarchy, "/", + slice ? slice : "", slice ? "/" : "", + escaped_template, "/", escaped_instance, NULL); } else - return strjoin(u->manager->cgroup_hierarchy, "/", escaped_instance, NULL); + return strjoin(u->manager->cgroup_hierarchy, "/", + slice ? slice : "", slice ? "/" : "", + escaped_instance, NULL); } int unit_add_cgroup_from_text(Unit *u, const char *name, bool overwrite, CGroupBonding **ret) { @@ -2143,6 +2164,26 @@ fail: return r; } +int unit_add_default_slice(Unit *u) { + Unit *slice; + int r; + + assert(u); + + if (UNIT_DEREF(u->slice)) + return 0; + + if (u->manager->running_as != SYSTEMD_SYSTEM) + return 0; + + r = manager_load_unit(u->manager, SPECIAL_SYSTEM_SLICE, NULL, NULL, &slice); + if (r < 0) + return r; + + unit_ref_set(&u->slice, slice); + return 0; +} + int unit_add_default_cgroups(Unit *u) { CGroupAttribute *a; char **c; diff --git a/src/core/unit.h b/src/core/unit.h index b04475e4fb..81b8adbfdc 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -118,6 +118,15 @@ enum UnitDependency { #include "cgroup.h" #include "cgroup-attr.h" +struct UnitRef { + /* Keeps tracks of references to a unit. This is useful so + * that we can merge two units if necessary and correct all + * references to them */ + + Unit* unit; + LIST_FIELDS(UnitRef, refs); +}; + struct Unit { Manager *manager; @@ -168,6 +177,8 @@ struct Unit { CGroupBonding *cgroup_bondings; CGroupAttribute *cgroup_attributes; + UnitRef slice; + /* Per type list */ LIST_FIELDS(Unit, units_by_type); @@ -240,15 +251,6 @@ struct Unit { bool in_audit:1; }; -struct UnitRef { - /* Keeps tracks of references to a unit. This is useful so - * that we can merge two units if necessary and correct all - * references to them */ - - Unit* unit; - LIST_FIELDS(UnitRef, refs); -}; - struct UnitStatusMessageFormats { const char *starting_stopping[2]; const char *finished_start_job[_JOB_RESULT_MAX]; @@ -265,6 +267,7 @@ struct UnitStatusMessageFormats { #include "snapshot.h" #include "swap.h" #include "path.h" +#include "slice.h" struct UnitVTable { /* How much memory does an object of this unit type need */ @@ -433,6 +436,7 @@ DEFINE_CAST(AUTOMOUNT, Automount); DEFINE_CAST(SNAPSHOT, Snapshot); DEFINE_CAST(SWAP, Swap); DEFINE_CAST(PATH, Path); +DEFINE_CAST(SLICE, Slice); Unit *unit_new(Manager *m, size_t size); void unit_free(Unit *u); @@ -474,6 +478,8 @@ int unit_load_fragment_and_dropin(Unit *u); int unit_load_fragment_and_dropin_optional(Unit *u); int unit_load(Unit *unit); +int unit_add_default_slice(Unit *u); + const char *unit_description(Unit *u) _pure_; bool unit_has_name(Unit *u, const char *name); diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index 7af0c3c124..4f58affe38 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -1617,3 +1617,53 @@ bool cg_controller_is_valid(const char *p, bool allow_named) { return true; } + +int cg_slice_to_path(const char *unit, char **ret) { + _cleanup_free_ char *p = NULL, *s = NULL, *e = NULL; + const char *dash; + + assert(unit); + assert(ret); + + if (!unit_name_is_valid(unit, false)) + return -EINVAL; + + if (!endswith(unit, ".slice")) + return -EINVAL; + + p = unit_name_to_prefix(unit); + if (!p) + return -ENOMEM; + + dash = strchr(p, '-'); + while (dash) { + _cleanup_free_ char *escaped = NULL; + char n[dash - p + sizeof(".slice")]; + + strcpy(stpncpy(n, p, dash - p), ".slice"); + + if (!unit_name_is_valid(n, false)) + return -EINVAL; + + escaped = cg_escape(n); + if (!escaped) + return -ENOMEM; + + if (!strextend(&s, escaped, "/", NULL)) + return -ENOMEM; + + dash = strchr(dash+1, '-'); + } + + e = cg_escape(unit); + if (!e) + return -ENOMEM; + + if (!strextend(&s, e, NULL)) + return -ENOMEM; + + *ret = s; + s = NULL; + + return 0; +} diff --git a/src/shared/cgroup-util.h b/src/shared/cgroup-util.h index 5835e04075..84274e605d 100644 --- a/src/shared/cgroup-util.h +++ b/src/shared/cgroup-util.h @@ -112,3 +112,5 @@ char *cg_escape(const char *p); char *cg_unescape(const char *p) _pure_; bool cg_controller_is_valid(const char *p, bool allow_named); + +int cg_slice_to_path(const char *unit, char **ret); diff --git a/src/shared/unit-name.c b/src/shared/unit-name.c index a809713595..2d4cd8d9f3 100644 --- a/src/shared/unit-name.c +++ b/src/shared/unit-name.c @@ -44,6 +44,7 @@ static const char* const unit_type_table[_UNIT_TYPE_MAX] = { [UNIT_TIMER] = "timer", [UNIT_SWAP] = "swap", [UNIT_PATH] = "path", + [UNIT_SLICE] = "slice" }; DEFINE_STRING_TABLE_LOOKUP(unit_type, UnitType); @@ -184,6 +185,7 @@ char *unit_name_change_suffix(const char *n, const char *suffix) { assert(n); assert(unit_name_is_valid(n, true)); assert(suffix); + assert(suffix[0] == '.'); assert_se(e = strrchr(n, '.')); a = e - n; @@ -506,16 +508,18 @@ char *unit_name_mangle(const char *name) { return r; } -char *snapshot_name_mangle(const char *name) { +char *unit_name_mangle_with_suffix(const char *name, const char *suffix) { char *r, *t; const char *f; assert(name); + assert(suffix); + assert(suffix[0] == '.'); /* Similar to unit_name_mangle(), but is called when we know * that this is about snapshot units. */ - r = new(char, strlen(name) * 4 + 1 + sizeof(".snapshot")-1); + r = new(char, strlen(name) * 4 + strlen(suffix) + 1); if (!r) return NULL; @@ -528,8 +532,8 @@ char *snapshot_name_mangle(const char *name) { *(t++) = *f; } - if (!endswith(name, ".snapshot")) - strcpy(t, ".snapshot"); + if (!endswith(name, suffix)) + strcpy(t, suffix); else *t = 0; diff --git a/src/shared/unit-name.h b/src/shared/unit-name.h index 9eca8eb3c1..baa487a81d 100644 --- a/src/shared/unit-name.h +++ b/src/shared/unit-name.h @@ -41,6 +41,7 @@ enum UnitType { UNIT_TIMER, UNIT_SWAP, UNIT_PATH, + UNIT_SLICE, _UNIT_TYPE_MAX, _UNIT_TYPE_INVALID = -1 }; @@ -94,4 +95,4 @@ char *unit_name_to_path(const char *name); char *unit_dbus_path_from_name(const char *name); char *unit_name_mangle(const char *name); -char *snapshot_name_mangle(const char *name); +char *unit_name_mangle_with_suffix(const char *name, const char *suffix); diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index a453598c72..8d496ab709 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -3736,7 +3736,7 @@ static int snapshot(DBusConnection *bus, char **args) { dbus_error_init(&error); if (strv_length(args) > 1) - n = snapshot_name_mangle(args[1]); + n = unit_name_mangle_with_suffix(args[1], ".snapshot"); else n = strdup(""); if (!n) @@ -3811,7 +3811,7 @@ static int delete_snapshot(DBusConnection *bus, char **args) { _cleanup_free_ char *n = NULL; int r; - n = snapshot_name_mangle(*name); + n = unit_name_mangle_with_suffix(*name, ".snapshot"); if (!n) return log_oom(); diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c index c9634d42b0..d4d58b320b 100644 --- a/src/test/test-cgroup-util.c +++ b/src/test/test-cgroup-util.c @@ -170,6 +170,25 @@ static void test_controller_is_valid(void) { assert_se(!cg_controller_is_valid("tatü", false)); } +static void test_slice_to_path_one(const char *unit, const char *path, int error) { + _cleanup_free_ char *ret = NULL; + + assert_se(cg_slice_to_path(unit, &ret) == error); + assert_se(streq_ptr(ret, path)); +} + +static void test_slice_to_path(void) { + + test_slice_to_path_one("foobar.slice", "foobar.slice", 0); + test_slice_to_path_one("foobar-waldo.slice", "foobar.slice/foobar-waldo.slice", 0); + test_slice_to_path_one("foobar-waldo.service", NULL, -EINVAL); + test_slice_to_path_one("-.slice", NULL, -EINVAL); + test_slice_to_path_one("-foo-.slice", NULL, -EINVAL); + test_slice_to_path_one("-foo.slice", NULL, -EINVAL); + test_slice_to_path_one("a-b.slice", "a.slice/a-b.slice", 0); + test_slice_to_path_one("a-b-c-d-e.slice", "a.slice/a-b.slice/a-b-c.slice/a-b-c-d.slice/a-b-c-d-e.slice", 0); +} + int main(void) { test_path_decode_unit(); test_path_get_unit(); @@ -178,6 +197,7 @@ int main(void) { test_proc(); test_escape(); test_controller_is_valid(); + test_slice_to_path(); return 0; } -- cgit v1.2.1 From f2561e85982ed25b610cad6253599a051f9ec8e2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 18 Jun 2013 00:59:54 +0200 Subject: units: add default units for system.slice, user.slice, machine.slice --- Makefile.am | 7 +++++++ units/basic.target | 4 ++-- units/machine.slice | 13 +++++++++++++ units/slices.target | 12 ++++++++++++ units/system.slice | 11 +++++++++++ units/user.slice | 13 +++++++++++++ 6 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 units/machine.slice create mode 100644 units/slices.target create mode 100644 units/system.slice create mode 100644 units/user.slice diff --git a/Makefile.am b/Makefile.am index 5a285be343..f84236d8a0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -222,6 +222,7 @@ install-target-wants-hook: what="$(SYSINIT_TARGET_WANTS)" && wants=sysinit.target && $(add-wants) what="$(SOCKETS_TARGET_WANTS)" && wants=sockets.target && $(add-wants) what="$(TIMERS_TARGET_WANTS)" && wants=timers.target && $(add-wants) + what="$(SLICES_TARGET_WANTS)" && wants=slices.target && $(add-wants) define add-wants [ -z "$$what" ] || ( \ @@ -376,6 +377,10 @@ dist_systemunit_DATA = \ units/paths.target \ units/suspend.target \ units/swap.target \ + units/slices.target \ + units/system.slice \ + units/user.slice \ + units/machine.slice \ units/systemd-initctl.socket \ units/systemd-shutdownd.socket \ units/syslog.socket \ @@ -4181,6 +4186,8 @@ USER_UNIT_ALIASES += \ GENERAL_ALIASES += \ $(systemunitdir)/remote-fs.target $(pkgsysconfdir)/system/multi-user.target.wants/remote-fs.target \ $(systemunitdir)/getty@.service $(pkgsysconfdir)/system/getty.target.wants/getty@tty1.service \ + $(systemunitdir)/machine.slice $(pkgsysconfdir)/system/slices.target.wants/machine.slice \ + $(systemunitdir)/user.slice $(pkgsysconfdir)/system/slices.target.wants/user.slice \ $(pkgsysconfdir)/user $(sysconfdir)/xdg/systemd/user \ ../system-services/org.freedesktop.systemd1.service $(dbussessionservicedir)/org.freedesktop.systemd1.service diff --git a/units/basic.target b/units/basic.target index 6b9cfe4c97..d7c68f4e2c 100644 --- a/units/basic.target +++ b/units/basic.target @@ -9,6 +9,6 @@ Description=Basic System Documentation=man:systemd.special(7) Requires=sysinit.target -Wants=sockets.target timers.target paths.target -After=sysinit.target sockets.target timers.target paths.target +Wants=sockets.target timers.target paths.target slices.target +After=sysinit.target sockets.target timers.target paths.target slices.target RefuseManualStart=yes diff --git a/units/machine.slice b/units/machine.slice new file mode 100644 index 0000000000..6b1754b9dc --- /dev/null +++ b/units/machine.slice @@ -0,0 +1,13 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Virtual Machine and Container Slice +Documentation=man:systemd.special(7) + +[Install] +WantedBy=slices.target diff --git a/units/slices.target b/units/slices.target new file mode 100644 index 0000000000..cbfdba0055 --- /dev/null +++ b/units/slices.target @@ -0,0 +1,12 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Slices +Documentation=man:systemd.special(7) +Wants=system.slice +After=system.slice diff --git a/units/system.slice b/units/system.slice new file mode 100644 index 0000000000..f78ecb4388 --- /dev/null +++ b/units/system.slice @@ -0,0 +1,11 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=System Slice +Documentation=man:systemd.special(7) +DefaultDependencies=no diff --git a/units/user.slice b/units/user.slice new file mode 100644 index 0000000000..dfaa44bcac --- /dev/null +++ b/units/user.slice @@ -0,0 +1,13 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=User and Session Slice +Documentation=man:systemd.special(7) + +[Install] +WantedBy=slices.target -- cgit v1.2.1 From 4ec9a8a48d61266638524a7cbc2c4763a9c92e2c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 18 Jun 2013 01:00:13 +0200 Subject: core: expose a "Slice" property on Unit objects on the bus --- src/core/dbus-unit.c | 20 ++++++++++++++++++++ src/core/dbus-unit.h | 1 + 2 files changed, 21 insertions(+) diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index 575f8eb36a..b7391b5506 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -81,6 +81,25 @@ static int bus_unit_append_following(DBusMessageIter *i, const char *property, v return 0; } +static int bus_unit_append_slice(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + const char *d; + + assert(i); + assert(property); + assert(u); + + if (UNIT_DEREF(u->slice)) + d = UNIT_DEREF(u->slice)->id; + else + d = ""; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d)) + return -ENOMEM; + + return 0; +} + static int bus_unit_append_dependencies(DBusMessageIter *i, const char *property, void *data) { Unit *u; Iterator j; @@ -1255,6 +1274,7 @@ const BusProperty bus_unit_properties[] = { { "Id", bus_property_append_string, "s", offsetof(Unit, id), true }, { "Names", bus_unit_append_names, "as", 0 }, { "Following", bus_unit_append_following, "s", 0 }, + { "Slice", bus_unit_append_slice, "s", 0 }, { "Requires", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRES]), true }, { "RequiresOverridable", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRES_OVERRIDABLE]), true }, { "Requisite", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUISITE]), true }, diff --git a/src/core/dbus-unit.h b/src/core/dbus-unit.h index acd1ddbe78..83932c5a6c 100644 --- a/src/core/dbus-unit.h +++ b/src/core/dbus-unit.h @@ -64,6 +64,7 @@ " \n" \ " \n" \ " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ -- cgit v1.2.1 From 702a2d8f6a90b999cef0fbf75a226a770f863b00 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 18 Jun 2013 02:07:35 +0200 Subject: core: unref slice ref after use --- src/core/unit.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/unit.c b/src/core/unit.c index b97158ff06..90ff43da66 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -416,6 +416,8 @@ void unit_free(Unit *u) { condition_free_list(u->conditions); + unit_ref_unset(&u->slice); + while (u->refs) unit_ref_unset(u->refs); -- cgit v1.2.1 From 214daa72cb0c72ea78d1eccd5ffe630a1e04b2f7 Mon Sep 17 00:00:00 2001 From: Sean McGovern Date: Wed, 12 Jun 2013 09:32:47 -0400 Subject: udev: handle network controllers in nonstandard domains Onboard network controllers are not always on PCI domain 0. [Kay: use int instead of long, add [P] to slot naming, remove sysname var] --- src/udev/udev-builtin-net_id.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c index 5719021e93..5b732bb418 100644 --- a/src/udev/udev-builtin-net_id.c +++ b/src/udev/udev-builtin-net_id.c @@ -35,13 +35,16 @@ * o -- on-board device index number * s[f][d] -- hotplug slot index number * x -- MAC address - * ps[f][d] -- PCI geographical location - * ps[f][u][..][c][i] + * [P]ps[f][d] + * -- PCI geographical location + * [P]ps[f][u][..][c][i] * -- USB port number chain * * All multi-function PCI devices will carry the [f] number in the * device name, including the function 0 device. * + * When using PCI geography, The PCI domain is only prepended when it is not 0. + * * For USB devices the full chain of port numbers of hubs is composed. If the * name gets longer than the maximum number of 15 characters, the name is not * exported. @@ -163,6 +166,7 @@ out: static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { struct udev *udev = udev_device_get_udev(names->pcidev); + unsigned int domain; unsigned int bus; unsigned int slot; unsigned int func; @@ -178,7 +182,7 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { int hotplug_slot = 0; int err = 0; - if (sscanf(udev_device_get_sysname(names->pcidev), "0000:%x:%x.%d", &bus, &slot, &func) != 3) + if (sscanf(udev_device_get_sysname(names->pcidev), "%x:%x:%x.%d", &domain, &bus, &slot, &func) != 4) return -ENOENT; /* kernel provided multi-device index */ @@ -188,7 +192,10 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { /* compose a name based on the raw kernel's PCI bus, slot numbers */ s = names->pci_path; - l = strpcpyf(&s, sizeof(names->pci_path), "p%ds%d", bus, slot); + l = sizeof(names->pci_path); + if (domain > 0) + l = strpcpyf(&s, l, "P%d", domain); + l = strpcpyf(&s, l, "p%ds%d", bus, slot); if (func > 0 || is_pci_multifunction(names->pcidev)) l = strpcpyf(&s, l, "f%d", func); if (dev_id > 0) @@ -236,7 +243,10 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { if (hotplug_slot > 0) { s = names->pci_slot; - l = strpcpyf(&s, sizeof(names->pci_slot), "s%d", hotplug_slot); + l = sizeof(names->pci_slot); + if (domain > 0) + l = strpcpyf(&s, l, "P%d", domain); + l = strpcpyf(&s, l, "s%d", hotplug_slot); if (func > 0 || is_pci_multifunction(names->pcidev)) l = strpcpyf(&s, l, "f%d", func); if (dev_id > 0) -- cgit v1.2.1 From 718fe4b1d50f89cbc11318edb0c2c3de9be2ac34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 18 Jun 2013 08:48:14 -0400 Subject: journalctl: properly print headers of empty journals --- TODO | 2 -- src/journal/journal-file.c | 13 +++++++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/TODO b/TODO index cfd2763a40..a6c2c15aa1 100644 --- a/TODO +++ b/TODO @@ -11,8 +11,6 @@ Bugfixes: * properly handle .mount unit state tracking when two mount points are stacked one on top of another on the exact same mount point. -* fix --header to files without entries (see test-journal output). - Fedora 19: * external: maybe it is time to patch procps so that "ps" links to diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index ca217f93fe..12364030d9 100644 --- a/src/journal/journal-file.c +++ b/src/journal/journal-file.c @@ -2270,6 +2270,15 @@ fail: log_error("File corrupt"); } +static const char* format_timestamp_safe(char *buf, size_t l, usec_t t) { + const char *x; + + x = format_timestamp(buf, l, t); + if (x) + return x; + return " --- "; +} + void journal_file_print_header(JournalFile *f) { char a[33], b[33], c[33], d[33]; char x[FORMAT_TIMESTAMP_MAX], y[FORMAT_TIMESTAMP_MAX], z[FORMAT_TIMESTAMP_MAX]; @@ -2317,8 +2326,8 @@ void journal_file_print_header(JournalFile *f) { yes_no(journal_file_rotate_suggested(f, 0)), le64toh(f->header->head_entry_seqnum), le64toh(f->header->tail_entry_seqnum), - format_timestamp(x, sizeof(x), le64toh(f->header->head_entry_realtime)), - format_timestamp(y, sizeof(y), le64toh(f->header->tail_entry_realtime)), + format_timestamp_safe(x, sizeof(x), le64toh(f->header->head_entry_realtime)), + format_timestamp_safe(y, sizeof(y), le64toh(f->header->tail_entry_realtime)), format_timespan(z, sizeof(z), le64toh(f->header->tail_entry_monotonic), USEC_PER_MSEC), le64toh(f->header->n_objects), le64toh(f->header->n_entries)); -- cgit v1.2.1 From 55d32caf94d8df547ca763be52b0c35bb6388606 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 18 Jun 2013 16:06:05 +0200 Subject: update TODO --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index a6c2c15aa1..dfcd6747f4 100644 --- a/TODO +++ b/TODO @@ -24,6 +24,8 @@ Fedora 19: * localed: - localectl: support new converted x11→console keymaps +* when installing fedora with yum --installroot /var/run is a directory, not a symlink + Features: * when a service changes state make reflect that in the -- cgit v1.2.1 From fe004b7c3a8325eb8d5420c1b940a5ade2691417 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 18 Jun 2013 16:25:11 +0200 Subject: journal: add references to SSKG paper FSS is based on --- man/journalctl.xml | 5 ++++- man/journald.conf.xml | 12 +++++++++--- src/journal/fsprg.c | 6 ++++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/man/journalctl.xml b/man/journalctl.xml index 7a8d4b2dcc..564634b757 100644 --- a/man/journalctl.xml +++ b/man/journalctl.xml @@ -593,7 +593,10 @@ sealing key is stored in the journal data directory and shall remain on the host. The verification key should be - stored externally. + stored externally. Also see the + option in + journald.conf5 + for details. diff --git a/man/journald.conf.xml b/man/journald.conf.xml index fe47fdffec..26f47f8975 100644 --- a/man/journald.conf.xml +++ b/man/journald.conf.xml @@ -130,9 +130,15 @@ by journalctl1's - command), forward secure sealing (FSS) for - all persistent journal files is - enabled. + command), forward secure sealing (FSS) + for all persistent journal files is + enabled. FSS is based on Seekable + Sequential Key Generators by + G. A. Marson and B. Poettering and + may be used to protect journal files + from unnoticed + alteration. diff --git a/src/journal/fsprg.c b/src/journal/fsprg.c index 6817a629c8..dd9a242561 100644 --- a/src/journal/fsprg.c +++ b/src/journal/fsprg.c @@ -19,7 +19,13 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA + */ + +/* + * See "Practical Secure Logging: Seekable Sequential Key Generators" + * by G. A. Marson, B. Poettering for details: * + * http://eprint.iacr.org/2013/397 */ #include -- cgit v1.2.1 From 422fa6500a44a222b655cd218a658f8a4f34a768 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 19 Jun 2013 18:08:14 -0400 Subject: cgls,loginctl,systemctl: fix -l Fixup for 98a6e13 "journalctl,loginctl,systemctl,systemd-cgls: add -l as alias for --full". --- src/cgls/cgls.c | 2 +- src/login/loginctl.c | 12 ++++++------ src/systemctl/systemctl.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/cgls/cgls.c b/src/cgls/cgls.c index f232731ab4..155c5cca7c 100644 --- a/src/cgls/cgls.c +++ b/src/cgls/cgls.c @@ -77,7 +77,7 @@ static int parse_argv(int argc, char *argv[]) { assert(argc >= 1); assert(argv); - while ((c = getopt_long(argc, argv, "hkaM:", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "hkalM:", options, NULL)) >= 0) { switch (c) { diff --git a/src/login/loginctl.c b/src/login/loginctl.c index 087e52d503..1b9723fdbf 100644 --- a/src/login/loginctl.c +++ b/src/login/loginctl.c @@ -1346,13 +1346,13 @@ static int parse_argv(int argc, char *argv[]) { { "version", no_argument, NULL, ARG_VERSION }, { "property", required_argument, NULL, 'p' }, { "all", no_argument, NULL, 'a' }, + { "full", no_argument, NULL, 'l' }, { "no-pager", no_argument, NULL, ARG_NO_PAGER }, { "kill-who", required_argument, NULL, ARG_KILL_WHO }, { "signal", required_argument, NULL, 's' }, { "host", required_argument, NULL, 'H' }, { "privileged", no_argument, NULL, 'P' }, { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD }, - { "full", no_argument, NULL, 'l' }, { NULL, 0, NULL, 0 } }; @@ -1361,7 +1361,7 @@ static int parse_argv(int argc, char *argv[]) { assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "hp:as:H:P", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "hp:als:H:P", options, NULL)) >= 0) { switch (c) { @@ -1395,6 +1395,10 @@ static int parse_argv(int argc, char *argv[]) { arg_all = true; break; + case 'l': + arg_full = true; + break; + case ARG_NO_PAGER: arg_no_pager = true; break; @@ -1424,10 +1428,6 @@ static int parse_argv(int argc, char *argv[]) { parse_user_at_host(optarg, &arg_user, &arg_host); break; - case 'l': - arg_full = true; - break; - case '?': return -EINVAL; diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 8d496ab709..53033baae8 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -4872,7 +4872,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "ht:p:aqfs:H:Pn:o:i", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:Pn:o:i", options, NULL)) >= 0) { switch (c) { -- cgit v1.2.1 From c25b1ee6cd6d956a834ba50568436b3349320d43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 19 Jun 2013 18:09:54 -0400 Subject: core/dbus: properly export cgroup properties on sockets https://bugs.freedesktop.org/show_bug.cgi?id=65945 --- src/core/dbus-socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c index 77d98ea0fd..973f905149 100644 --- a/src/core/dbus-socket.c +++ b/src/core/dbus-socket.c @@ -205,7 +205,7 @@ DBusHandlerResult bus_socket_message_handler(Unit *u, DBusConnection *c, DBusMes { "org.freedesktop.systemd1.Socket", bus_socket_properties, s }, { "org.freedesktop.systemd1.Socket", bus_exec_context_properties, &s->exec_context }, { "org.freedesktop.systemd1.Socket", bus_kill_context_properties, &s->kill_context }, - { "org.freedesktop.systemd1.Socket", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Socket", bus_unit_cgroup_properties, u }, { NULL, } }; -- cgit v1.2.1 From 77f40f165cc60a1d6b8a3503e4b7e46814d5935e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Stelmach?= Date: Wed, 19 Jun 2013 14:59:02 +0200 Subject: Describe handling of an AF_UNIX socket MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Describe how to handle an AF_UNIX socket, with Accept set to false, received from systemd, upon exit. Signed-off-by: Łukasz Stelmach --- man/systemd.socket.xml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml index 6dc847df3f..f1e7d408ab 100644 --- a/man/systemd.socket.xml +++ b/man/systemd.socket.xml @@ -381,9 +381,15 @@ performance reasons, it is recommended to write new daemons only in a way that is suitable for - . This - option is mostly useful to allow - daemons designed for usage with + . A daemon + listening on an AF_UNIX socket may, but does not need to, call + close2 + or + shutdown2 + on the received socket before exiting. However, + it must not unlink the socket from a + filesystem. This option is mostly useful + to allow daemons designed for usage with inetd8, to work unmodified with systemd socket activation. -- cgit v1.2.1 From 9444b1f20e311f073864d81e913bd4f32fe95cfd Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 20 Jun 2013 03:45:08 +0200 Subject: logind: add infrastructure to keep track of machines, and move to slices - This changes all logind cgroup objects to use slice objects rather than fixed croup locations. - logind can now collect minimal information about running VMs/containers. As fixed cgroup locations can no longer be used we need an entity that keeps track of machine cgroups in whatever slice they might be located. Since logind already keeps track of users, sessions and seats this is a trivial addition. - nspawn will now register with logind and pass various bits of metadata along. A new option "--slice=" has been added to place the container in a specific slice. - loginctl gained commands to list, introspect and terminate machines. - user.slice and machine.slice will now be pulled in by logind.service, since only logind.service requires this slice. --- Makefile.am | 13 +- TODO | 19 +- catalog/systemd.catalog | 18 ++ src/cgls/cgls.c | 9 +- src/core/cgroup.c | 69 +++--- src/core/dbus-manager.c | 2 - src/core/dbus-unit.c | 5 +- src/core/manager.h | 2 +- src/core/service.c | 2 +- src/core/socket.c | 4 +- src/core/special.h | 4 +- src/core/unit-printf.c | 28 +-- src/core/unit.c | 27 ++- src/core/unit.h | 3 + src/login/loginctl.c | 382 ++++++++++++++++++++++++++++++--- src/login/logind-dbus.c | 449 ++++++++++++++++++++++++++++++++++++++- src/login/logind-machine-dbus.c | 315 ++++++++++++++++++++++++++++ src/login/logind-machine.c | 455 ++++++++++++++++++++++++++++++++++++++++ src/login/logind-machine.h | 80 +++++++ src/login/logind-seat-dbus.c | 6 +- src/login/logind-session-dbus.c | 8 +- src/login/logind-session.c | 165 +++++++++++---- src/login/logind-session.h | 9 +- src/login/logind-user-dbus.c | 10 +- src/login/logind-user.c | 150 +++++++------ src/login/logind-user.h | 1 + src/login/logind.c | 340 +++++++++++++++++------------- src/login/logind.h | 13 +- src/login/sd-login.c | 4 +- src/login/user-sessions.c | 121 +++++++++-- src/nspawn/nspawn.c | 171 +++++---------- src/shared/cgroup-util.c | 220 +++++++++---------- src/shared/cgroup-util.h | 3 - src/shared/unit-name.c | 7 +- src/systemd/sd-bus.h | 6 + src/systemd/sd-messages.h | 6 + src/test/test-cgroup-util.c | 89 +++++--- units/machine.slice | 4 +- units/system.slice | 1 + units/systemd-logind.service.in | 3 +- units/user.slice | 4 +- 41 files changed, 2526 insertions(+), 701 deletions(-) create mode 100644 src/login/logind-machine-dbus.c create mode 100644 src/login/logind-machine.c create mode 100644 src/login/logind-machine.h diff --git a/Makefile.am b/Makefile.am index f84236d8a0..ff5a129da8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -379,8 +379,6 @@ dist_systemunit_DATA = \ units/swap.target \ units/slices.target \ units/system.slice \ - units/user.slice \ - units/machine.slice \ units/systemd-initctl.socket \ units/systemd-shutdownd.socket \ units/syslog.socket \ @@ -1701,7 +1699,8 @@ systemd_nspawn_LDADD = \ libsystemd-capability.la \ libsystemd-shared.la \ libsystemd-daemon.la \ - libsystemd-id128-internal.la + libsystemd-id128-internal.la \ + libsystemd-bus.la # ------------------------------------------------------------------------------ systemd_stdio_bridge_SOURCES = \ @@ -3552,6 +3551,8 @@ systemd_logind_SOURCES = \ src/login/logind-seat.h \ src/login/logind-session.c \ src/login/logind-session.h \ + src/login/logind-machine.c \ + src/login/logind-machine.h \ src/login/logind-user.c \ src/login/logind-user.h \ src/login/logind-inhibit.c \ @@ -3559,6 +3560,7 @@ systemd_logind_SOURCES = \ src/login/logind-session-dbus.c \ src/login/logind-seat-dbus.c \ src/login/logind-user-dbus.c \ + src/login/logind-machine-dbus.c \ src/login/logind-acl.h nodist_systemd_logind_SOURCES = \ @@ -3574,6 +3576,7 @@ systemd_logind_LDADD = \ libsystemd-shared.la \ libsystemd-daemon.la \ libsystemd-dbus.la \ + libsystemd-id128-internal.la \ libudev.la if HAVE_ACL @@ -3710,6 +3713,8 @@ UNINSTALL_EXEC_HOOKS += libsystemd-login-uninstall-hook nodist_systemunit_DATA += \ units/systemd-logind.service \ units/systemd-user-sessions.service + units/user.slice \ + units/machine.slice dist_dbussystemservice_DATA += \ src/login/org.freedesktop.login1.service @@ -4186,8 +4191,6 @@ USER_UNIT_ALIASES += \ GENERAL_ALIASES += \ $(systemunitdir)/remote-fs.target $(pkgsysconfdir)/system/multi-user.target.wants/remote-fs.target \ $(systemunitdir)/getty@.service $(pkgsysconfdir)/system/getty.target.wants/getty@tty1.service \ - $(systemunitdir)/machine.slice $(pkgsysconfdir)/system/slices.target.wants/machine.slice \ - $(systemunitdir)/user.slice $(pkgsysconfdir)/system/slices.target.wants/user.slice \ $(pkgsysconfdir)/user $(sysconfdir)/xdg/systemd/user \ ../system-services/org.freedesktop.systemd1.service $(dbussessionservicedir)/org.freedesktop.systemd1.service diff --git a/TODO b/TODO index dfcd6747f4..f0af723d08 100644 --- a/TODO +++ b/TODO @@ -28,20 +28,33 @@ Fedora 19: Features: +* move systemctl dump to systemd-analyze + +* libsystemd-logind: sd_session_is_active() and friends: verify + validity of session name before appending it to a path + +* logind: when a PAM client calls ReleaseSession() start a timeout and + kill the session entirely after that is reached. + +* gparted needs to disable auto-activation of mount units somehow, or + maybe we should stop doing auto-activiation of this after boot + entirely. https://bugzilla.gnome.org/show_bug.cgi?id=701676 + * when a service changes state make reflect that in the RUNNING/LISTENING states of its socket * slices: - - fix libsystemd-login to handle slices properly - add option to pam_systemd to move login session into a slice - - add call to logind's dbus intrface to register a machine (also, calls for listing them) + - remove ControlGroup= setting + - in sd_pid_get_owner_uid() fallback to query session file + - add api to determine slice of unit * when recursively showing the cgroup hierarchy, optionally also show the hierarchies of child processes * document logic of auto/noauto and fail/nofail in fstab in systemd.mount or systemd-fstab-generator man page -* we should properly escape hostnames we add into dbus server strings +* we should properly escape ssh hostnames we add into dbus server strings * something pulls in pcre as so dep into our daemons such as hostnamed. diff --git a/catalog/systemd.catalog b/catalog/systemd.catalog index 62635c87b0..dbeadb7dea 100644 --- a/catalog/systemd.catalog +++ b/catalog/systemd.catalog @@ -269,3 +269,21 @@ This does not interfere with mounting, but the pre-exisiting files in this directory become inaccessible. To see those over-mounted files, please manually mount the underlying file system to a secondary location. + +-- 24d8d4452573402496068381a6312df2 +Subject: A virtual machine or container has been started +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +The virtual machine @NAME@ with its leader PID @LEADER@ has been +started is now ready to use. + +-- 58432bd3bace477cb514b56381b8a758 +Subject: A virtual machine or container has been terminated +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +The virtual machine @NAME@ with its leader PID @LEADER@ has been +shut down. diff --git a/src/cgls/cgls.c b/src/cgls/cgls.c index 155c5cca7c..c3229ad2d3 100644 --- a/src/cgls/cgls.c +++ b/src/cgls/cgls.c @@ -34,6 +34,7 @@ #include "pager.h" #include "build.h" #include "output-mode.h" +#include "fileio.h" static bool arg_no_pager = false; static bool arg_kernel_threads = false; @@ -184,9 +185,11 @@ int main(int argc, char *argv[]) { r = show_cgroup_by_path(p, NULL, 0, arg_kernel_threads, output_flags); } else { - if (arg_machine) - r = cg_get_machine_path(arg_machine, &root); - else + if (arg_machine) { + char *m; + m = strappenda("/run/systemd/machines/", arg_machine); + r = parse_env_file(m, NEWLINE, "CGROUP", &root, NULL); + } else r = cg_get_root_path(&root); if (r < 0) { log_error("Failed to get %s path: %s", diff --git a/src/core/cgroup.c b/src/core/cgroup.c index a995d1436d..5065329739 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -32,6 +32,7 @@ #include "log.h" #include "strv.h" #include "path-util.h" +#include "special.h" int cgroup_bonding_realize(CGroupBonding *b) { int r; @@ -304,7 +305,8 @@ int cgroup_bonding_is_empty_list(CGroupBonding *first) { LIST_FOREACH(by_unit, b, first) { int r; - if ((r = cgroup_bonding_is_empty(b)) < 0) { + r = cgroup_bonding_is_empty(b); + if (r < 0) { /* If this returned -EAGAIN, then we don't know if the * group is empty, so let's see if another group can * tell us */ @@ -319,10 +321,9 @@ int cgroup_bonding_is_empty_list(CGroupBonding *first) { } int manager_setup_cgroup(Manager *m) { - _cleanup_free_ char *current = NULL, *path = NULL; - char suffix_buffer[sizeof("/systemd-") + DECIMAL_STR_MAX(pid_t)]; - const char *suffix; + _cleanup_free_ char *path = NULL; int r; + char *e, *a; assert(m); @@ -333,37 +334,30 @@ int manager_setup_cgroup(Manager *m) { } /* 1. Determine hierarchy */ - r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, ¤t); + free(m->cgroup_root); + m->cgroup_root = NULL; + + r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &m->cgroup_root); if (r < 0) { log_error("Cannot determine cgroup we are running in: %s", strerror(-r)); return r; } - if (m->running_as == SYSTEMD_SYSTEM) - suffix = NULL; - else { - sprintf(suffix_buffer, "/systemd-%lu", (unsigned long) getpid()); - suffix = suffix_buffer; + /* Already in /system.slice? If so, let's cut this off again */ + if (m->running_as == SYSTEMD_SYSTEM) { + e = endswith(m->cgroup_root, "/" SPECIAL_SYSTEM_SLICE); + if (e) + *e = 0; } - free(m->cgroup_hierarchy); - if (!suffix || endswith(current, suffix)) { - /* We probably got reexecuted and can continue to use our root cgroup */ - m->cgroup_hierarchy = current; - current = NULL; - } else { - /* We need a new root cgroup */ - if (streq(current, "/")) - m->cgroup_hierarchy = strdup(suffix); - else - m->cgroup_hierarchy = strappend(current, suffix); - - if (!m->cgroup_hierarchy) - return log_oom(); - } + /* And make sure to store away the root value without trailing + * slash, even for the root dir, so that we can easily prepend + * it everywhere. */ + if (streq(m->cgroup_root, "/")) + m->cgroup_root[0] = 0; /* 2. Show data */ - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_hierarchy, NULL, &path); + r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_root, NULL, &path); if (r < 0) { log_error("Cannot find cgroup mount point: %s", strerror(-r)); return r; @@ -382,8 +376,9 @@ int manager_setup_cgroup(Manager *m) { log_debug("Release agent already installed."); } - /* 4. Realize the group */ - r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_hierarchy, 0); + /* 4. Realize the system slice and put us in there */ + a = strappenda(m->cgroup_root, "/" SPECIAL_SYSTEM_SLICE); + r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, a, 0); if (r < 0) { log_error("Failed to create root cgroup hierarchy: %s", strerror(-r)); return r; @@ -402,30 +397,24 @@ int manager_setup_cgroup(Manager *m) { /* 6. Remove non-existing controllers from the default controllers list */ cg_shorten_controllers(m->default_controllers); - /* 7. Let's create the user and machine hierarchies - * right-away, so that people can inotify on them, if they - * wish, without this being racy. */ - if (m->running_as == SYSTEMD_SYSTEM) { - cg_create(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_hierarchy, "../user"); - cg_create(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_hierarchy, "../machine"); - } - return 0; } void manager_shutdown_cgroup(Manager *m, bool delete) { assert(m); - if (delete && m->cgroup_hierarchy) - cg_delete(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_hierarchy); + /* We can't really delete the group, since we are in it. But + * let's trim it. */ + if (delete && m->cgroup_root) + cg_trim(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_root, false); if (m->pin_cgroupfs_fd >= 0) { close_nointr_nofail(m->pin_cgroupfs_fd); m->pin_cgroupfs_fd = -1; } - free(m->cgroup_hierarchy); - m->cgroup_hierarchy = NULL; + free(m->cgroup_root); + m->cgroup_root = NULL; } int cgroup_bonding_get(Manager *m, const char *cgroup, CGroupBonding **bonding) { diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 25d38cc491..d41b6ae15f 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -301,7 +301,6 @@ " \n" \ " \n" \ " \n" \ - " \n" \ " \n" \ " \n" \ " \n" \ @@ -614,7 +613,6 @@ static const BusProperty bus_manager_properties[] = { { "ConfirmSpawn", bus_property_append_bool, "b", offsetof(Manager, confirm_spawn) }, { "ShowStatus", bus_property_append_bool, "b", offsetof(Manager, show_status) }, { "UnitPath", bus_property_append_strv, "as", offsetof(Manager, lookup_paths.unit_path), true }, - { "ControlGroupHierarchy", bus_property_append_string, "s", offsetof(Manager, cgroup_hierarchy), true }, { "DefaultControllers", bus_property_append_strv, "as", offsetof(Manager, default_controllers), true }, { "DefaultStandardOutput", bus_manager_append_exec_output, "s", offsetof(Manager, default_std_output) }, { "DefaultStandardError", bus_manager_append_exec_output, "s", offsetof(Manager, default_std_error) }, diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index b7391b5506..8a7ab349d1 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -89,10 +89,7 @@ static int bus_unit_append_slice(DBusMessageIter *i, const char *property, void assert(property); assert(u); - if (UNIT_DEREF(u->slice)) - d = UNIT_DEREF(u->slice)->id; - else - d = ""; + d = strempty(unit_slice_name(u)); if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d)) return -ENOMEM; diff --git a/src/core/manager.h b/src/core/manager.h index dcc4ebed92..e21c8f7abf 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -199,7 +199,7 @@ struct Manager { /* Data specific to the cgroup subsystem */ Hashmap *cgroup_bondings; /* path string => CGroupBonding object 1:n */ - char *cgroup_hierarchy; + char *cgroup_root; usec_t gc_queue_timestamp; int gc_marker; diff --git a/src/core/service.c b/src/core/service.c index ac8cdb2c31..a0c648a85b 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -220,7 +220,7 @@ static void service_close_socket_fd(Service *s) { static void service_connection_unref(Service *s) { assert(s); - if (!UNIT_DEREF(s->accept_socket)) + if (!UNIT_ISSET(s->accept_socket)) return; socket_connection_unref(SOCKET(UNIT_DEREF(s->accept_socket))); diff --git a/src/core/socket.c b/src/core/socket.c index 2b3b6813ca..2f25e25aa6 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -1005,7 +1005,7 @@ static int socket_open_fds(Socket *s) { if ((r = socket_instantiate_service(s)) < 0) return r; - if (UNIT_DEREF(s->service) && + if (UNIT_ISSET(s->service) && SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]) { r = label_get_create_label_from_exe(SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]->path, &label); @@ -1633,7 +1633,7 @@ static int socket_start(Unit *u) { return 0; /* Cannot run this without the service being around */ - if (UNIT_DEREF(s->service)) { + if (UNIT_ISSET(s->service)) { Service *service; service = SERVICE(UNIT_DEREF(s->service)); diff --git a/src/core/special.h b/src/core/special.h index e183056a20..337a0a43e9 100644 --- a/src/core/special.h +++ b/src/core/special.h @@ -114,5 +114,7 @@ #define SPECIAL_RUNLEVEL4_TARGET "runlevel4.target" #define SPECIAL_RUNLEVEL5_TARGET "runlevel5.target" -/* Where we add all our system units by default */ +/* Where we add all our system units, users and machines by default */ #define SPECIAL_SYSTEM_SLICE "system.slice" +#define SPECIAL_USER_SLICE "user.slice" +#define SPECIAL_MACHINE_SLICE "machine.slice" diff --git a/src/core/unit-printf.c b/src/core/unit-printf.c index 85a05b872a..caf51259d2 100644 --- a/src/core/unit-printf.c +++ b/src/core/unit-printf.c @@ -27,6 +27,8 @@ #include "unit-name.h" #include "unit-printf.h" #include "macro.h" +#include "cgroup-util.h" +#include "special.h" static char *specifier_prefix_and_instance(char specifier, void *data, void *userdata) { Unit *u = userdata; @@ -86,22 +88,22 @@ static char *specifier_cgroup(char specifier, void *data, void *userdata) { } static char *specifier_cgroup_root(char specifier, void *data, void *userdata) { + _cleanup_free_ char *p = NULL; Unit *u = userdata; - char *p; - assert(u); + const char *slice; + int r; - if (specifier == 'r') - return strdup(u->manager->cgroup_hierarchy); + assert(u); - if (path_get_parent(u->manager->cgroup_hierarchy, &p) < 0) - return strdup(""); + slice = unit_slice_name(u); + if (specifier == 'R' || !slice) + return strdup(u->manager->cgroup_root); - if (streq(p, "/")) { - free(p); - return strdup(""); - } + r = cg_slice_to_path(slice, &p); + if (r < 0) + return NULL; - return p; + return strjoin(u->manager->cgroup_root, "/", p, NULL); } static char *specifier_runtime(char specifier, void *data, void *userdata) { @@ -256,8 +258,8 @@ char *unit_full_printf(Unit *u, const char *format) { * * %f the the instance if set, otherwise the id * %c cgroup path of unit - * %r root cgroup path of this systemd instance (e.g. "/user/lennart/shared/systemd-4711") - * %R parent of root cgroup path (e.g. "/usr/lennart/shared") + * %r where units in this slice are place in the cgroup tree + * %R the root of this systemd's instance tree * %t the runtime directory to place sockets in (e.g. "/run" or $XDG_RUNTIME_DIR) * %U the UID of the configured user or running user * %u the username of the configured user or running user diff --git a/src/core/unit.c b/src/core/unit.c index 90ff43da66..f75045dc48 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -672,7 +672,8 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { "%s\tActive Exit Timestamp: %s\n" "%s\tInactive Enter Timestamp: %s\n" "%s\tGC Check Good: %s\n" - "%s\tNeed Daemon Reload: %s\n", + "%s\tNeed Daemon Reload: %s\n" + "%s\tSlice: %s\n", prefix, u->id, prefix, unit_description(u), prefix, strna(u->instance), @@ -683,7 +684,8 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { prefix, strna(format_timestamp(timestamp3, sizeof(timestamp3), u->active_exit_timestamp.realtime)), prefix, strna(format_timestamp(timestamp4, sizeof(timestamp4), u->inactive_enter_timestamp.realtime)), prefix, yes_no(unit_check_gc(u)), - prefix, yes_no(unit_need_daemon_reload(u))); + prefix, yes_no(unit_need_daemon_reload(u)), + prefix, strna(unit_slice_name(u))); SET_FOREACH(t, u->names, i) fprintf(f, "%s\tName: %s\n", prefix, t); @@ -878,7 +880,7 @@ static int unit_add_default_dependencies(Unit *u) { return r; } - if (u->default_dependencies && UNIT_DEREF(u->slice)) { + if (u->default_dependencies && UNIT_ISSET(u->slice)) { r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_WANTS, UNIT_DEREF(u->slice), true); if (r < 0) return r; @@ -1994,7 +1996,7 @@ char *unit_default_cgroup_path(Unit *u) { assert(u); - if (UNIT_DEREF(u->slice)) { + if (UNIT_ISSET(u->slice)) { r = cg_slice_to_path(UNIT_DEREF(u->slice)->id, &slice); if (r < 0) return NULL; @@ -2015,11 +2017,11 @@ char *unit_default_cgroup_path(Unit *u) { if (!escaped_template) return NULL; - return strjoin(u->manager->cgroup_hierarchy, "/", + return strjoin(u->manager->cgroup_root, "/", slice ? slice : "", slice ? "/" : "", escaped_template, "/", escaped_instance, NULL); } else - return strjoin(u->manager->cgroup_hierarchy, "/", + return strjoin(u->manager->cgroup_root, "/", slice ? slice : "", slice ? "/" : "", escaped_instance, NULL); } @@ -2172,7 +2174,7 @@ int unit_add_default_slice(Unit *u) { assert(u); - if (UNIT_DEREF(u->slice)) + if (UNIT_ISSET(u->slice)) return 0; if (u->manager->running_as != SYSTEMD_SYSTEM) @@ -2186,6 +2188,15 @@ int unit_add_default_slice(Unit *u) { return 0; } +const char *unit_slice_name(Unit *u) { + assert(u); + + if (!UNIT_ISSET(u->slice)) + return NULL; + + return UNIT_DEREF(u->slice)->id; +} + int unit_add_default_cgroups(Unit *u) { CGroupAttribute *a; char **c; @@ -2196,7 +2207,7 @@ int unit_add_default_cgroups(Unit *u) { /* Adds in the default cgroups, if they weren't specified * otherwise. */ - if (!u->manager->cgroup_hierarchy) + if (!u->manager->cgroup_root) return 0; r = unit_add_one_default_cgroup(u, NULL); diff --git a/src/core/unit.h b/src/core/unit.h index 81b8adbfdc..da52101bd2 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -542,6 +542,8 @@ void unit_reset_failed(Unit *u); Unit *unit_following(Unit *u); +const char *unit_slice_name(Unit *u); + bool unit_stop_pending(Unit *u) _pure_; bool unit_inactive_or_pending(Unit *u) _pure_; bool unit_active_or_pending(Unit *u); @@ -563,6 +565,7 @@ Unit* unit_ref_set(UnitRef *ref, Unit *u); void unit_ref_unset(UnitRef *ref); #define UNIT_DEREF(ref) ((ref).unit) +#define UNIT_ISSET(ref) (!!(ref).unit) int unit_add_one_mount_link(Unit *u, Mount *m); int unit_add_mount_links(Unit *u); diff --git a/src/login/loginctl.c b/src/login/loginctl.c index 1b9723fdbf..3637a408dc 100644 --- a/src/login/loginctl.c +++ b/src/login/loginctl.c @@ -261,6 +261,69 @@ static int list_seats(DBusConnection *bus, char **args, unsigned n) { return 0; } +static int list_machines(DBusConnection *bus, char **args, unsigned n) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + DBusMessageIter iter, sub, sub2; + unsigned k = 0; + int r; + + pager_open_if_enabled(); + + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "ListMachines", + &reply, + NULL, + DBUS_TYPE_INVALID); + if (r) + return r; + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + return -EIO; + } + + dbus_message_iter_recurse(&iter, &sub); + + if (on_tty()) + printf("%-32s %-9s %-16s\n", "MACHINE", "CONTAINER", "SERVICE"); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *name, *class, *service, *object; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + return -EIO; + } + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &class, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &service, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &object, false) < 0) { + log_error("Failed to parse reply."); + return -EIO; + } + + printf("%-32s %-9s %-16s\n", name, class, service); + + k++; + + dbus_message_iter_next(&sub); + } + + if (on_tty()) + printf("\n%u machines listed.\n", k); + + return 0; +} + typedef struct SessionStatusInfo { const char *id; uid_t uid; @@ -279,6 +342,7 @@ typedef struct SessionStatusInfo { const char *type; const char *class; const char *state; + const char *slice; } SessionStatusInfo; typedef struct UserStatusInfo { @@ -289,6 +353,7 @@ typedef struct UserStatusInfo { const char *state; char **sessions; const char *display; + const char *slice; } UserStatusInfo; typedef struct SeatStatusInfo { @@ -297,6 +362,18 @@ typedef struct SeatStatusInfo { char **sessions; } SeatStatusInfo; +typedef struct MachineStatusInfo { + const char *name; + sd_id128_t id; + const char *default_control_group; + const char *class; + const char *service; + const char *slice; + const char *root_directory; + pid_t leader; + usec_t timestamp; +} MachineStatusInfo; + static void print_session_status_info(SessionStatusInfo *i) { char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1; char since2[FORMAT_TIMESTAMP_MAX], *s2; @@ -318,15 +395,13 @@ static void print_session_status_info(SessionStatusInfo *i) { printf("\t Since: %s\n", s2); if (i->leader > 0) { - char *t = NULL; + _cleanup_free_ char *t = NULL; printf("\t Leader: %u", (unsigned) i->leader); get_process_comm(i->leader, &t); - if (t) { + if (t) printf(" (%s)", t); - free(t); - } printf("\n"); } @@ -375,6 +450,9 @@ static void print_session_status_info(SessionStatusInfo *i) { if (i->state) printf("\t State: %s\n", i->state); + if (i->slice) + printf("\t Slice: %s\n", i->slice); + if (i->default_control_group) { unsigned c; int output_flags = @@ -419,6 +497,9 @@ static void print_user_status_info(UserStatusInfo *i) { if (!isempty(i->state)) printf("\t State: %s\n", i->state); + if (i->slice) + printf("\t Slice: %s\n", i->slice); + if (!strv_isempty(i->sessions)) { char **l; printf("\tSessions:"); @@ -488,6 +569,76 @@ static void print_seat_status_info(SeatStatusInfo *i) { } } +static void print_machine_status_info(MachineStatusInfo *i) { + char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1; + char since2[FORMAT_TIMESTAMP_MAX], *s2; + assert(i); + + fputs(strna(i->name), stdout); + + if (!sd_id128_equal(i->id, SD_ID128_NULL)) + printf("(" SD_ID128_FORMAT_STR ")\n", SD_ID128_FORMAT_VAL(i->id)); + else + putchar('\n'); + + s1 = format_timestamp_relative(since1, sizeof(since1), i->timestamp); + s2 = format_timestamp(since2, sizeof(since2), i->timestamp); + + if (s1) + printf("\t Since: %s; %s\n", s2, s1); + else if (s2) + printf("\t Since: %s\n", s2); + + if (i->leader > 0) { + _cleanup_free_ char *t = NULL; + + printf("\t Leader: %u", (unsigned) i->leader); + + get_process_comm(i->leader, &t); + if (t) + printf(" (%s)", t); + + putchar('\n'); + } + + if (i->service) { + printf("\t Service: %s", i->service); + + if (i->class) + printf("; class %s", i->class); + + putchar('\n'); + } else if (i->class) + printf("\t Class: %s\n", i->class); + + if (i->slice) + printf("\t Slice: %s\n", i->slice); + if (i->root_directory) + printf("\t Root: %s\n", i->root_directory); + + if (i->default_control_group) { + unsigned c; + int output_flags = + arg_all * OUTPUT_SHOW_ALL | + arg_full * OUTPUT_FULL_WIDTH; + + printf("\t CGroup: %s\n", i->default_control_group); + + if (arg_transport != TRANSPORT_SSH) { + c = columns(); + if (c > 18) + c -= 18; + else + c = 0; + + show_cgroup_and_extra_by_spec(i->default_control_group, + "\t\t ", c, false, &i->leader, + i->leader > 0 ? 1 : 0, + output_flags); + } + } +} + static int status_property_session(const char *name, DBusMessageIter *iter, SessionStatusInfo *i) { assert(name); assert(iter); @@ -521,6 +672,8 @@ static int status_property_session(const char *name, DBusMessageIter *iter, Sess i->type = s; else if (streq(name, "Class")) i->class = s; + else if (streq(name, "Slice")) + i->slice = s; else if (streq(name, "State")) i->state = s; } @@ -606,6 +759,8 @@ static int status_property_user(const char *name, DBusMessageIter *iter, UserSta i->name = s; else if (streq(name, "DefaultControlGroup")) i->default_control_group = s; + else if (streq(name, "Slice")) + i->slice = s; else if (streq(name, "State")) i->state = s; } @@ -757,6 +912,80 @@ static int status_property_seat(const char *name, DBusMessageIter *iter, SeatSta return 0; } +static int status_property_machine(const char *name, DBusMessageIter *iter, MachineStatusInfo *i) { + assert(name); + assert(iter); + assert(i); + + switch (dbus_message_iter_get_arg_type(iter)) { + + case DBUS_TYPE_STRING: { + const char *s; + + dbus_message_iter_get_basic(iter, &s); + + if (!isempty(s)) { + if (streq(name, "Name")) + i->name = s; + else if (streq(name, "DefaultControlGroup")) + i->default_control_group = s; + else if (streq(name, "Class")) + i->class = s; + else if (streq(name, "Service")) + i->service = s; + else if (streq(name, "Slice")) + i->slice = s; + else if (streq(name, "RootDirectory")) + i->root_directory = s; + } + break; + } + + case DBUS_TYPE_UINT32: { + uint32_t u; + + dbus_message_iter_get_basic(iter, &u); + + if (streq(name, "Leader")) + i->leader = (pid_t) u; + + break; + } + + case DBUS_TYPE_UINT64: { + uint64_t u; + + dbus_message_iter_get_basic(iter, &u); + + if (streq(name, "Timestamp")) + i->timestamp = (usec_t) u; + + break; + } + + case DBUS_TYPE_ARRAY: { + DBusMessageIter sub; + + dbus_message_iter_recurse(iter, &sub); + + if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_BYTE && streq(name, "Id")) { + void *v; + int n; + + dbus_message_iter_get_fixed_array(&sub, &v, &n); + if (n == 0) + i->id = SD_ID128_NULL; + else if (n == 16) + memcpy(&i->id, v, n); + } + + break; + } + } + + return 0; +} + static int print_property(const char *name, DBusMessageIter *iter) { assert(name); assert(iter); @@ -838,6 +1067,7 @@ static int show_one(const char *verb, DBusConnection *bus, const char *path, boo SessionStatusInfo session_info = {}; UserStatusInfo user_info = {}; SeatStatusInfo seat_info = {}; + MachineStatusInfo machine_info = {}; assert(path); assert(new_line); @@ -901,8 +1131,10 @@ static int show_one(const char *verb, DBusConnection *bus, const char *path, boo r = status_property_session(name, &sub3, &session_info); else if (strstr(verb, "user")) r = status_property_user(name, &sub3, &user_info); - else + else if (strstr(verb, "seat")) r = status_property_seat(name, &sub3, &seat_info); + else + r = status_property_machine(name, &sub3, &machine_info); if (r < 0) { log_error("Failed to parse reply."); @@ -917,8 +1149,10 @@ static int show_one(const char *verb, DBusConnection *bus, const char *path, boo print_session_status_info(&session_info); else if (strstr(verb, "user")) print_user_status_info(&user_info); - else + else if (strstr(verb, "seat")) print_seat_status_info(&seat_info); + else + print_machine_status_info(&machine_info); } r = 0; @@ -981,7 +1215,7 @@ static int show(DBusConnection *bus, char **args, unsigned n) { } u = (uint32_t) uid; - ret = bus_method_call_with_reply ( + ret = bus_method_call_with_reply( bus, "org.freedesktop.login1", "/org/freedesktop/login1", @@ -991,9 +1225,10 @@ static int show(DBusConnection *bus, char **args, unsigned n) { NULL, DBUS_TYPE_UINT32, &u, DBUS_TYPE_INVALID); - } else { - ret = bus_method_call_with_reply ( + } else if (strstr(args[0], "seat")) { + + ret = bus_method_call_with_reply( bus, "org.freedesktop.login1", "/org/freedesktop/login1", @@ -1003,8 +1238,22 @@ static int show(DBusConnection *bus, char **args, unsigned n) { NULL, DBUS_TYPE_STRING, &args[i], DBUS_TYPE_INVALID); + + } else { + + ret = bus_method_call_with_reply( + bus, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "GetMachine", + &reply, + NULL, + DBUS_TYPE_STRING, &args[i], + DBUS_TYPE_INVALID); } - if (ret) + + if (ret < 0) goto finish; if (!dbus_message_get_args(reply, &error, @@ -1085,6 +1334,36 @@ static int kill_session(DBusConnection *bus, char **args, unsigned n) { return 0; } +static int kill_machine(DBusConnection *bus, char **args, unsigned n) { + unsigned i; + + assert(args); + + if (!arg_kill_who) + arg_kill_who = "all"; + + for (i = 1; i < n; i++) { + int r; + + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "KillMachine", + NULL, + NULL, + DBUS_TYPE_STRING, &args[i], + DBUS_TYPE_STRING, &arg_kill_who, + DBUS_TYPE_INT32, &arg_signal, + DBUS_TYPE_INVALID); + if (r) + return r; + } + + return 0; +} + static int enable_linger(DBusConnection *bus, char **args, unsigned n) { unsigned i; dbus_bool_t b, interactive = true; @@ -1288,6 +1567,31 @@ static int terminate_seat(DBusConnection *bus, char **args, unsigned n) { return 0; } +static int terminate_machine(DBusConnection *bus, char **args, unsigned n) { + unsigned i; + + assert(args); + + for (i = 1; i < n; i++) { + int r; + + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "TerminateMachine", + NULL, + NULL, + DBUS_TYPE_STRING, &args[i], + DBUS_TYPE_INVALID); + if (r) + return r; + } + + return 0; +} + static int help(void) { printf("%s [OPTIONS...] {COMMAND} ...\n\n" @@ -1326,7 +1630,12 @@ static int help(void) { " show-seat [NAME...] Show properties of one or more seats\n" " attach [NAME] [DEVICE...] Attach one or more devices to a seat\n" " flush-devices Flush all device associations\n" - " terminate-seat [NAME...] Terminate all sessions on one or more seats\n", + " terminate-seat [NAME...] Terminate all sessions on one or more seats\n" + " list-machines List running VMs and containers\n" + " machine-status [NAME...] Show VM/container status\n" + " show-machine [NAME...] Show properties of one or more VMs/containers\n" + " terminate-machine [NAME...] Terminate one or more VMs/containers\n" + " kill-machine [NAME...] Send signal to processes of a VM/container\n", program_invocation_short_name); return 0; @@ -1452,29 +1761,34 @@ static int loginctl_main(DBusConnection *bus, int argc, char *argv[], DBusError const int argc; int (* const dispatch)(DBusConnection *bus, char **args, unsigned n); } verbs[] = { - { "list-sessions", LESS, 1, list_sessions }, - { "session-status", MORE, 2, show }, - { "show-session", MORE, 1, show }, - { "activate", EQUAL, 2, activate }, - { "lock-session", MORE, 2, activate }, - { "unlock-session", MORE, 2, activate }, - { "lock-sessions", EQUAL, 1, lock_sessions }, - { "unlock-sessions", EQUAL, 1, lock_sessions }, - { "terminate-session", MORE, 2, activate }, - { "kill-session", MORE, 2, kill_session }, - { "list-users", EQUAL, 1, list_users }, - { "user-status", MORE, 2, show }, - { "show-user", MORE, 1, show }, - { "enable-linger", MORE, 2, enable_linger }, - { "disable-linger", MORE, 2, enable_linger }, - { "terminate-user", MORE, 2, terminate_user }, - { "kill-user", MORE, 2, kill_user }, - { "list-seats", EQUAL, 1, list_seats }, - { "seat-status", MORE, 2, show }, - { "show-seat", MORE, 1, show }, - { "attach", MORE, 3, attach }, - { "flush-devices", EQUAL, 1, flush_devices }, - { "terminate-seat", MORE, 2, terminate_seat }, + { "list-sessions", LESS, 1, list_sessions }, + { "session-status", MORE, 2, show }, + { "show-session", MORE, 1, show }, + { "activate", EQUAL, 2, activate }, + { "lock-session", MORE, 2, activate }, + { "unlock-session", MORE, 2, activate }, + { "lock-sessions", EQUAL, 1, lock_sessions }, + { "unlock-sessions", EQUAL, 1, lock_sessions }, + { "terminate-session", MORE, 2, activate }, + { "kill-session", MORE, 2, kill_session }, + { "list-users", EQUAL, 1, list_users }, + { "user-status", MORE, 2, show }, + { "show-user", MORE, 1, show }, + { "enable-linger", MORE, 2, enable_linger }, + { "disable-linger", MORE, 2, enable_linger }, + { "terminate-user", MORE, 2, terminate_user }, + { "kill-user", MORE, 2, kill_user }, + { "list-seats", EQUAL, 1, list_seats }, + { "seat-status", MORE, 2, show }, + { "show-seat", MORE, 1, show }, + { "attach", MORE, 3, attach }, + { "flush-devices", EQUAL, 1, flush_devices }, + { "terminate-seat", MORE, 2, terminate_seat }, + { "list-machines", EQUAL, 1, list_machines }, + { "machine-status", MORE, 2, show }, + { "show-machine", MORE, 1, show }, + { "terminate-machine", MORE, 2, terminate_machine }, + { "kill-machine", MORE, 2, kill_machine }, }; int left; diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 4a84b860f1..631006924f 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -36,6 +36,8 @@ #include "systemd/sd-messages.h" #include "fileio-label.h" #include "label.h" +#include "utf8.h" +#include "unit-name.h" #define BUS_MANAGER_INTERFACE \ " \n" \ @@ -51,10 +53,22 @@ " \n" \ " \n" \ " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ @@ -64,6 +78,9 @@ " \n" \ " \n" \ " \n" \ + " \n" \ + " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ @@ -91,6 +108,16 @@ " \n" \ " \n" \ " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ @@ -124,6 +151,9 @@ " \n" \ " \n" \ " \n" \ + " \n" \ + " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ @@ -201,13 +231,20 @@ " \n" \ " \n" \ " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ - " \n" \ " \n" \ " \n" \ " \n" \ @@ -342,8 +379,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess dbus_message_iter_get_basic(&iter, &leader); - if (leader <= 0 || - !dbus_message_iter_next(&iter) || + if (!dbus_message_iter_next(&iter) || dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) return -EINVAL; @@ -507,6 +543,12 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess dbus_message_iter_get_basic(&iter, &kill_processes); + if (leader <= 0) { + leader = bus_get_unix_process_id(m->bus, dbus_message_get_sender(message), NULL); + if (leader == 0) + return -EINVAL; + } + r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, leader, &cgroup); if (r < 0) goto fail; @@ -601,10 +643,12 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess if (r < 0) goto fail; - r = manager_add_session(m, user, id, &session); + r = manager_add_session(m, id, &session); if (r < 0) goto fail; + session_set_user(session, user); + session->leader = leader; session->audit_id = audit_id; session->type = t; @@ -718,6 +762,183 @@ fail: return r; } +static bool valid_machine_name(const char *p) { + size_t l; + + if (!filename_is_safe(p)) + return false; + + if (!ascii_is_valid(p)) + return false; + + l = strlen(p); + + if (l < 1 || l> 64) + return false; + + return true; +} + +static int bus_manager_create_machine( + Manager *manager, + DBusMessage *message, + DBusMessage **_reply) { + + const char *name, *service, *class, *slice, *root_directory; + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + _cleanup_free_ char *p = NULL; + DBusMessageIter iter, sub; + MachineClass c; + uint32_t leader; + sd_id128_t id; + dbus_bool_t b; + Machine *m; + int n, r; + void *v; + + assert(manager); + assert(message); + assert(_reply); + + if (!dbus_message_iter_init(message, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &name); + + if (!valid_machine_name(name) || + !dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_BYTE) + return -EINVAL; + + dbus_message_iter_recurse(&iter, &sub); + dbus_message_iter_get_fixed_array(&sub, &v, &n); + + if (n == 0) + id = SD_ID128_NULL; + else if (n == 16) + memcpy(&id, v, n); + else + return -EINVAL; + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &service); + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &class); + + if (isempty(class)) + c = _MACHINE_CLASS_INVALID; + else { + c = machine_class_from_string(class); + if (c < 0) + return -EINVAL; + } + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &leader); + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &slice); + if (!(isempty(slice) || (unit_name_is_valid(slice, false) && endswith(slice, ".slice"))) || + !dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &root_directory); + + if (!(isempty(root_directory) || path_is_absolute(root_directory))) + return -EINVAL; + + if (hashmap_get(manager->machines, name)) + return -EEXIST; + + if (leader <= 0) { + leader = bus_get_unix_process_id(manager->bus, dbus_message_get_sender(message), NULL); + if (leader == 0) + return -EINVAL; + } + + r = manager_add_machine(manager, name, &m); + if (r < 0) + goto fail; + + m->leader = leader; + m->class = c; + m->id = id; + + if (!isempty(service)) { + m->service = strdup(service); + if (!m->service) { + r = -ENOMEM; + goto fail; + } + } + + if (!isempty(slice)) { + m->slice = strdup(slice); + if (!m->slice) { + r = -ENOMEM; + goto fail; + } + } + + if (!isempty(root_directory)) { + m->root_directory = strdup(root_directory); + if (!m->root_directory) { + r = -ENOMEM; + goto fail; + } + } + + r = machine_start(m); + if (r < 0) + goto fail; + + reply = dbus_message_new_method_return(message); + if (!reply) { + r = -ENOMEM; + goto fail; + } + + p = machine_bus_path(m); + if (!p) { + r = -ENOMEM; + goto fail; + } + + b = dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID); + if (!b) { + r = -ENOMEM; + goto fail; + } + + *_reply = reply; + reply = NULL; + return 0; + +fail: + if (m) + machine_add_to_gc_queue(m); + + return r; +} + static int bus_manager_inhibit( Manager *m, DBusConnection *connection, @@ -1387,7 +1608,6 @@ static int bus_manager_do_shutdown_or_sleep( static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_manager_append_handle_action, handle_action, HandleAction); static const BusProperty bus_login_manager_properties[] = { - { "ControlGroupHierarchy", bus_property_append_string, "s", offsetof(Manager, cgroup_path), true }, { "Controllers", bus_property_append_strv, "as", offsetof(Manager, controllers), true }, { "ResetControllers", bus_property_append_strv, "as", offsetof(Manager, reset_controllers), true }, { "NAutoVTs", bus_property_append_unsigned, "u", offsetof(Manager, n_autovts) }, @@ -1530,6 +1750,107 @@ static DBusHandlerResult manager_message_handler( if (!b) goto oom; + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "GetUserByPID")) { + uint32_t pid; + char *p; + User *user; + bool b; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_UINT32, &pid, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + r = manager_get_user_by_pid(m, pid, &user); + if (r <= 0) + return bus_send_error_reply(connection, message, NULL, r < 0 ? r : -ENOENT); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + p = user_bus_path(user); + if (!p) + goto oom; + + b = dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID); + free(p); + + if (!b) + goto oom; + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "GetMachine")) { + Machine *machine; + const char *name; + char *p; + bool b; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + machine = hashmap_get(m->machines, name); + if (!machine) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + p = machine_bus_path(machine); + if (!p) + goto oom; + + b = dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID); + free(p); + + if (!b) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "GetMachineByPID")) { + uint32_t pid; + char *p; + Machine *machine; + bool b; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_UINT32, &pid, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + r = manager_get_machine_by_pid(m, pid, &machine); + if (r <= 0) + return bus_send_error_reply(connection, message, NULL, r < 0 ? r : -ENOENT); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + p = machine_bus_path(machine); + if (!p) + goto oom; + + b = dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID); + free(p); + + if (!b) + goto oom; + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "GetSeat")) { const char *name; char *p; @@ -1612,7 +1933,6 @@ static DBusHandlerResult manager_message_handler( goto oom; } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ListUsers")) { - char *p; User *user; Iterator i; DBusMessageIter iter, sub; @@ -1627,6 +1947,7 @@ static DBusHandlerResult manager_message_handler( goto oom; HASHMAP_FOREACH(user, m->users, i) { + _cleanup_free_ char *p = NULL; DBusMessageIter sub2; uint32_t uid; @@ -1646,8 +1967,6 @@ static DBusHandlerResult manager_message_handler( goto oom; } - free(p); - if (!dbus_message_iter_close_container(&sub, &sub2)) goto oom; } @@ -1656,7 +1975,6 @@ static DBusHandlerResult manager_message_handler( goto oom; } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ListSeats")) { - char *p; Seat *seat; Iterator i; DBusMessageIter iter, sub; @@ -1671,6 +1989,7 @@ static DBusHandlerResult manager_message_handler( goto oom; HASHMAP_FOREACH(seat, m->seats, i) { + _cleanup_free_ char *p = NULL; DBusMessageIter sub2; if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2)) @@ -1686,8 +2005,6 @@ static DBusHandlerResult manager_message_handler( goto oom; } - free(p); - if (!dbus_message_iter_close_container(&sub, &sub2)) goto oom; } @@ -1739,6 +2056,49 @@ static DBusHandlerResult manager_message_handler( if (!dbus_message_iter_close_container(&iter, &sub)) goto oom; + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ListMachines")) { + Machine *machine; + Iterator i; + DBusMessageIter iter, sub; + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + dbus_message_iter_init_append(reply, &iter); + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(ssso)", &sub)) + goto oom; + + HASHMAP_FOREACH(machine, m->machines, i) { + _cleanup_free_ char *p = NULL; + DBusMessageIter sub2; + const char *class; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2)) + goto oom; + + p = machine_bus_path(machine); + if (!p) + goto oom; + + class = strempty(machine_class_to_string(machine->class)); + + if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &machine->name) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &class) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &machine->service) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &p)) { + free(p); + goto oom; + } + + if (!dbus_message_iter_close_container(&sub, &sub2)) + goto oom; + } + + if (!dbus_message_iter_close_container(&iter, &sub)) + goto oom; + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "Inhibit")) { r = bus_manager_inhibit(m, connection, message, &error, &reply); @@ -1758,6 +2118,11 @@ static DBusHandlerResult manager_message_handler( if (r < 0) return bus_send_error_reply(connection, message, NULL, r); + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "CreateMachine")) { + + r = bus_manager_create_machine(m, message, &reply); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ReleaseSession")) { const char *name; @@ -1945,6 +2310,45 @@ static DBusHandlerResult manager_message_handler( if (!reply) goto oom; + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "KillMachine")) { + const char *swho; + int32_t signo; + KillWho who; + const char *name; + Machine *machine; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &swho, + DBUS_TYPE_INT32, &signo, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (isempty(swho)) + who = KILL_ALL; + else { + who = kill_who_from_string(swho); + if (who < 0) + return bus_send_error_reply(connection, message, &error, -EINVAL); + } + + if (signo <= 0 || signo >= _NSIG) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + machine = hashmap_get(m->machines, name); + if (!machine) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + r = machine_kill(machine, who, signo); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "TerminateSession")) { const char *name; Session *session; @@ -2014,6 +2418,29 @@ static DBusHandlerResult manager_message_handler( if (!reply) goto oom; + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "TerminateMachine")) { + const char *name; + Machine *machine; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + machine = hashmap_get(m->machines, name); + if (!machine) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + r = machine_stop(machine); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "SetUserLinger")) { uint32_t uid; struct passwd *pw; diff --git a/src/login/logind-machine-dbus.c b/src/login/logind-machine-dbus.c new file mode 100644 index 0000000000..7feea2e92a --- /dev/null +++ b/src/login/logind-machine-dbus.c @@ -0,0 +1,315 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include "logind.h" +#include "logind-machine.h" +#include "dbus-common.h" + +#define BUS_MACHINE_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_MACHINE_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.login1.Machine\0" + +static int bus_machine_append_default_cgroup(DBusMessageIter *i, const char *property, void *data) { + _cleanup_free_ char *t = NULL; + Machine *m = data; + int r; + bool success; + + assert(i); + assert(property); + assert(m); + + r = cg_join_spec(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_path, &t); + if (r < 0) + return r; + + success = dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t); + return success ? 0 : -ENOMEM; +} + +static int bus_machine_append_id(DBusMessageIter *i, const char *property, void *data) { + DBusMessageIter sub; + Machine *m = data; + dbus_bool_t b; + void *p; + + assert(i); + assert(property); + assert(m); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "y", &sub)) + return -ENOMEM; + + p = &m->id; + b = dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_BYTE, &p, 16); + if (!b) + return -ENOMEM; + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int get_machine_for_path(Manager *m, const char *path, Machine **_machine) { + _cleanup_free_ char *e = NULL; + Machine *machine; + + assert(m); + assert(path); + assert(_machine); + + if (!startswith(path, "/org/freedesktop/login1/machine/")) + return -EINVAL; + + e = bus_path_unescape(path + 32); + if (!e) + return -ENOMEM; + + machine = hashmap_get(m->machines, e); + if (!machine) + return -ENOENT; + + *_machine = machine; + return 0; +} + +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_machine_append_class, machine_class, MachineClass); + +static const BusProperty bus_login_machine_properties[] = { + { "Name", bus_property_append_string, "s", offsetof(Machine, name), true }, + { "Id", bus_machine_append_id, "ay", 0 }, + { "Timestamp", bus_property_append_usec, "t", offsetof(Machine, timestamp.realtime) }, + { "TimestampMonotonic", bus_property_append_usec, "t", offsetof(Machine, timestamp.monotonic) }, + { "DefaultControlGroup", bus_machine_append_default_cgroup, "s", 0 }, + { "Service", bus_property_append_string, "s", offsetof(Machine, service), true }, + { "Slice", bus_property_append_string, "s", offsetof(Machine, slice), true }, + { "Leader", bus_property_append_pid, "u", offsetof(Session, leader) }, + { "Class", bus_machine_append_class, "s", offsetof(Machine, class) }, + { "RootDirectory", bus_property_append_string, "s", offsetof(Machine, root_directory), true }, + { NULL, } +}; + +static DBusHandlerResult machine_message_dispatch( + Machine *m, + DBusConnection *connection, + DBusMessage *message) { + + DBusError error; + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + int r; + + assert(m); + assert(connection); + assert(message); + + if (dbus_message_is_method_call(message, "org.freedesktop.login1.Machine", "Terminate")) { + + r = machine_stop(m); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Machine", "Kill")) { + const char *swho; + int32_t signo; + KillWho who; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &swho, + DBUS_TYPE_INT32, &signo, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (isempty(swho)) + who = KILL_ALL; + else { + who = kill_who_from_string(swho); + if (who < 0) + return bus_send_error_reply(connection, message, &error, -EINVAL); + } + + if (signo <= 0 || signo >= _NSIG) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + r = machine_kill(m, who, signo); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else { + const BusBoundProperties bps[] = { + { "org.freedesktop.login1.Machine", bus_login_machine_properties, m }, + { NULL, } + }; + + return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps); + } + + if (reply) { + if (!bus_maybe_send_reply(connection, message, reply)) + goto oom; + } + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +static DBusHandlerResult machine_message_handler( + DBusConnection *connection, + DBusMessage *message, + void *userdata) { + + Manager *manager = userdata; + Machine *m; + int r; + + r = get_machine_for_path(manager, dbus_message_get_path(message), &m); + if (r < 0) { + + if (r == -ENOMEM) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + if (r == -ENOENT) { + DBusError e; + + dbus_error_init(&e); + dbus_set_error_const(&e, DBUS_ERROR_UNKNOWN_OBJECT, "Unknown machine"); + return bus_send_error_reply(connection, message, &e, r); + } + + return bus_send_error_reply(connection, message, NULL, r); + } + + return machine_message_dispatch(m, connection, message); +} + +const DBusObjectPathVTable bus_machine_vtable = { + .message_function = machine_message_handler +}; + +char *machine_bus_path(Machine *m) { + _cleanup_free_ char *e = NULL; + + assert(m); + + e = bus_path_escape(m->name); + if (!e) + return NULL; + + return strappend("/org/freedesktop/login1/machine/", e); +} + +int machine_send_signal(Machine *m, bool new_machine) { + _cleanup_dbus_message_unref_ DBusMessage *msg = NULL; + _cleanup_free_ char *p = NULL; + + assert(m); + + msg = dbus_message_new_signal("/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + new_machine ? "MachineNew" : "MachineRemoved"); + + if (!m) + return -ENOMEM; + + p = machine_bus_path(m); + if (!p) + return -ENOMEM; + + if (!dbus_message_append_args( + msg, + DBUS_TYPE_STRING, &m->name, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID)) + return -ENOMEM; + + if (!dbus_connection_send(m->manager->bus, msg, NULL)) + return -ENOMEM; + + return 0; +} + +int machine_send_changed(Machine *m, const char *properties) { + _cleanup_dbus_message_unref_ DBusMessage *msg = NULL; + _cleanup_free_ char *p = NULL; + + assert(m); + + if (!m->started) + return 0; + + p = machine_bus_path(m); + if (!p) + return -ENOMEM; + + msg = bus_properties_changed_new(p, "org.freedesktop.login1.Machine", properties); + if (!msg) + return -ENOMEM; + + if (!dbus_connection_send(m->manager->bus, msg, NULL)) + return -ENOMEM; + + return 0; +} diff --git a/src/login/logind-machine.c b/src/login/logind-machine.c new file mode 100644 index 0000000000..347e5aa022 --- /dev/null +++ b/src/login/logind-machine.c @@ -0,0 +1,455 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +#include "logind-machine.h" +#include "util.h" +#include "mkdir.h" +#include "cgroup-util.h" +#include "hashmap.h" +#include "strv.h" +#include "fileio.h" +#include "special.h" +#include + +Machine* machine_new(Manager *manager, const char *name) { + Machine *m; + + assert(manager); + assert(name); + + m = new0(Machine, 1); + if (!m) + return NULL; + + m->name = strdup(name); + if (!m->name) + goto fail; + + m->state_file = strappend("/run/systemd/machines/", m->name); + if (!m->state_file) + goto fail; + + if (hashmap_put(manager->machines, m->name, m) < 0) + goto fail; + + m->class = _MACHINE_CLASS_INVALID; + m->manager = manager; + + return m; + +fail: + free(m->state_file); + free(m->name); + free(m); + + return NULL; +} + +void machine_free(Machine *m) { + assert(m); + + if (m->in_gc_queue) + LIST_REMOVE(Machine, gc_queue, m->manager->machine_gc_queue, m); + + if (m->cgroup_path) { + hashmap_remove(m->manager->machine_cgroups, m->cgroup_path); + free(m->cgroup_path); + } + + hashmap_remove(m->manager->machines, m->name); + + free(m->name); + free(m->state_file); + free(m->service); + free(m->slice); + free(m->root_directory); + free(m); +} + +int machine_save(Machine *m) { + _cleanup_free_ char *temp_path = NULL; + _cleanup_fclose_ FILE *f = NULL; + int r; + + assert(m); + assert(m->state_file); + + if (!m->started) + return 0; + + r = mkdir_safe_label("/run/systemd/machines", 0755, 0, 0); + if (r < 0) + goto finish; + + r = fopen_temporary(m->state_file, &f, &temp_path); + if (r < 0) + goto finish; + + fchmod(fileno(f), 0644); + + fprintf(f, + "# This is private data. Do not parse.\n" + "NAME=%s\n", + m->name); + + if (m->cgroup_path) + fprintf(f, "CGROUP=%s\n", m->cgroup_path); + + if (m->service) + fprintf(f, "SERVICE=%s\n", m->service); + + if (m->slice) + fprintf(f, "SLICE=%s\n", m->slice); + + if (m->root_directory) + fprintf(f, "ROOT=%s\n", m->root_directory); + + if (!sd_id128_equal(m->id, SD_ID128_NULL)) + fprintf(f, "ID=" SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(m->id)); + + if (m->leader != 0) + fprintf(f, "LEADER=%lu\n", (unsigned long) m->leader); + + if (m->class != _MACHINE_CLASS_INVALID) + fprintf(f, "CLASS=%s\n", machine_class_to_string(m->class)); + + if (dual_timestamp_is_set(&m->timestamp)) + fprintf(f, + "REALTIME=%llu\n" + "MONOTONIC=%llu\n", + (unsigned long long) m->timestamp.realtime, + (unsigned long long) m->timestamp.monotonic); + + fflush(f); + + if (ferror(f) || rename(temp_path, m->state_file) < 0) { + r = -errno; + unlink(m->state_file); + unlink(temp_path); + } + +finish: + if (r < 0) + log_error("Failed to save machine data for %s: %s", m->name, strerror(-r)); + + return r; +} + +int machine_load(Machine *m) { + _cleanup_free_ char *realtime = NULL, *monotonic = NULL, *id = NULL, *leader = NULL, *class = NULL; + int r; + + assert(m); + + r = parse_env_file(m->state_file, NEWLINE, + "CGROUP", &m->cgroup_path, + "SERVICE", &m->service, + "SLICE", &m->slice, + "ROOT", &m->root_directory, + "ID", &id, + "LEADER", &leader, + "CLASS", &class, + "REALTIME", &realtime, + "MONOTONIC", &monotonic, + NULL); + if (r < 0) { + if (r == -ENOENT) + return 0; + + log_error("Failed to read %s: %s", m->state_file, strerror(-r)); + return r; + } + + if (id) + sd_id128_from_string(id, &m->id); + + if (leader) + parse_pid(leader, &m->leader); + + if (class) { + MachineClass c; + + c = machine_class_from_string(class); + if (c >= 0) + m->class = c; + } + + if (realtime) { + unsigned long long l; + if (sscanf(realtime, "%llu", &l) > 0) + m->timestamp.realtime = l; + } + + if (monotonic) { + unsigned long long l; + if (sscanf(monotonic, "%llu", &l) > 0) + m->timestamp.monotonic = l; + } + + return r; +} + +static int machine_create_one_group(Machine *m, const char *controller, const char *path) { + int r; + + assert(m); + assert(path); + + if (m->leader > 0) + r = cg_create_and_attach(controller, path, m->leader); + else + r = -EINVAL; + + if (r < 0) { + r = cg_create(controller, path, NULL); + if (r < 0) + return r; + } + + return 0; +} + +static int machine_create_cgroup(Machine *m) { + char **k; + int r; + + assert(m); + + if (!m->slice) { + m->slice = strdup(SPECIAL_MACHINE_SLICE); + if (!m->slice) + return log_oom(); + } + + if (!m->cgroup_path) { + _cleanup_free_ char *escaped = NULL, *slice = NULL; + char *name; + + name = strappenda(m->name, ".machine"); + + escaped = cg_escape(name); + if (!escaped) + return log_oom(); + + r = cg_slice_to_path(m->slice, &slice); + if (r < 0) + return r; + + m->cgroup_path = strjoin(m->manager->cgroup_root, "/", slice, "/", escaped, NULL); + if (!m->cgroup_path) + return log_oom(); + } + + r = machine_create_one_group(m, SYSTEMD_CGROUP_CONTROLLER, m->cgroup_path); + if (r < 0) { + log_error("Failed to create cgroup "SYSTEMD_CGROUP_CONTROLLER":%s: %s", m->cgroup_path, strerror(-r)); + return r; + } + + STRV_FOREACH(k, m->manager->controllers) { + + if (strv_contains(m->manager->reset_controllers, *k)) + continue; + + r = machine_create_one_group(m, *k, m->cgroup_path); + if (r < 0) + log_warning("Failed to create cgroup %s:%s: %s", *k, m->cgroup_path, strerror(-r)); + } + + if (m->leader > 0) { + STRV_FOREACH(k, m->manager->reset_controllers) { + r = cg_attach(*k, "/", m->leader); + if (r < 0) + log_warning("Failed to reset controller %s: %s", *k, strerror(-r)); + } + } + + r = hashmap_put(m->manager->machine_cgroups, m->cgroup_path, m); + if (r < 0) + log_warning("Failed to create mapping between cgroup and machine"); + + return 0; +} + +int machine_start(Machine *m) { + int r; + + assert(m); + + if (m->started) + return 0; + + log_struct(LOG_INFO, + MESSAGE_ID(SD_MESSAGE_MACHINE_START), + "NAME=%s", m->name, + "LEADER=%lu", (unsigned long) m->leader, + "MESSAGE=New machine %s.", m->name, + NULL); + + /* Create cgroup */ + r = machine_create_cgroup(m); + if (r < 0) + return r; + + if (!dual_timestamp_is_set(&m->timestamp)) + dual_timestamp_get(&m->timestamp); + + m->started = true; + + /* Save new machine data */ + machine_save(m); + + machine_send_signal(m, true); + + return 0; +} + +static int machine_terminate_cgroup(Machine *m) { + int r; + char **k; + + assert(m); + + if (!m->cgroup_path) + return 0; + + cg_trim(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_path, false); + + r = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_path, true); + if (r < 0) + log_error("Failed to kill machine cgroup: %s", strerror(-r)); + + STRV_FOREACH(k, m->manager->controllers) + cg_trim(*k, m->cgroup_path, true); + + hashmap_remove(m->manager->machine_cgroups, m->cgroup_path); + + free(m->cgroup_path); + m->cgroup_path = NULL; + + return r; +} + +int machine_stop(Machine *m) { + int r = 0, k; + assert(m); + + if (m->started) + log_struct(LOG_INFO, + MESSAGE_ID(SD_MESSAGE_MACHINE_STOP), + "NAME=%s", m->name, + "LEADER=%lu", (unsigned long) m->leader, + "MESSAGE=Machine %s terminated.", m->name, + NULL); + + /* Kill cgroup */ + k = machine_terminate_cgroup(m); + if (k < 0) + r = k; + + unlink(m->state_file); + machine_add_to_gc_queue(m); + + if (m->started) + machine_send_signal(m, false); + + m->started = false; + + return r; +} + +int machine_check_gc(Machine *m, bool drop_not_started) { + int r; + + assert(m); + + if (drop_not_started && !m->started) + return 0; + + if (m->cgroup_path) { + r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_path, false); + if (r < 0) + return r; + + if (r <= 0) + return 1; + } + + return 0; +} + +void machine_add_to_gc_queue(Machine *m) { + assert(m); + + if (m->in_gc_queue) + return; + + LIST_PREPEND(Machine, gc_queue, m->manager->machine_gc_queue, m); + m->in_gc_queue = true; +} + +int machine_kill(Machine *m, KillWho who, int signo) { + _cleanup_set_free_ Set *pid_set = NULL; + int r = 0; + + assert(m); + + if (!m->cgroup_path) + return -ESRCH; + + if (m->leader <= 0 && who == KILL_LEADER) + return -ESRCH; + + if (m->leader > 0) + if (kill(m->leader, signo) < 0) + r = -errno; + + if (who == KILL_ALL) { + int q; + + pid_set = set_new(trivial_hash_func, trivial_compare_func); + if (!pid_set) + return log_oom(); + + if (m->leader > 0) { + q = set_put(pid_set, LONG_TO_PTR(m->leader)); + if (q < 0) + r = q; + } + + q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_path, signo, false, true, false, pid_set); + if (q < 0 && (q != -EAGAIN && q != -ESRCH && q != -ENOENT)) + r = q; + } + + return r; +} + +static const char* const machine_class_table[_MACHINE_CLASS_MAX] = { + [MACHINE_CONTAINER] = "container", + [MACHINE_VM] = "vm" +}; + +DEFINE_STRING_TABLE_LOOKUP(machine_class, MachineClass); diff --git a/src/login/logind-machine.h b/src/login/logind-machine.h new file mode 100644 index 0000000000..cd5174ff9e --- /dev/null +++ b/src/login/logind-machine.h @@ -0,0 +1,80 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +typedef struct Machine Machine; + +#include "list.h" +#include "util.h" +#include "logind.h" +#include "logind-session.h" + +typedef enum MachineClass { + MACHINE_CONTAINER, + MACHINE_VM, + _MACHINE_CLASS_MAX, + _MACHINE_CLASS_INVALID = -1 +} MachineClass; + +struct Machine { + Manager *manager; + + char *name; + sd_id128_t id; + + MachineClass class; + + char *state_file; + char *service; + char *cgroup_path; + char *slice; + char *root_directory; + + pid_t leader; + + dual_timestamp timestamp; + + bool in_gc_queue:1; + bool started:1; + + LIST_FIELDS(Machine, gc_queue); +}; + +Machine* machine_new(Manager *manager, const char *name); +void machine_free(Machine *m); +int machine_check_gc(Machine *m, bool drop_not_started); +void machine_add_to_gc_queue(Machine *m); +int machine_start(Machine *m); +int machine_stop(Machine *m); +int machine_save(Machine *m); +int machine_load(Machine *m); +int machine_kill(Machine *m, KillWho who, int signo); + +char *machine_bus_path(Machine *s); + +extern const DBusObjectPathVTable bus_machine_vtable; + +int machine_send_signal(Machine *m, bool new_machine); +int machine_send_changed(Machine *m, const char *properties); + +const char* machine_class_to_string(MachineClass t) _const_; +MachineClass machine_class_from_string(const char *s) _pure_; diff --git a/src/login/logind-seat-dbus.c b/src/login/logind-seat-dbus.c index 5c535ba0ec..230f7f082a 100644 --- a/src/login/logind-seat-dbus.c +++ b/src/login/logind-seat-dbus.c @@ -209,8 +209,8 @@ static int bus_seat_append_idle_hint_since(DBusMessageIter *i, const char *prope } static int get_seat_for_path(Manager *m, const char *path, Seat **_s) { + _cleanup_free_ char *id = NULL; Seat *s; - char *id; assert(m); assert(path); @@ -224,8 +224,6 @@ static int get_seat_for_path(Manager *m, const char *path, Seat **_s) { return -ENOMEM; s = hashmap_get(m->seats, id); - free(id); - if (!s) return -ENOENT; @@ -348,7 +346,7 @@ const DBusObjectPathVTable bus_seat_vtable = { }; char *seat_bus_path(Seat *s) { - _cleanup_free_ char *t; + _cleanup_free_ char *t = NULL; assert(s); diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c index ec823af547..e306eabb32 100644 --- a/src/login/logind-session-dbus.c +++ b/src/login/logind-session-dbus.c @@ -56,6 +56,7 @@ " \n" \ " \n" \ " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ @@ -233,8 +234,8 @@ static int bus_session_append_state(DBusMessageIter *i, const char *property, vo } static int get_session_for_path(Manager *m, const char *path, Session **_s) { + _cleanup_free_ char *id = NULL; Session *s; - char *id; assert(m); assert(path); @@ -248,8 +249,6 @@ static int get_session_for_path(Manager *m, const char *path, Session **_s) { return -ENOMEM; s = hashmap_get(m->sessions, id); - free(id); - if (!s) return -ENOENT; @@ -270,6 +269,7 @@ static const BusProperty bus_login_session_properties[] = { { "RemoteUser", bus_property_append_string, "s", offsetof(Session, remote_user), true }, { "RemoteHost", bus_property_append_string, "s", offsetof(Session, remote_host), true }, { "Service", bus_property_append_string, "s", offsetof(Session, service), true }, + { "Slice", bus_property_append_string, "s", offsetof(Session, slice), true }, { "Leader", bus_property_append_pid, "u", offsetof(Session, leader) }, { "Audit", bus_property_append_uint32, "u", offsetof(Session, audit_id) }, { "Type", bus_session_append_type, "s", offsetof(Session, type) }, @@ -448,7 +448,7 @@ const DBusObjectPathVTable bus_session_vtable = { }; char *session_bus_path(Session *s) { - _cleanup_free_ char *t; + _cleanup_free_ char *t = NULL; assert(s); diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 4fd3985811..aba517d1f7 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -35,7 +35,7 @@ #include "logind-session.h" #include "fileio.h" -Session* session_new(Manager *m, User *u, const char *id) { +Session* session_new(Manager *m, const char *id) { Session *s; assert(m); @@ -61,9 +61,6 @@ Session* session_new(Manager *m, User *u, const char *id) { s->manager = m; s->fifo_fd = -1; - s->user = u; - - LIST_PREPEND(Session, sessions_by_user, u->sessions, s); return s; } @@ -99,6 +96,7 @@ void session_free(Session *s) { free(s->remote_host); free(s->remote_user); free(s->service); + free(s->slice); hashmap_remove(s->manager->sessions, s->id); session_remove_fifo(s); @@ -107,6 +105,14 @@ void session_free(Session *s) { free(s); } +void session_set_user(Session *s, User *u) { + assert(s); + assert(!s->user); + + s->user = u; + LIST_PREPEND(Session, sessions_by_user, u->sessions, s); +} + int session_save(Session *s) { _cleanup_fclose_ FILE *f = NULL; _cleanup_free_ char *temp_path = NULL; @@ -114,6 +120,9 @@ int session_save(Session *s) { assert(s); + if (!s->user) + return -ESTALE; + if (!s->started) return 0; @@ -174,6 +183,9 @@ int session_save(Session *s) { if (s->service) fprintf(f, "SERVICE=%s\n", s->service); + if (s->seat) + fprintf(f, "SLICE=%s\n", s->slice); + if (s->seat && seat_can_multi_session(s->seat)) fprintf(f, "VTNR=%i\n", s->vtnr); @@ -183,6 +195,13 @@ int session_save(Session *s) { if (s->audit_id > 0) fprintf(f, "AUDIT=%"PRIu32"\n", s->audit_id); + if (dual_timestamp_is_set(&s->timestamp)) + fprintf(f, + "REALTIME=%llu\n" + "MONOTONIC=%llu\n", + (unsigned long long) s->timestamp.realtime, + (unsigned long long) s->timestamp.monotonic); + fflush(f); if (ferror(f) || rename(temp_path, s->state_file) < 0) { @@ -199,14 +218,17 @@ finish: } int session_load(Session *s) { - char *remote = NULL, + _cleanup_free_ char *remote = NULL, *kill_processes = NULL, *seat = NULL, *vtnr = NULL, *leader = NULL, *audit_id = NULL, *type = NULL, - *class = NULL; + *class = NULL, + *uid = NULL, + *realtime = NULL, + *monotonic = NULL; int k, r; @@ -223,14 +245,44 @@ int session_load(Session *s) { "REMOTE_HOST", &s->remote_host, "REMOTE_USER", &s->remote_user, "SERVICE", &s->service, + "SLICE", &s->slice, "VTNR", &vtnr, "LEADER", &leader, "TYPE", &type, "CLASS", &class, + "UID", &uid, + "REALTIME", &realtime, + "MONOTONIC", &monotonic, NULL); - if (r < 0) - goto finish; + if (r < 0) { + log_error("Failed to read %s: %s", s->state_file, strerror(-r)); + return r; + } + + if (!s->user) { + uid_t u; + User *user; + + if (!uid) { + log_error("UID not specified for session %s", s->id); + return -ENOENT; + } + + r = parse_uid(uid, &u); + if (r < 0) { + log_error("Failed to parse UID value %s for session %s.", uid, s->id); + return r; + } + + user = hashmap_get(s->manager->users, ULONG_TO_PTR((unsigned long) u)); + if (!user) { + log_error("User of session %s not known.", s->id); + return -ENOENT; + } + + session_set_user(s, user); + } if (remote) { k = parse_boolean(remote); @@ -295,14 +347,17 @@ int session_load(Session *s) { close_nointr_nofail(fd); } -finish: - free(remote); - free(kill_processes); - free(seat); - free(vtnr); - free(leader); - free(audit_id); - free(class); + if (realtime) { + unsigned long long l; + if (sscanf(realtime, "%llu", &l) > 0) + s->timestamp.realtime = l; + } + + if (monotonic) { + unsigned long long l; + if (sscanf(monotonic, "%llu", &l) > 0) + s->timestamp.monotonic = l; + } return r; } @@ -311,6 +366,7 @@ int session_activate(Session *s) { int r; assert(s); + assert(s->user); if (s->vtnr < 0) return -ENOTSUP; @@ -407,17 +463,19 @@ static int session_create_one_group(Session *s, const char *controller, const ch int r; assert(s); + assert(s->user); assert(path); - if (s->leader > 0) { + if (s->leader > 0) r = cg_create_and_attach(controller, path, s->leader); - if (r < 0) - r = cg_create(controller, path, NULL); - } else - r = cg_create(controller, path, NULL); + else + r = -EINVAL; - if (r < 0) - return r; + if (r < 0) { + r = cg_create(controller, path, NULL); + if (r < 0) + return r; + } r = cg_set_task_access(controller, path, 0644, s->user->uid, s->user->gid, -1); if (r >= 0) @@ -428,7 +486,6 @@ static int session_create_one_group(Session *s, const char *controller, const ch static int session_create_cgroup(Session *s) { char **k; - char *p; int r; assert(s); @@ -446,30 +503,41 @@ static int session_create_cgroup(Session *s) { if (!escaped) return log_oom(); - p = strjoin(s->user->cgroup_path, "/", escaped, NULL); - if (!p) + if (s->slice) { + _cleanup_free_ char *slice = NULL; + + r = cg_slice_to_path(s->slice, &slice); + if (r < 0) + return r; + + s->cgroup_path = strjoin(s->manager->cgroup_root, "/", slice, "/", escaped, NULL); + } else + s->cgroup_path = strjoin(s->user->cgroup_path, "/", escaped, NULL); + + if (!s->cgroup_path) + return log_oom(); + } + + if (!s->slice) { + s->slice = strdup(s->user->slice); + if (!s->slice) return log_oom(); - } else - p = s->cgroup_path; + } - r = session_create_one_group(s, SYSTEMD_CGROUP_CONTROLLER, p); + r = session_create_one_group(s, SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path); if (r < 0) { - log_error("Failed to create "SYSTEMD_CGROUP_CONTROLLER":%s: %s", p, strerror(-r)); - free(p); - s->cgroup_path = NULL; + log_error("Failed to create "SYSTEMD_CGROUP_CONTROLLER":%s: %s", s->cgroup_path, strerror(-r)); return r; } - s->cgroup_path = p; - STRV_FOREACH(k, s->controllers) { if (strv_contains(s->reset_controllers, *k)) continue; - r = session_create_one_group(s, *k, p); + r = session_create_one_group(s, *k, s->cgroup_path); if (r < 0) - log_warning("Failed to create %s:%s: %s", *k, p, strerror(-r)); + log_warning("Failed to create %s:%s: %s", *k, s->cgroup_path, strerror(-r)); } STRV_FOREACH(k, s->manager->controllers) { @@ -479,9 +547,9 @@ static int session_create_cgroup(Session *s) { strv_contains(s->controllers, *k)) continue; - r = session_create_one_group(s, *k, p); + r = session_create_one_group(s, *k, s->cgroup_path); if (r < 0) - log_warning("Failed to create %s:%s: %s", *k, p, strerror(-r)); + log_warning("Failed to create %s:%s: %s", *k, s->cgroup_path, strerror(-r)); } if (s->leader > 0) { @@ -502,7 +570,6 @@ static int session_create_cgroup(Session *s) { r = cg_attach(*k, "/", s->leader); if (r < 0) log_warning("Failed to reset controller %s: %s", *k, strerror(-r)); - } } @@ -517,7 +584,9 @@ int session_start(Session *s) { int r; assert(s); - assert(s->user); + + if (!s->user) + return -ESTALE; if (s->started) return 0; @@ -542,7 +611,8 @@ int session_start(Session *s) { /* Create X11 symlink */ session_link_x11_socket(s); - dual_timestamp_get(&s->timestamp); + if (!dual_timestamp_is_set(&s->timestamp)) + dual_timestamp_get(&s->timestamp); if (s->seat) seat_read_active_vt(s->seat); @@ -667,6 +737,9 @@ int session_stop(Session *s) { assert(s); + if (!s->user) + return -ESTALE; + if (s->started) log_struct(s->type == SESSION_TTY || s->type == SESSION_X11 ? LOG_INFO : LOG_DEBUG, MESSAGE_ID(SD_MESSAGE_SESSION_STOP), @@ -932,6 +1005,9 @@ int session_check_gc(Session *s, bool drop_not_started) { if (drop_not_started && !s->started) return 0; + if (!s->user) + return 0; + if (s->fifo_fd >= 0) { r = pipe_eof(s->fifo_fd); @@ -978,8 +1054,8 @@ SessionState session_get_state(Session *s) { } int session_kill(Session *s, KillWho who, int signo) { + _cleanup_set_free_ Set *pid_set = NULL; int r = 0; - Set *pid_set = NULL; assert(s); @@ -998,7 +1074,7 @@ int session_kill(Session *s, KillWho who, int signo) { pid_set = set_new(trivial_hash_func, trivial_compare_func); if (!pid_set) - return -ENOMEM; + return log_oom(); if (s->leader > 0) { q = set_put(pid_set, LONG_TO_PTR(s->leader)); @@ -1012,9 +1088,6 @@ int session_kill(Session *s, KillWho who, int signo) { r = q; } - if (pid_set) - set_free(pid_set); - return r; } diff --git a/src/login/logind-session.h b/src/login/logind-session.h index a73df3a3bc..60597c2362 100644 --- a/src/login/logind-session.h +++ b/src/login/logind-session.h @@ -22,6 +22,7 @@ ***/ typedef struct Session Session; +typedef enum KillWho KillWho; #include "list.h" #include "util.h" @@ -54,12 +55,12 @@ typedef enum SessionType { _SESSION_TYPE_INVALID = -1 } SessionType; -typedef enum KillWho { +enum KillWho { KILL_LEADER, KILL_ALL, _KILL_WHO_MAX, _KILL_WHO_INVALID = -1 -} KillWho; +}; struct Session { Manager *manager; @@ -82,6 +83,7 @@ struct Session { char *remote_host; char *service; + char *slice; int vtnr; Seat *seat; @@ -108,8 +110,9 @@ struct Session { LIST_FIELDS(Session, gc_queue); }; -Session *session_new(Manager *m, User *u, const char *id); +Session *session_new(Manager *m, const char *id); void session_free(Session *s); +void session_set_user(Session *s, User *u); int session_check_gc(Session *s, bool drop_not_started); void session_add_to_gc_queue(Session *s); int session_activate(Session *s); diff --git a/src/login/logind-user-dbus.c b/src/login/logind-user-dbus.c index 3ec3ff8e61..2a2825308d 100644 --- a/src/login/logind-user-dbus.c +++ b/src/login/logind-user-dbus.c @@ -40,13 +40,14 @@ " \n" \ " \n" \ " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ - " \n" \ + " \n" #define INTROSPECTION \ DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ @@ -212,10 +213,10 @@ static int get_user_for_path(Manager *m, const char *path, User **_u) { assert(path); assert(_u); - if (!startswith(path, "/org/freedesktop/login1/user/")) + if (!startswith(path, "/org/freedesktop/login1/user/_")) return -EINVAL; - r = safe_atolu(path + 29, &lu); + r = safe_atolu(path + 30, &lu); if (r < 0) return r; @@ -236,6 +237,7 @@ static const BusProperty bus_login_user_properties[] = { { "RuntimePath", bus_property_append_string, "s", offsetof(User, runtime_path), true }, { "DefaultControlGroup", bus_user_append_default_cgroup, "s", 0 }, { "Service", bus_property_append_string, "s", offsetof(User, service), true }, + { "Slice", bus_property_append_string, "s", offsetof(User, slice), true }, { "Display", bus_user_append_display, "(so)", 0 }, { "State", bus_user_append_state, "s", 0 }, { "Sessions", bus_user_append_sessions, "a(so)", 0 }, @@ -348,7 +350,7 @@ char *user_bus_path(User *u) { assert(u); - if (asprintf(&s, "/org/freedesktop/login1/user/%llu", (unsigned long long) u->uid) < 0) + if (asprintf(&s, "/org/freedesktop/login1/user/_%llu", (unsigned long long) u->uid) < 0) return NULL; return s; diff --git a/src/login/logind-user.c b/src/login/logind-user.c index 9e2cbf646b..fb0c9b75d7 100644 --- a/src/login/logind-user.c +++ b/src/login/logind-user.c @@ -30,6 +30,7 @@ #include "hashmap.h" #include "strv.h" #include "fileio.h" +#include "special.h" User* user_new(Manager *m, uid_t uid, gid_t gid, const char *name) { User *u; @@ -42,29 +43,27 @@ User* user_new(Manager *m, uid_t uid, gid_t gid, const char *name) { return NULL; u->name = strdup(name); - if (!u->name) { - free(u); - return NULL; - } + if (!u->name) + goto fail; - if (asprintf(&u->state_file, "/run/systemd/users/%lu", (unsigned long) uid) < 0) { - free(u->name); - free(u); - return NULL; - } + if (asprintf(&u->state_file, "/run/systemd/users/%lu", (unsigned long) uid) < 0) + goto fail; - if (hashmap_put(m->users, ULONG_TO_PTR((unsigned long) uid), u) < 0) { - free(u->state_file); - free(u->name); - free(u); - return NULL; - } + if (hashmap_put(m->users, ULONG_TO_PTR((unsigned long) uid), u) < 0) + goto fail; u->manager = m; u->uid = uid; u->gid = gid; return u; + +fail: + free(u->state_file); + free(u->name); + free(u); + + return NULL; } void user_free(User *u) { @@ -76,9 +75,10 @@ void user_free(User *u) { while (u->sessions) session_free(u->sessions); - if (u->cgroup_path) + if (u->cgroup_path) { hashmap_remove(u->manager->user_cgroups, u->cgroup_path); - free(u->cgroup_path); + free(u->cgroup_path); + } free(u->service); free(u->runtime_path); @@ -87,13 +87,14 @@ void user_free(User *u) { free(u->name); free(u->state_file); + free(u->slice); free(u); } int user_save(User *u) { - FILE *f; + _cleanup_free_ char *temp_path = NULL; + _cleanup_fclose_ FILE *f = NULL; int r; - char *temp_path; assert(u); assert(u->state_file); @@ -119,24 +120,26 @@ int user_save(User *u) { user_state_to_string(user_get_state(u))); if (u->cgroup_path) - fprintf(f, - "CGROUP=%s\n", - u->cgroup_path); + fprintf(f, "CGROUP=%s\n", u->cgroup_path); if (u->runtime_path) - fprintf(f, - "RUNTIME=%s\n", - u->runtime_path); + fprintf(f, "RUNTIME=%s\n", u->runtime_path); if (u->service) - fprintf(f, - "SERVICE=%s\n", - u->service); + fprintf(f, "SERVICE=%s\n", u->service); + + if (u->slice) + fprintf(f, "SLICE=%s\n", u->slice); if (u->display) + fprintf(f, "DISPLAY=%s\n", u->display->id); + + if (dual_timestamp_is_set(&u->timestamp)) fprintf(f, - "DISPLAY=%s\n", - u->display->id); + "REALTIME=%llu\n" + "MONOTONIC=%llu\n", + (unsigned long long) u->timestamp.realtime, + (unsigned long long) u->timestamp.monotonic); if (u->sessions) { Session *i; @@ -233,9 +236,6 @@ int user_save(User *u) { unlink(temp_path); } - fclose(f); - free(temp_path); - finish: if (r < 0) log_error("Failed to save user data for %s: %s", u->name, strerror(-r)); @@ -244,21 +244,22 @@ finish: } int user_load(User *u) { - int r; - char *display = NULL; + _cleanup_free_ char *display = NULL, *realtime = NULL, *monotonic = NULL; Session *s = NULL; + int r; assert(u); r = parse_env_file(u->state_file, NEWLINE, - "CGROUP", &u->cgroup_path, - "RUNTIME", &u->runtime_path, - "SERVICE", &u->service, - "DISPLAY", &display, + "CGROUP", &u->cgroup_path, + "RUNTIME", &u->runtime_path, + "SERVICE", &u->service, + "DISPLAY", &display, + "SLICE", &u->slice, + "REALTIME", &realtime, + "MONOTONIC", &monotonic, NULL); if (r < 0) { - free(display); - if (r == -ENOENT) return 0; @@ -266,14 +267,24 @@ int user_load(User *u) { return r; } - if (display) { + if (display) s = hashmap_get(u->manager->sessions, display); - free(display); - } if (s && s->display && display_is_local(s->display)) u->display = s; + if (realtime) { + unsigned long long l; + if (sscanf(realtime, "%llu", &l) > 0) + u->timestamp.realtime = l; + } + + if (monotonic) { + unsigned long long l; + if (sscanf(monotonic, "%llu", &l) > 0) + u->timestamp.monotonic = l; + } + return r; } @@ -309,13 +320,18 @@ static int user_mkdir_runtime_path(User *u) { static int user_create_cgroup(User *u) { char **k; - char *p; int r; assert(u); + if (!u->slice) { + u->slice = strdup(SPECIAL_USER_SLICE); + if (!u->slice) + return log_oom(); + } + if (!u->cgroup_path) { - _cleanup_free_ char *name = NULL, *escaped = NULL; + _cleanup_free_ char *name = NULL, *escaped = NULL, *slice = NULL; if (asprintf(&name, "%lu.user", (unsigned long) u->uid) < 0) return log_oom(); @@ -324,30 +340,29 @@ static int user_create_cgroup(User *u) { if (!escaped) return log_oom(); - p = strjoin(u->manager->cgroup_path, "/", escaped, NULL); - if (!p) + r = cg_slice_to_path(u->slice, &slice); + if (r < 0) + return r; + + u->cgroup_path = strjoin(u->manager->cgroup_root, "/", slice, "/", escaped, NULL); + if (!u->cgroup_path) return log_oom(); - } else - p = u->cgroup_path; + } - r = cg_create(SYSTEMD_CGROUP_CONTROLLER, p, NULL); + r = cg_create(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, NULL); if (r < 0) { - log_error("Failed to create cgroup "SYSTEMD_CGROUP_CONTROLLER":%s: %s", p, strerror(-r)); - free(p); - u->cgroup_path = NULL; + log_error("Failed to create cgroup "SYSTEMD_CGROUP_CONTROLLER":%s: %s", u->cgroup_path, strerror(-r)); return r; } - u->cgroup_path = p; - STRV_FOREACH(k, u->manager->controllers) { if (strv_contains(u->manager->reset_controllers, *k)) continue; - r = cg_create(*k, p, NULL); + r = cg_create(*k, u->cgroup_path, NULL); if (r < 0) - log_warning("Failed to create cgroup %s:%s: %s", *k, p, strerror(-r)); + log_warning("Failed to create cgroup %s:%s: %s", *k, u->cgroup_path, strerror(-r)); } r = hashmap_put(u->manager->user_cgroups, u->cgroup_path, u); @@ -390,7 +405,8 @@ int user_start(User *u) { if (r < 0) return r; - dual_timestamp_get(&u->timestamp); + if (!dual_timestamp_is_set(&u->timestamp)) + dual_timestamp_get(&u->timestamp); u->started = true; @@ -633,8 +649,8 @@ UserState user_get_state(User *u) { } int user_kill(User *u, int signo) { - int r = 0, q; - Set *pid_set = NULL; + _cleanup_set_free_ Set *pid_set = NULL; + int r; assert(u); @@ -645,15 +661,11 @@ int user_kill(User *u, int signo) { if (!pid_set) return -ENOMEM; - q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, signo, false, true, false, pid_set); - if (q < 0) - if (q != -EAGAIN && q != -ESRCH && q != -ENOENT) - r = q; - - if (pid_set) - set_free(pid_set); + r = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, signo, false, true, false, pid_set); + if (r < 0 && (r != -EAGAIN && r != -ESRCH && r != -ENOENT)) + return r; - return r; + return 0; } static const char* const user_state_table[_USER_STATE_MAX] = { diff --git a/src/login/logind-user.h b/src/login/logind-user.h index 080354da74..16d798541a 100644 --- a/src/login/logind-user.h +++ b/src/login/logind-user.h @@ -49,6 +49,7 @@ struct User { char *runtime_path; char *service; char *cgroup_path; + char *slice; Session *display; diff --git a/src/login/logind.c b/src/login/logind.c index 5a394401dc..d0d18ae540 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -74,16 +74,18 @@ Manager *manager_new(void) { m->users = hashmap_new(trivial_hash_func, trivial_compare_func); m->inhibitors = hashmap_new(string_hash_func, string_compare_func); m->buttons = hashmap_new(string_hash_func, string_compare_func); + m->machines = hashmap_new(string_hash_func, string_compare_func); m->user_cgroups = hashmap_new(string_hash_func, string_compare_func); m->session_cgroups = hashmap_new(string_hash_func, string_compare_func); + m->machine_cgroups = hashmap_new(string_hash_func, string_compare_func); m->session_fds = hashmap_new(trivial_hash_func, trivial_compare_func); m->inhibitor_fds = hashmap_new(trivial_hash_func, trivial_compare_func); m->button_fds = hashmap_new(trivial_hash_func, trivial_compare_func); - if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || - !m->user_cgroups || !m->session_cgroups || + if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || !m->machines || + !m->user_cgroups || !m->session_cgroups || !m->machine_cgroups || !m->session_fds || !m->inhibitor_fds || !m->button_fds) { manager_free(m); return NULL; @@ -102,11 +104,14 @@ Manager *manager_new(void) { return NULL; } - if (cg_get_user_path(&m->cgroup_path) < 0) { + if (cg_get_root_path(&m->cgroup_root) < 0) { manager_free(m); return NULL; } + if (streq(m->cgroup_root, "/")) + m->cgroup_root[0] = 0; + return m; } @@ -117,6 +122,7 @@ void manager_free(Manager *m) { Seat *s; Inhibitor *i; Button *b; + Machine *machine; assert(m); @@ -138,15 +144,20 @@ void manager_free(Manager *m) { while ((b = hashmap_first(m->buttons))) button_free(b); + while ((machine = hashmap_first(m->machines))) + machine_free(machine); + hashmap_free(m->devices); hashmap_free(m->seats); hashmap_free(m->sessions); hashmap_free(m->users); hashmap_free(m->inhibitors); hashmap_free(m->buttons); + hashmap_free(m->machines); hashmap_free(m->user_cgroups); hashmap_free(m->session_cgroups); + hashmap_free(m->machine_cgroups); hashmap_free(m->session_fds); hashmap_free(m->inhibitor_fds); @@ -190,7 +201,7 @@ void manager_free(Manager *m) { free(m->action_job); - free(m->cgroup_path); + free(m->cgroup_root); free(m); } @@ -242,7 +253,7 @@ int manager_add_seat(Manager *m, const char *id, Seat **_seat) { return 0; } -int manager_add_session(Manager *m, User *u, const char *id, Session **_session) { +int manager_add_session(Manager *m, const char *id, Session **_session) { Session *s; assert(m); @@ -256,7 +267,7 @@ int manager_add_session(Manager *m, User *u, const char *id, Session **_session) return 0; } - s = session_new(m, u, id); + s = session_new(m, id); if (!s) return -ENOMEM; @@ -366,6 +377,30 @@ int manager_add_button(Manager *m, const char *name, Button **_button) { return 0; } +int manager_add_machine(Manager *m, const char *name, Machine **_machine) { + Machine *machine; + + assert(m); + assert(name); + + machine = hashmap_get(m->machines, name); + if (machine) { + if (_machine) + *_machine = machine; + + return 0; + } + + machine = machine_new(m, name); + if (!m) + return -ENOMEM; + + if (_machine) + *_machine = machine; + + return 0; +} + int manager_process_seat_device(Manager *m, struct udev_device *d) { Device *device; int r; @@ -554,7 +589,7 @@ finish: } int manager_enumerate_seats(Manager *m) { - DIR *d; + _cleanup_closedir_ DIR *d = NULL; struct dirent *de; int r = 0; @@ -573,7 +608,7 @@ int manager_enumerate_seats(Manager *m) { return -errno; } - while ((de = readdir(d))) { + FOREACH_DIRENT(de, d, return -errno) { Seat *s; int k; @@ -591,66 +626,16 @@ int manager_enumerate_seats(Manager *m) { r = k; } - closedir(d); - - return r; -} - -static int manager_enumerate_users_from_cgroup(Manager *m) { - _cleanup_closedir_ DIR *d = NULL; - int r = 0, k; - char *name; - - r = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_path, &d); - if (r < 0) { - if (r == -ENOENT) - return 0; - - log_error("Failed to open %s: %s", m->cgroup_path, strerror(-r)); - return r; - } - - while ((k = cg_read_subgroup(d, &name)) > 0) { - User *user; - char *e; - - e = endswith(name, ".user"); - if (e) { - *e = 0; - - k = manager_add_user_by_name(m, name, &user); - if (k < 0) { - free(name); - r = k; - continue; - } - - user_add_to_gc_queue(user); - - if (!user->cgroup_path) { - user->cgroup_path = strjoin(m->cgroup_path, "/", name, NULL); - if (!user->cgroup_path) { - k = log_oom(); - free(name); - break; - } - } - } - - free(name); - } - - if (k < 0) - r = k; - return r; } static int manager_enumerate_linger_users(Manager *m) { - DIR *d; + _cleanup_closedir_ DIR *d = NULL; struct dirent *de; int r = 0; + assert(m); + d = opendir("/var/lib/systemd/linger"); if (!d) { if (errno == ENOENT) @@ -660,7 +645,7 @@ static int manager_enumerate_linger_users(Manager *m) { return -errno; } - while ((de = readdir(d))) { + FOREACH_DIRENT(de, d, return -errno) { int k; if (!dirent_is_file(de)) @@ -673,27 +658,22 @@ static int manager_enumerate_linger_users(Manager *m) { } } - closedir(d); - return r; } int manager_enumerate_users(Manager *m) { - DIR *d; + _cleanup_closedir_ DIR *d = NULL; struct dirent *de; int r, k; assert(m); - /* First, enumerate user cgroups */ - r = manager_enumerate_users_from_cgroup(m); - - /* Second, add lingering users on top */ + /* Add lingering users */ k = manager_enumerate_linger_users(m); if (k < 0) r = k; - /* Third, read in user data stored on disk */ + /* Read in user data stored on disk */ d = opendir("/run/systemd/users"); if (!d) { if (errno == ENOENT) @@ -703,88 +683,65 @@ int manager_enumerate_users(Manager *m) { return -errno; } - while ((de = readdir(d))) { - uid_t uid; + FOREACH_DIRENT(de, d, return -errno) { User *u; if (!dirent_is_file(de)) continue; - k = parse_uid(de->d_name, &uid); + k = manager_add_user_by_name(m, de->d_name, &u); if (k < 0) { - log_error("Failed to parse file name %s: %s", de->d_name, strerror(-k)); - continue; - } + log_error("Failed to add user by file name %s: %s", de->d_name, strerror(-k)); - u = hashmap_get(m->users, ULONG_TO_PTR(uid)); - if (!u) { - unlinkat(dirfd(d), de->d_name, 0); + r = k; continue; } + user_add_to_gc_queue(u); + k = user_load(u); if (k < 0) r = k; } - closedir(d); - return r; } -static int manager_enumerate_sessions_from_cgroup(Manager *m) { - User *u; - Iterator i; +int manager_enumerate_sessions(Manager *m) { + _cleanup_closedir_ DIR *d = NULL; + struct dirent *de; int r = 0; - HASHMAP_FOREACH(u, m->users, i) { - _cleanup_closedir_ DIR *d = NULL; - char *name; + assert(m); + + /* Read in session data stored on disk */ + d = opendir("/run/systemd/sessions"); + if (!d) { + if (errno == ENOENT) + return 0; + + log_error("Failed to open /run/systemd/sessions: %m"); + return -errno; + } + + FOREACH_DIRENT(de, d, return -errno) { + struct Session *s; int k; - if (!u->cgroup_path) + if (!dirent_is_file(de)) continue; - k = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, &d); + k = manager_add_session(m, de->d_name, &s); if (k < 0) { - if (k == -ENOENT) - continue; + log_error("Failed to add session by file name %s: %s", de->d_name, strerror(-k)); - log_error("Failed to open %s: %s", u->cgroup_path, strerror(-k)); r = k; continue; } - while ((k = cg_read_subgroup(d, &name)) > 0) { - Session *session; - char *e; - - e = endswith(name, ".session"); - if (e) { - *e = 0; - - k = manager_add_session(m, u, name, &session); - if (k < 0) { - free(name); - r = k; - continue; - } - - session_add_to_gc_queue(session); - - if (!session->cgroup_path) { - session->cgroup_path = strjoin(m->cgroup_path, "/", name, NULL); - if (!session->cgroup_path) { - k = log_oom(); - free(name); - break; - } - } - } - - free(name); - } + session_add_to_gc_queue(s); + k = session_load(s); if (k < 0) r = k; } @@ -792,86 +749,83 @@ static int manager_enumerate_sessions_from_cgroup(Manager *m) { return r; } -int manager_enumerate_sessions(Manager *m) { - DIR *d; +int manager_enumerate_inhibitors(Manager *m) { + _cleanup_closedir_ DIR *d = NULL; struct dirent *de; int r = 0; assert(m); - /* First enumerate session cgroups */ - r = manager_enumerate_sessions_from_cgroup(m); - - /* Second, read in session data stored on disk */ - d = opendir("/run/systemd/sessions"); + d = opendir("/run/systemd/inhibit"); if (!d) { if (errno == ENOENT) return 0; - log_error("Failed to open /run/systemd/sessions: %m"); + log_error("Failed to open /run/systemd/inhibit: %m"); return -errno; } - while ((de = readdir(d))) { - struct Session *s; + FOREACH_DIRENT(de, d, return -errno) { int k; + Inhibitor *i; if (!dirent_is_file(de)) continue; - s = hashmap_get(m->sessions, de->d_name); - if (!s) { - unlinkat(dirfd(d), de->d_name, 0); + k = manager_add_inhibitor(m, de->d_name, &i); + if (k < 0) { + log_notice("Couldn't add inhibitor %s: %s", de->d_name, strerror(-k)); + r = k; continue; } - k = session_load(s); + k = inhibitor_load(i); if (k < 0) r = k; } - closedir(d); - return r; } -int manager_enumerate_inhibitors(Manager *m) { - DIR *d; +int manager_enumerate_machines(Manager *m) { + _cleanup_closedir_ DIR *d = NULL; struct dirent *de; int r = 0; assert(m); - d = opendir("/run/systemd/inhibit"); + /* Read in machine data stored on disk */ + d = opendir("/run/systemd/machines"); if (!d) { if (errno == ENOENT) return 0; - log_error("Failed to open /run/systemd/inhibit: %m"); + log_error("Failed to open /run/systemd/machines: %m"); return -errno; } - while ((de = readdir(d))) { + FOREACH_DIRENT(de, d, return -errno) { + struct Machine *machine; int k; - Inhibitor *i; if (!dirent_is_file(de)) continue; - k = manager_add_inhibitor(m, de->d_name, &i); + k = manager_add_machine(m, de->d_name, &machine); if (k < 0) { - log_notice("Couldn't add inhibitor %s: %s", de->d_name, strerror(-k)); + log_error("Failed to add machine by file name %s: %s", de->d_name, strerror(-k)); + r = k; continue; } - k = inhibitor_load(i); + machine_add_to_gc_queue(machine); + + k = machine_load(machine); if (k < 0) r = k; } - closedir(d); - return r; } @@ -1109,6 +1063,43 @@ int manager_get_user_by_cgroup(Manager *m, const char *cgroup, User **user) { } } +int manager_get_machine_by_cgroup(Manager *m, const char *cgroup, Machine **machine) { + Machine *u; + char *p; + + assert(m); + assert(cgroup); + assert(machine); + + u = hashmap_get(m->machine_cgroups, cgroup); + if (u) { + *machine = u; + return 1; + } + + p = strdupa(cgroup); + if (!p) + return log_oom(); + + for (;;) { + char *e; + + e = strrchr(p, '/'); + if (!e || e == p) { + *machine = NULL; + return 0; + } + + *e = 0; + + u = hashmap_get(m->machine_cgroups, p); + if (u) { + *machine = u; + return 1; + } + } +} + int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) { _cleanup_free_ char *p = NULL; int r; @@ -1124,7 +1115,38 @@ int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) { return manager_get_session_by_cgroup(m, p, session); } +int manager_get_user_by_pid(Manager *m, pid_t pid, User **user) { + _cleanup_free_ char *p = NULL; + int r; + + assert(m); + assert(pid >= 1); + assert(user); + + r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &p); + if (r < 0) + return r; + + return manager_get_user_by_cgroup(m, p, user); +} + +int manager_get_machine_by_pid(Manager *m, pid_t pid, Machine **machine) { + _cleanup_free_ char *p = NULL; + int r; + + assert(m); + assert(pid >= 1); + assert(machine); + + r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &p); + if (r < 0) + return r; + + return manager_get_machine_by_cgroup(m, p, machine); +} + void manager_cgroup_notify_empty(Manager *m, const char *cgroup) { + Machine *machine; Session *s; User *u; int r; @@ -1136,6 +1158,10 @@ void manager_cgroup_notify_empty(Manager *m, const char *cgroup) { r = manager_get_user_by_cgroup(m, cgroup, &u); if (r > 0) user_add_to_gc_queue(u); + + r = manager_get_machine_by_cgroup(m, cgroup, &machine); + if (r > 0) + machine_add_to_gc_queue(machine); } static void manager_dispatch_other(Manager *m, int fd) { @@ -1197,6 +1223,7 @@ static int manager_connect_bus(Manager *m) { !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/seat", &bus_seat_vtable, m) || !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/session", &bus_session_vtable, m) || !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/user", &bus_user_vtable, m) || + !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/machine", &bus_machine_vtable, m) || !dbus_connection_add_filter(m->bus, bus_message_filter, m, NULL)) { r = log_oom(); goto fail; @@ -1371,6 +1398,7 @@ void manager_gc(Manager *m, bool drop_not_started) { Seat *seat; Session *session; User *user; + Machine *machine; assert(m); @@ -1403,6 +1431,16 @@ void manager_gc(Manager *m, bool drop_not_started) { user_free(user); } } + + while ((machine = m->machine_gc_queue)) { + LIST_REMOVE(Machine, gc_queue, m->machine_gc_queue, machine); + machine->in_gc_queue = false; + + if (machine_check_gc(machine, drop_not_started) == 0) { + machine_stop(machine); + machine_free(machine); + } + } } int manager_get_idle_hint(Manager *m, dual_timestamp *t) { @@ -1521,6 +1559,7 @@ int manager_startup(Manager *m) { Session *session; User *user; Inhibitor *inhibitor; + Machine *machine; Iterator i; assert(m); @@ -1560,6 +1599,7 @@ int manager_startup(Manager *m) { manager_enumerate_sessions(m); manager_enumerate_inhibitors(m); manager_enumerate_buttons(m); + manager_enumerate_machines(m); /* Remove stale objects before we start them */ manager_gc(m, false); @@ -1580,6 +1620,9 @@ int manager_startup(Manager *m) { HASHMAP_FOREACH(inhibitor, m->inhibitors, i) inhibitor_start(inhibitor); + HASHMAP_FOREACH(machine, m->machines, i) + machine_start(machine); + manager_dispatch_idle_action(m); return 0; @@ -1731,6 +1774,7 @@ int main(int argc, char *argv[]) { mkdir_label("/run/systemd/seats", 0755); mkdir_label("/run/systemd/users", 0755); mkdir_label("/run/systemd/sessions", 0755); + mkdir_label("/run/systemd/machines", 0755); m = manager_new(); if (!m) { diff --git a/src/login/logind.h b/src/login/logind.h index 904dc20467..ce25211878 100644 --- a/src/login/logind.h +++ b/src/login/logind.h @@ -41,6 +41,7 @@ typedef struct Manager Manager; #include "logind-inhibit.h" #include "logind-button.h" #include "logind-action.h" +#include "logind-machine.h" struct Manager { DBusConnection *bus; @@ -51,10 +52,12 @@ struct Manager { Hashmap *users; Hashmap *inhibitors; Hashmap *buttons; + Hashmap *machines; LIST_HEAD(Seat, seat_gc_queue); LIST_HEAD(Session, session_gc_queue); LIST_HEAD(User, user_gc_queue); + LIST_HEAD(Machine, machine_gc_queue); struct udev *udev; struct udev_monitor *udev_seat_monitor, *udev_vcsa_monitor, *udev_button_monitor; @@ -74,7 +77,7 @@ struct Manager { Seat *vtconsole; - char *cgroup_path; + char *cgroup_root; char **controllers, **reset_controllers; char **kill_only_users, **kill_exclude_users; @@ -86,6 +89,7 @@ struct Manager { Hashmap *session_cgroups; Hashmap *user_cgroups; + Hashmap *machine_cgroups; Hashmap *session_fds; Hashmap *inhibitor_fds; @@ -139,11 +143,12 @@ void manager_free(Manager *m); int manager_add_device(Manager *m, const char *sysfs, Device **_device); int manager_add_button(Manager *m, const char *name, Button **_button); int manager_add_seat(Manager *m, const char *id, Seat **_seat); -int manager_add_session(Manager *m, User *u, const char *id, Session **_session); +int manager_add_session(Manager *m, const char *id, Session **_session); int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **_user); int manager_add_user_by_name(Manager *m, const char *name, User **_user); int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user); int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **_inhibitor); +int manager_add_machine(Manager *m, const char *name, Machine **_machine); int manager_process_seat_device(Manager *m, struct udev_device *d); int manager_process_button_device(Manager *m, struct udev_device *d); @@ -160,6 +165,7 @@ int manager_enumerate_seats(Manager *m); int manager_enumerate_sessions(Manager *m); int manager_enumerate_users(Manager *m); int manager_enumerate_inhibitors(Manager *m); +int manager_enumerate_machines(Manager *m); int manager_startup(Manager *m); int manager_run(Manager *m); @@ -172,8 +178,11 @@ void manager_gc(Manager *m, bool drop_not_started); int manager_get_idle_hint(Manager *m, dual_timestamp *t); int manager_get_user_by_cgroup(Manager *m, const char *cgroup, User **user); +int manager_get_user_by_pid(Manager *m, pid_t pid, User **user); int manager_get_session_by_cgroup(Manager *m, const char *cgroup, Session **session); int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session); +int manager_get_machine_by_cgroup(Manager *m, const char *cgroup, Machine **machine); +int manager_get_machine_by_pid(Manager *m, pid_t pid, Machine **machine); extern const DBusObjectPathVTable bus_manager_vtable; diff --git a/src/login/sd-login.c b/src/login/sd-login.c index d0dc42f685..d2e95034e1 100644 --- a/src/login/sd-login.c +++ b/src/login/sd-login.c @@ -598,7 +598,7 @@ _public_ int sd_get_machine_names(char ***machines) { char *n; int c = 0, r; - r = cg_get_machine_path(NULL, &md); + r = cg_get_root_path(&md); if (r < 0) return r; @@ -681,7 +681,7 @@ _public_ int sd_login_monitor_new(const char *category, sd_login_monitor **m) { _cleanup_free_ char *md = NULL, *p = NULL; int r; - r = cg_get_machine_path(NULL, &md); + r = cg_get_root_path(&md); if (r < 0) return r; diff --git a/src/login/user-sessions.c b/src/login/user-sessions.c index 41d32044e9..18066ccc39 100644 --- a/src/login/user-sessions.c +++ b/src/login/user-sessions.c @@ -28,6 +28,106 @@ #include "cgroup-util.h" #include "fileio.h" +static int kill_all_users(void) { + _cleanup_closedir_ DIR *d = NULL; + struct dirent *de; + int r = 0; + + d = opendir("/run/systemd/users"); + if (!d) { + if (errno == ENOENT) + return 0; + + log_error("Failed to open /run/systemd/users: %m"); + return -errno; + } + + FOREACH_DIRENT(de, d, return -errno) { + _cleanup_free_ char *cgroup = NULL; + char *a; + int k; + + if (!dirent_is_file(de)) + continue; + + a = strappenda("/run/systemd/users/", de->d_name); + + k = parse_env_file(a, NEWLINE, "CGROUP", &cgroup, NULL); + if (k < 0) { + if (k != -ENOENT) { + log_error("Failed to read user data: %s", strerror(-k)); + r = k; + } + + continue; + } + + if (!cgroup) { + log_error("User data did not contain cgroup field."); + r = -ENOENT; + continue; + } + + k = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, cgroup, true); + if (k < 0) { + log_error("Failed to kill cgroup %s: %s", cgroup, strerror(-k)); + r = k; + } + } + + return r; +} + +static int kill_all_sessions(void) { + _cleanup_closedir_ DIR *d = NULL; + struct dirent *de; + int r = 0; + + d = opendir("/run/systemd/sessions"); + if (!d) { + if (errno == ENOENT) + return 0; + + log_error("Failed to open /run/systemd/sessions: %m"); + return -errno; + } + + FOREACH_DIRENT(de, d, return -errno) { + _cleanup_free_ char *cgroup = NULL; + char *a; + int k; + + if (!dirent_is_file(de)) + continue; + + a = strappenda("/run/systemd/sessions/", de->d_name); + + k = parse_env_file(a, NEWLINE, "CGROUP", &cgroup, NULL); + if (k < 0) { + if (k != -ENOENT) { + log_error("Failed to read session data: %s", strerror(-k)); + r = k; + } + + continue; + } + + if (!cgroup) { + log_error("Session data did not contain cgroup field."); + r = -ENOENT; + continue; + } + + k = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, cgroup, true); + if (k < 0) { + log_error("Failed to kill cgroup %s: %s", cgroup, strerror(-k)); + r = k; + } + } + + return r; +} + int main(int argc, char*argv[]) { int ret = EXIT_FAILURE; @@ -68,27 +168,18 @@ int main(int argc, char*argv[]) { } else if (streq(argv[1], "stop")) { int r, q; - char *cgroup_user_tree = NULL; r = write_string_file_atomic("/run/nologin", "System is going down."); if (r < 0) log_error("Failed to create /run/nologin: %s", strerror(-r)); - q = cg_get_user_path(&cgroup_user_tree); - if (q < 0) { - log_error("Failed to determine use path: %s", strerror(-q)); - goto finish; - } - - q = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, cgroup_user_tree, true); - free(cgroup_user_tree); - if (q < 0) { - log_error("Failed to kill sessions: %s", strerror(-q)); - goto finish; - } + q = kill_all_users(); + if (q < 0 && r >= 0) + r = q; - if (r < 0) - goto finish; + q = kill_all_sessions(); + if (q < 0 && r >= 0) + r = q; } else { log_error("Unknown verb %s.", argv[1]); diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 32cfe05dcd..83be00231c 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -43,11 +43,8 @@ #include #include -#ifdef HAVE_XATTR -#include -#endif - #include +#include #include "log.h" #include "util.h" @@ -64,6 +61,8 @@ #include "fdset.h" #include "build.h" #include "fileio.h" +#include "bus-internal.h" +#include "bus-message.h" #ifndef TTY_GID #define TTY_GID 5 @@ -78,9 +77,9 @@ typedef enum LinkJournal { static char *arg_directory = NULL; static char *arg_user = NULL; -static char **arg_controllers = NULL; -static char *arg_uuid = NULL; +static sd_id128_t arg_uuid = {}; static char *arg_machine = NULL; +static const char *arg_slice = NULL; static bool arg_private_network = false; static bool arg_read_only = false; static bool arg_boot = false; @@ -123,10 +122,9 @@ static int help(void) { " -D --directory=NAME Root directory for the container\n" " -b --boot Boot up full system (i.e. invoke init)\n" " -u --user=USER Run the command under specified user or uid\n" - " -C --controllers=LIST Put the container in specified comma-separated\n" - " cgroup hierarchies\n" " --uuid=UUID Set a specific machine UUID for the container\n" " -M --machine=NAME Set the machine name for the container\n" + " -S --slice=SLICE Place the container in the specified slice\n" " --private-network Disable network in container\n" " --read-only Mount the root directory read-only\n" " --capability=CAP In addition to the default, retain specified\n" @@ -159,7 +157,6 @@ static int parse_argv(int argc, char *argv[]) { { "version", no_argument, NULL, ARG_VERSION }, { "directory", required_argument, NULL, 'D' }, { "user", required_argument, NULL, 'u' }, - { "controllers", required_argument, NULL, 'C' }, { "private-network", no_argument, NULL, ARG_PRIVATE_NETWORK }, { "boot", no_argument, NULL, 'b' }, { "uuid", required_argument, NULL, ARG_UUID }, @@ -169,15 +166,16 @@ static int parse_argv(int argc, char *argv[]) { { "bind", required_argument, NULL, ARG_BIND }, { "bind-ro", required_argument, NULL, ARG_BIND_RO }, { "machine", required_argument, NULL, 'M' }, + { "slice", required_argument, NULL, 'S' }, { NULL, 0, NULL, 0 } }; - int c; + int c, r; assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "+hD:u:C:bM:j", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "+hD:u:C:bM:jS:", options, NULL)) >= 0) { switch (c) { @@ -208,15 +206,6 @@ static int parse_argv(int argc, char *argv[]) { break; - case 'C': - strv_free(arg_controllers); - arg_controllers = strv_split(optarg, ","); - if (!arg_controllers) - return log_oom(); - - cg_shorten_controllers(arg_controllers); - break; - case ARG_PRIVATE_NETWORK: arg_private_network = true; break; @@ -226,12 +215,15 @@ static int parse_argv(int argc, char *argv[]) { break; case ARG_UUID: - if (!id128_is_valid(optarg)) { + r = sd_id128_from_string(optarg, &arg_uuid); + if (r < 0) { log_error("Invalid UUID: %s", optarg); - return -EINVAL; + return r; } + break; - arg_uuid = optarg; + case 'S': + arg_slice = strdup(optarg); break; case 'M': @@ -301,7 +293,6 @@ static int parse_argv(int argc, char *argv[]) { _cleanup_free_ char *a = NULL, *b = NULL; char *e; char ***x; - int r; x = c == ARG_BIND ? &arg_bind : &arg_bind_ro; @@ -912,68 +903,6 @@ static int setup_journal(const char *directory) { return 0; } -static int setup_cgroup(const char *path) { - char **c; - int r; - - r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, path, 1); - if (r < 0) { - log_error("Failed to create cgroup: %s", strerror(-r)); - return r; - } - - STRV_FOREACH(c, arg_controllers) { - r = cg_create_and_attach(*c, path, 1); - if (r < 0) - log_warning("Failed to create cgroup in controller %s: %s", *c, strerror(-r)); - } - - return 0; -} - -static int save_attributes(const char *cgroup, pid_t pid, const char *uuid, const char *directory) { -#ifdef HAVE_XATTR - _cleanup_free_ char *path = NULL; - char buf[DECIMAL_STR_MAX(pid_t)]; - int r = 0, k; - - assert(cgroup); - assert(pid >= 0); - assert(arg_directory); - - assert_se(snprintf(buf, sizeof(buf), "%lu", (unsigned long) pid) < (int) sizeof(buf)); - - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, cgroup, NULL, &path); - if (r < 0) { - log_error("Failed to get path: %s", strerror(-r)); - return r; - } - - r = setxattr(path, "trusted.init_pid", buf, strlen(buf), XATTR_CREATE); - if (r < 0) - log_warning("Failed to set %s attribute on %s: %m", "trusted.init_pid", path); - - if (uuid) { - k = setxattr(path, "trusted.machine_id", uuid, strlen(uuid), XATTR_CREATE); - if (k < 0) { - log_warning("Failed to set %s attribute on %s: %m", "trusted.machine_id", path); - if (r == 0) - r = k; - } - } - - k = setxattr(path, "trusted.root_directory", directory, strlen(directory), XATTR_CREATE); - if (k < 0) { - log_warning("Failed to set %s attribute on %s: %m", "trusted.root_directory", path); - if (r == 0) - r = k; - } - return r; -#else - return 0; -#endif -} - static int drop_capabilities(void) { return capability_bounding_set_drop(~arg_retain, false); } @@ -1220,6 +1149,41 @@ finish: return r; } +static int register_machine(void) { + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_bus_unref_ sd_bus *bus = NULL; + int r; + + r = sd_bus_open_system(&bus); + if (r < 0) { + log_error("Failed to open system bus: %s", strerror(-r)); + return r; + } + + r = sd_bus_call_method( + bus, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "CreateMachine", + &error, + NULL, + "sayssuss", + arg_machine, + SD_BUS_APPEND_ID128(arg_uuid), + "nspawn", + "container", + (uint32_t) 0, + strempty(arg_slice), + strempty(arg_directory)); + if (r < 0) { + log_error("Failed to register machine: %s", error.message); + return r; + } + + return 0; +} + static bool audit_enabled(void) { int fd; @@ -1234,7 +1198,6 @@ static bool audit_enabled(void) { int main(int argc, char *argv[]) { pid_t pid = 0; int r = EXIT_FAILURE, k; - _cleanup_free_ char *newcg = NULL; _cleanup_close_ int master = -1; int n_fd_passed; const char *console = NULL; @@ -1325,22 +1288,6 @@ int main(int argc, char *argv[]) { fdset_close_others(fds); log_open(); - k = cg_get_machine_path(arg_machine, &newcg); - if (k < 0) { - log_error("Failed to determine machine cgroup path: %s", strerror(-k)); - goto finish; - } - - k = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, newcg, true); - if (k <= 0 && k != -ENOENT) { - log_error("Container already running."); - - free(newcg); - newcg = NULL; - - goto finish; - } - master = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC|O_NDELAY); if (master < 0) { log_error("Failed to acquire pseudo tty: %m"); @@ -1484,11 +1431,12 @@ int main(int argc, char *argv[]) { goto child_fail; } - if (setup_cgroup(newcg) < 0) - goto child_fail; - close_pipe(pipefd2); + r = register_machine(); + if (r < 0) + goto finish; + /* Mark everything as slave, so that we still * receive mounts from the real root, but don't * propagate mounts to the real root. */ @@ -1639,8 +1587,8 @@ int main(int argc, char *argv[]) { goto child_fail; } - if (arg_uuid) { - if (asprintf((char**)(envp + n_env++), "container_uuid=%s", arg_uuid) < 0) { + if (!sd_id128_equal(arg_uuid, SD_ID128_NULL)) { + if (asprintf((char**)(envp + n_env++), "container_uuid=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(arg_uuid)) < 0) { log_oom(); goto child_fail; } @@ -1702,8 +1650,6 @@ int main(int argc, char *argv[]) { fd_wait_for_event(pipefd2[0], POLLHUP, -1); close_nointr_nofail(pipefd2[0]); - save_attributes(newcg, pid, arg_uuid, arg_directory); - fdset_free(fds); fds = NULL; @@ -1756,12 +1702,11 @@ finish: close_pipe(kmsg_socket_pair); - if (newcg) - cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, newcg, true); + if (pid > 0) + kill(pid, SIGKILL); free(arg_directory); free(arg_machine); - strv_free(arg_controllers); fdset_free(fds); diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index 4f58affe38..05d026a587 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -38,6 +38,7 @@ #include "strv.h" #include "unit-name.h" #include "fileio.h" +#include "special.h" int cg_enumerate_processes(const char *controller, const char *path, FILE **_f) { _cleanup_free_ char *fs = NULL; @@ -470,19 +471,19 @@ static const char *normalize_controller(const char *controller) { static int join_path(const char *controller, const char *path, const char *suffix, char **fs) { char *t = NULL; - if (controller) { - if (path && suffix) + if (!isempty(controller)) { + if (!isempty(path) && !isempty(suffix)) t = strjoin("/sys/fs/cgroup/", controller, "/", path, "/", suffix, NULL); - else if (path) + else if (!isempty(path)) t = strjoin("/sys/fs/cgroup/", controller, "/", path, NULL); - else if (suffix) + else if (!isempty(suffix)) t = strjoin("/sys/fs/cgroup/", controller, "/", suffix, NULL); else t = strappend("/sys/fs/cgroup/", controller); } else { - if (path && suffix) + if (!isempty(path) && !isempty(suffix)) t = strjoin(path, "/", suffix, NULL); - else if (path) + else if (!isempty(path)) t = strdup(path); else return -EINVAL; @@ -1091,96 +1092,20 @@ int cg_mangle_path(const char *path, char **result) { return cg_get_path(c ? c : SYSTEMD_CGROUP_CONTROLLER, p ? p : "/", NULL, result); } -int cg_get_system_path(char **path) { - char *p; - int r; - - assert(path); - - r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 1, &p); - if (r < 0) { - p = strdup("/system"); - if (!p) - return -ENOMEM; - } - - if (endswith(p, "/system")) - *path = p; - else { - char *q; - - q = strappend(p, "/system"); - free(p); - if (!q) - return -ENOMEM; - - *path = q; - } - - return 0; -} - int cg_get_root_path(char **path) { - char *root, *e; + char *p, *e; int r; assert(path); - r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 1, &root); + r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 1, &p); if (r < 0) return r; - e = endswith(root, "/system"); - if (e == root) - e[1] = 0; - else if (e) + e = endswith(p, "/" SPECIAL_SYSTEM_SLICE); + if (e) *e = 0; - *path = root; - return 0; -} - -int cg_get_user_path(char **path) { - _cleanup_free_ char *root = NULL; - char *p; - - assert(path); - - /* Figure out the place to put user cgroups below. We use the - * same as PID 1 has but with the "/system" suffix replaced by - * "/user" */ - - if (cg_get_root_path(&root) < 0 || streq(root, "/")) - p = strdup("/user"); - else - p = strappend(root, "/user"); - - if (!p) - return -ENOMEM; - - *path = p; - return 0; -} - -int cg_get_machine_path(const char *machine, char **path) { - _cleanup_free_ char *root = NULL, *escaped = NULL; - char *p; - - assert(path); - - if (machine) { - const char *name = strappenda(machine, ".nspawn"); - - escaped = cg_escape(name); - if (!escaped) - return -ENOMEM; - } - - p = strjoin(cg_get_root_path(&root) >= 0 && !streq(root, "/") ? root : "", - "/machine", machine ? "/" : "", machine ? escaped : "", NULL); - if (!p) - return -ENOMEM; - *path = p; return 0; } @@ -1301,15 +1226,29 @@ int cg_path_decode_unit(const char *cgroup, char **unit){ return 0; } +static const char *skip_slices(const char *p) { + size_t n; + + /* Skips over all slice assignments */ + + for (;;) { + p += strspn(p, "/"); + + n = strcspn(p, "/"); + if (n <= 6 || memcmp(p + n - 6, ".slice", 6) != 0) + return p; + + p += n; + } +} + int cg_path_get_unit(const char *path, char **unit) { const char *e; assert(path); assert(unit); - e = path_startswith(path, "/system/"); - if (!e) - return -ENOENT; + e = skip_slices(path); return cg_path_decode_unit(e, unit); } @@ -1327,15 +1266,55 @@ int cg_pid_get_unit(pid_t pid, char **unit) { return cg_path_get_unit(cgroup, unit); } -_pure_ static const char *skip_label(const char *e) { - assert(e); +static const char *skip_user(const char *p) { + size_t n; - e = strchr(e, '/'); - if (!e) + assert(p); + + p += strspn(p, "/"); + + n = strcspn(p, "/"); + if (n <= 5 || memcmp(p + n - 5, ".user", 5) != 0) + return p; + + p += n; + p += strspn(p, "/"); + + return p; +} + +static const char *skip_session(const char *p) { + size_t n; + + assert(p); + + p += strspn(p, "/"); + + n = strcspn(p, "/"); + if (n <= 8 || memcmp(p + n - 8, ".session", 8) != 0) return NULL; - e += strspn(e, "/"); - return e; + p += n; + p += strspn(p, "/"); + + return p; +} + +static const char *skip_systemd_label(const char *p) { + size_t n; + + assert(p); + + p += strspn(p, "/"); + + n = strcspn(p, "/"); + if (n < 8 || memcmp(p, "systemd-", 8) != 0) + return p; + + p += n; + p += strspn(p, "/"); + + return p; } int cg_path_get_user_unit(const char *path, char **unit) { @@ -1348,24 +1327,19 @@ int cg_path_get_user_unit(const char *path, char **unit) { * cgroups might have arbitrary child cgroups and we shouldn't get * confused by those */ - e = path_startswith(path, "/user/"); - if (!e) - return -ENOENT; + /* Skip slices, if there are any */ + e = skip_slices(path); - /* Skip the user name */ - e = skip_label(e); - if (!e) - return -ENOENT; + /* Skip the user name, if there is one */ + e = skip_user(e); - /* Skip the session ID */ - e = skip_label(e); + /* Skip the session ID, require that there is one */ + e = skip_session(e); if (!e) return -ENOENT; - /* Skip the systemd cgroup */ - e = skip_label(e); - if (!e) - return -ENOENT; + /* Skip the systemd cgroup, if there is one */ + e = skip_systemd_label(e); return cg_path_decode_unit(e, unit); } @@ -1384,23 +1358,27 @@ int cg_pid_get_user_unit(pid_t pid, char **unit) { } int cg_path_get_machine_name(const char *path, char **machine) { - const char *e, *n; + const char *e, *n, *x; char *s, *r; assert(path); assert(machine); - e = path_startswith(path, "/machine/"); - if (!e) - return -ENOENT; + /* Skip slices, if there are any */ + e = skip_slices(path); n = strchrnul(e, '/'); if (e == n) return -ENOENT; s = strndupa(e, n - e); + s = cg_unescape(s); + + x = endswith(s, ".machine"); + if (!x) + return -ENOENT; - r = strdup(cg_unescape(s)); + r = strndup(s, x - s); if (!r) return -ENOMEM; @@ -1428,14 +1406,11 @@ int cg_path_get_session(const char *path, char **session) { assert(path); assert(session); - e = path_startswith(path, "/user/"); - if (!e) - return -ENOENT; + /* Skip slices, if there are any */ + e = skip_slices(path); - /* Skip the user name */ - e = skip_label(e); - if (!e) - return -ENOENT; + /* Skip the user name, if there is one */ + e = skip_user(e); n = strchrnul(e, '/'); if (n - e < 8) @@ -1471,9 +1446,8 @@ int cg_path_get_owner_uid(const char *path, uid_t *uid) { assert(path); assert(uid); - e = path_startswith(path, "/user/"); - if (!e) - return -ENOENT; + /* Skip slices, if there are any */ + e = skip_slices(path); n = strchrnul(e, '/'); if (n - e < 5) diff --git a/src/shared/cgroup-util.h b/src/shared/cgroup-util.h index 84274e605d..0485c11ade 100644 --- a/src/shared/cgroup-util.h +++ b/src/shared/cgroup-util.h @@ -84,9 +84,6 @@ int cg_is_empty_by_spec(const char *spec, bool ignore_self); int cg_is_empty_recursive(const char *controller, const char *path, bool ignore_self); int cg_get_root_path(char **path); -int cg_get_system_path(char **path); -int cg_get_user_path(char **path); -int cg_get_machine_path(const char *machine, char **path); int cg_path_get_session(const char *path, char **session); int cg_path_get_owner_uid(const char *path, uid_t *uid); diff --git a/src/shared/unit-name.c b/src/shared/unit-name.c index 2d4cd8d9f3..0910e86f10 100644 --- a/src/shared/unit-name.c +++ b/src/shared/unit-name.c @@ -455,7 +455,7 @@ char *unit_name_to_path(const char *name) { } char *unit_dbus_path_from_name(const char *name) { - char *e, *p; + _cleanup_free_ char *e = NULL; assert(name); @@ -463,10 +463,7 @@ char *unit_dbus_path_from_name(const char *name) { if (!e) return NULL; - p = strappend("/org/freedesktop/systemd1/unit/", e); - free(e); - - return p; + return strappend("/org/freedesktop/systemd1/unit/", e); } char *unit_name_mangle(const char *name) { diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h index eeca69dd1a..878001ccb5 100644 --- a/src/systemd/sd-bus.h +++ b/src/systemd/sd-bus.h @@ -205,6 +205,12 @@ int sd_bus_error_copy(sd_bus_error *dest, const sd_bus_error *e); int sd_bus_error_is_set(const sd_bus_error *e); int sd_bus_error_has_name(const sd_bus_error *e, const char *name); +#define SD_BUS_APPEND_ID128(x) 16, \ + (x).bytes[0], (x).bytes[1], (x).bytes[2], (x).bytes[3], \ + (x).bytes[4], (x).bytes[5], (x).bytes[6], (x).bytes[7], \ + (x).bytes[8], (x).bytes[9], (x).bytes[10], (x).bytes[11], \ + (x).bytes[12], (x).bytes[13], (x).bytes[14], (x).bytes[15] + #ifdef __cplusplus } #endif diff --git a/src/systemd/sd-messages.h b/src/systemd/sd-messages.h index c8de331691..2f80749c0f 100644 --- a/src/systemd/sd-messages.h +++ b/src/systemd/sd-messages.h @@ -31,6 +31,10 @@ extern "C" { /* Hey! If you add a new message here, you *must* also update the * message catalog with an appropriate explanation */ +/* And if you add a new ID here, make sure to generate a random one + * with journalctl --new-id128. Do not use any other IDs, and do not + * count them up manually. */ + #define SD_MESSAGE_JOURNAL_START SD_ID128_MAKE(f7,73,79,a8,49,0b,40,8b,be,5f,69,40,50,5a,77,7b) #define SD_MESSAGE_JOURNAL_STOP SD_ID128_MAKE(d9,3f,b3,c9,c2,4d,45,1a,97,ce,a6,15,ce,59,c0,0b) #define SD_MESSAGE_JOURNAL_DROPPED SD_ID128_MAKE(a5,96,d6,fe,7b,fa,49,94,82,8e,72,30,9e,95,d6,1e) @@ -42,6 +46,8 @@ extern "C" { #define SD_MESSAGE_SESSION_STOP SD_ID128_MAKE(33,54,93,94,24,b4,45,6d,98,02,ca,83,33,ed,42,4a) #define SD_MESSAGE_SEAT_START SD_ID128_MAKE(fc,be,fc,5d,a2,3d,42,80,93,f9,7c,82,a9,29,0f,7b) #define SD_MESSAGE_SEAT_STOP SD_ID128_MAKE(e7,85,2b,fe,46,78,4e,d0,ac,cd,e0,4b,c8,64,c2,d5) +#define SD_MESSAGE_MACHINE_START SD_ID128_MAKE(24,d8,d4,45,25,73,40,24,96,06,83,81,a6,31,2d,f2) +#define SD_MESSAGE_MACHINE_STOP SD_ID128_MAKE(58,43,2b,d3,ba,ce,47,7c,b5,14,b5,63,81,b8,a7,58) #define SD_MESSAGE_TIME_CHANGE SD_ID128_MAKE(c7,a7,87,07,9b,35,4e,aa,a9,e7,7b,37,18,93,cd,27) #define SD_MESSAGE_TIMEZONE_CHANGE SD_ID128_MAKE(45,f8,2f,4a,ef,7a,4b,bf,94,2c,e8,61,d1,f2,09,90) diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c index d4d58b320b..aea8a7a1c3 100644 --- a/src/test/test-cgroup-util.c +++ b/src/test/test-cgroup-util.c @@ -47,6 +47,17 @@ static void check_p_g_u(const char *path, int code, const char *result) { assert_se(streq_ptr(unit, result)); } +static void test_path_get_unit(void) { + check_p_g_u("/system.slice/foobar.service/sdfdsaf", 0, "foobar.service"); + check_p_g_u("/system.slice/getty@.service/getty@tty5.service", 0, "getty@tty5.service"); + check_p_g_u("/system.slice/getty@.service/getty@tty5.service/aaa/bbb", 0, "getty@tty5.service"); + check_p_g_u("/system.slice/getty@.service/getty@tty5.service/", 0, "getty@tty5.service"); + check_p_g_u("/system.slice/getty@tty6.service/tty5", 0, "getty@tty6.service"); + check_p_g_u("sadfdsafsda", -EINVAL, NULL); + check_p_g_u("/system.slice/getty####@tty6.service/tty5", -EINVAL, NULL); + check_p_g_u("/system.slice/system-waldo.slice/foobar.service/sdfdsaf", 0, "foobar.service"); +} + static void check_p_g_u_u(const char *path, int code, const char *result) { _cleanup_free_ char *unit = NULL; @@ -54,39 +65,64 @@ static void check_p_g_u_u(const char *path, int code, const char *result) { assert_se(streq_ptr(unit, result)); } -static void test_path_get_unit(void) { - check_p_g_u("/system/foobar.service/sdfdsaf", 0, "foobar.service"); - check_p_g_u("/system/getty@.service/getty@tty5.service", 0, "getty@tty5.service"); - check_p_g_u("/system/getty@.service/getty@tty5.service/aaa/bbb", 0, "getty@tty5.service"); - check_p_g_u("/system/getty@.service/getty@tty5.service/", 0, "getty@tty5.service"); - check_p_g_u("/system/getty@tty6.service/tty5", 0, "getty@tty6.service"); - check_p_g_u("sadfdsafsda", -ENOENT, NULL); - check_p_g_u("/system/getty####@tty6.service/tty5", -EINVAL, NULL); +static void test_path_get_user_unit(void) { + check_p_g_u_u("/user.slice/1000.user/2.session/systemd-21548/foobar.service", 0, "foobar.service"); + check_p_g_u_u("/user.slice/1002.user/2.session/systemd-21548/foobar.service/waldo", 0, "foobar.service"); + check_p_g_u_u("/user.slice/1000.user/2.session/systemd-21548/foobar.service/waldo/uuuux", 0, "foobar.service"); + check_p_g_u_u("/user.slice/1000.user/2.session/systemd-21548/waldo/waldo/uuuux", -EINVAL, NULL); + check_p_g_u_u("/user.slice/1000.user/2.session/foobar.service", 0, "foobar.service"); + check_p_g_u_u("/user.slice/1000.user/2.session/systemd-21548/foobar@.service/foobar@pie.service/pa/po", 0, "foobar@pie.service"); + check_p_g_u_u("/2.session/systemd-21548/foobar@.service/foobar@pie.service/pa/po", 0, "foobar@pie.service"); + check_p_g_u_u("/xyz.slice/xyz-waldo.slice/77.session/systemd-21548/foobar@.service/foobar@pie.service/pa/po", 0, "foobar@pie.service"); + check_p_g_u_u("/meh.service", -ENOENT, NULL); } -static void test_path_get_user_unit(void) { - check_p_g_u_u("/user/lennart/2/systemd-21548/foobar.service", 0, "foobar.service"); - check_p_g_u_u("/user/lennart/2/systemd-21548/foobar.service/waldo", 0, "foobar.service"); - check_p_g_u_u("/user/lennart/2/systemd-21548/foobar.service/waldo/uuuux", 0, "foobar.service"); - check_p_g_u_u("/user/lennart/2/systemd-21548/waldo/waldo/uuuux", -EINVAL, NULL); - check_p_g_u_u("/user/lennart/2/foobar.service", -ENOENT, NULL); - check_p_g_u_u("/user/lennart/2/systemd-21548/foobar@.service/foobar@pie.service/pa/po", 0, "foobar@pie.service"); +static void check_p_g_s(const char *path, int code, const char *result) { + _cleanup_free_ char *s = NULL; + + assert_se(cg_path_get_session(path, &s) == code); + assert_se(streq_ptr(s, result)); } -static void test_get_paths(void) { - _cleanup_free_ char *a = NULL, *b = NULL, *c = NULL, *d = NULL; +static void test_path_get_session(void) { + check_p_g_s("/user.slice/1000.user/2.session/systemd-21548/foobar.service", 0, "2"); + check_p_g_s("/3.session", 0, "3"); + check_p_g_s("", -ENOENT, 0); +} - assert_se(cg_get_root_path(&a) >= 0); - log_info("Root = %s", a); +static void check_p_g_o_u(const char *path, int code, uid_t result) { + uid_t uid = 0; - assert_se(cg_get_system_path(&b) >= 0); - log_info("System = %s", b); + assert_se(cg_path_get_owner_uid(path, &uid) == code); + assert_se(uid == result); +} + +static void test_path_get_owner_uid(void) { + check_p_g_o_u("/user.slice/1000.user/2.session/systemd-21548/foobar.service", 0, 1000); + check_p_g_o_u("/1006.user", 0, 1006); + check_p_g_o_u("", -ENOENT, 0); +} - assert_se(cg_get_user_path(&c) >= 0); - log_info("User = %s", c); +static void check_p_g_m_n(const char *path, int code, const char *result) { + _cleanup_free_ char *m = NULL; - assert_se(cg_get_machine_path("harley", &d) >= 0); - log_info("Machine = %s", d); + assert_se(cg_path_get_machine_name(path, &m) == code); + assert_se(streq_ptr(m, result)); +} + +static void test_path_get_machine_name(void) { + check_p_g_m_n("/user.slice/foobar.machine", 0, "foobar"); + check_p_g_m_n("/foobar.machine", 0, "foobar"); + check_p_g_m_n("/user.slice/user-kuux.slice/foobar.machine", 0, "foobar"); + check_p_g_m_n("/user.slice/user-kuux.slice/foobar.machine/asjhdkj", 0, "foobar"); + check_p_g_m_n("", -ENOENT, NULL); +} + +static void test_get_paths(void) { + _cleanup_free_ char *a = NULL; + + assert_se(cg_get_root_path(&a) >= 0); + log_info("Root = %s", a); } static void test_proc(void) { @@ -193,6 +229,9 @@ int main(void) { test_path_decode_unit(); test_path_get_unit(); test_path_get_user_unit(); + test_path_get_session(); + test_path_get_owner_uid(); + test_path_get_machine_name(); test_get_paths(); test_proc(); test_escape(); diff --git a/units/machine.slice b/units/machine.slice index 6b1754b9dc..3d40dfd73b 100644 --- a/units/machine.slice +++ b/units/machine.slice @@ -8,6 +8,4 @@ [Unit] Description=Virtual Machine and Container Slice Documentation=man:systemd.special(7) - -[Install] -WantedBy=slices.target +Before=slices.target diff --git a/units/system.slice b/units/system.slice index f78ecb4388..8281fe58f6 100644 --- a/units/system.slice +++ b/units/system.slice @@ -9,3 +9,4 @@ Description=System Slice Documentation=man:systemd.special(7) DefaultDependencies=no +Before=slices.target diff --git a/units/systemd-logind.service.in b/units/systemd-logind.service.in index cf3c430b7f..ec05e670f3 100644 --- a/units/systemd-logind.service.in +++ b/units/systemd-logind.service.in @@ -9,7 +9,8 @@ Description=Login Service Documentation=man:systemd-logind.service(8) man:logind.conf(5) Documentation=http://www.freedesktop.org/wiki/Software/systemd/multiseat -After=nss-user-lookup.target +Wants=user.slice machine.slice +After=nss-user-lookup.target user.slice machine.slice [Service] ExecStart=@rootlibexecdir@/systemd-logind diff --git a/units/user.slice b/units/user.slice index dfaa44bcac..9fa6284c12 100644 --- a/units/user.slice +++ b/units/user.slice @@ -8,6 +8,4 @@ [Unit] Description=User and Session Slice Documentation=man:systemd.special(7) - -[Install] -WantedBy=slices.target +Before=slices.target -- cgit v1.2.1 From 5caef0fc192e88b2d965da50900567046e186ce1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 20 Jun 2013 04:00:28 +0200 Subject: logind: make ListMachines bus call public --- src/login/org.freedesktop.login1.conf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/login/org.freedesktop.login1.conf b/src/login/org.freedesktop.login1.conf index 6c1f2f57e5..0407609c19 100644 --- a/src/login/org.freedesktop.login1.conf +++ b/src/login/org.freedesktop.login1.conf @@ -60,6 +60,10 @@ send_interface="org.freedesktop.login1.Manager" send_member="ListUsers"/> + + -- cgit v1.2.1 From ba73ed858f27355d088fe2d96cb8c7e9eb75ff0c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 20 Jun 2013 04:03:38 +0200 Subject: sd-login: update machine enumeration/notifications APIs for new /run/systemd/machines/ --- TODO | 2 +- src/login/sd-login.c | 48 ++---------------------------------------------- 2 files changed, 3 insertions(+), 47 deletions(-) diff --git a/TODO b/TODO index f0af723d08..0b4048bf70 100644 --- a/TODO +++ b/TODO @@ -44,7 +44,7 @@ Features: RUNNING/LISTENING states of its socket * slices: - - add option to pam_systemd to move login session into a slice + - add option to pam_systemd to move login session into a slice (?) - remove ControlGroup= setting - in sd_pid_get_owner_uid() fallback to query session file - add api to determine slice of unit diff --git a/src/login/sd-login.c b/src/login/sd-login.c index d2e95034e1..875d134efc 100644 --- a/src/login/sd-login.c +++ b/src/login/sd-login.c @@ -592,40 +592,7 @@ _public_ int sd_get_uids(uid_t **users) { } _public_ int sd_get_machine_names(char ***machines) { - _cleanup_closedir_ DIR *d = NULL; - _cleanup_strv_free_ char **l = NULL; - _cleanup_free_ char *md = NULL; - char *n; - int c = 0, r; - - r = cg_get_root_path(&md); - if (r < 0) - return r; - - r = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, md, &d); - if (r < 0) - return r; - - while ((r = cg_read_subgroup(d, &n)) > 0) { - - r = strv_push(&l, n); - if (r < 0) { - free(n); - return -ENOMEM; - } - - c++; - } - - if (r < 0) - return r; - - if (machines) { - *machines = l; - l = NULL; - } - - return c; + return get_files_in_directory("/run/systemd/machines/", machines); } static inline int MONITOR_TO_FD(sd_login_monitor *m) { @@ -678,18 +645,7 @@ _public_ int sd_login_monitor_new(const char *category, sd_login_monitor **m) { } if (!category || streq(category, "machine")) { - _cleanup_free_ char *md = NULL, *p = NULL; - int r; - - r = cg_get_root_path(&md); - if (r < 0) - return r; - - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, md, NULL, &p); - if (r < 0) - return r; - - k = inotify_add_watch(fd, p, IN_MOVED_TO|IN_CREATE|IN_DELETE); + k = inotify_add_watch(fd, "/run/systemd/machines/", IN_MOVED_TO|IN_DELETE); if (k < 0) { close_nointr_nofail(fd); return -errno; -- cgit v1.2.1 From bd5a54582ae4e7cdc390d05ea8f73dc7d02ed147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 20 Jun 2013 00:01:15 -0400 Subject: nspawn: '-C' option has been removed Fixup for 9444b1f "logind: add infrastructure to keep track of machines, and move to slices." --- src/nspawn/nspawn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 83be00231c..66c2228ca2 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -175,7 +175,7 @@ static int parse_argv(int argc, char *argv[]) { assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "+hD:u:C:bM:jS:", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "+hD:u:bM:jS:", options, NULL)) >= 0) { switch (c) { -- cgit v1.2.1 From ac34b3af131af68e493c3dea071e5aad6eee3ecc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 20 Jun 2013 00:20:55 -0400 Subject: build-sys: make intltool and distcheck happy --- Makefile.am | 2 ++ po/POTFILES.skip | 1 + 2 files changed, 3 insertions(+) diff --git a/Makefile.am b/Makefile.am index ff5a129da8..016d7dad32 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3713,6 +3713,8 @@ UNINSTALL_EXEC_HOOKS += libsystemd-login-uninstall-hook nodist_systemunit_DATA += \ units/systemd-logind.service \ units/systemd-user-sessions.service + +dist_systemunit_DATA += \ units/user.slice \ units/machine.slice diff --git a/po/POTFILES.skip b/po/POTFILES.skip index 0502c13023..65327aaca5 100644 --- a/po/POTFILES.skip +++ b/po/POTFILES.skip @@ -5,6 +5,7 @@ src/core/dbus-manager.c src/core/dbus-mount.c src/core/dbus-path.c src/core/dbus-service.c +src/core/dbus-slice.c src/core/dbus-snapshot.c src/core/dbus-socket.c src/core/dbus-swap.c -- cgit v1.2.1 From b3629c7da0b4a406ecc2182fcd766581778173ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 20 Jun 2013 00:51:10 -0400 Subject: logind: uninitialized variable --- src/login/logind.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/login/logind.c b/src/login/logind.c index d0d18ae540..ea74254b28 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -669,9 +669,7 @@ int manager_enumerate_users(Manager *m) { assert(m); /* Add lingering users */ - k = manager_enumerate_linger_users(m); - if (k < 0) - r = k; + r = manager_enumerate_linger_users(m); /* Read in user data stored on disk */ d = opendir("/run/systemd/users"); -- cgit v1.2.1 From 6c10d3997019c4f09dad5650209b49c5ccd11551 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Thu, 20 Jun 2013 15:46:37 +0200 Subject: kernel-install: filter out "initrd=" from /proc/cmdline --- src/kernel-install/90-loaderentry.install | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/kernel-install/90-loaderentry.install b/src/kernel-install/90-loaderentry.install index 55b4d24672..6fbb14908a 100644 --- a/src/kernel-install/90-loaderentry.install +++ b/src/kernel-install/90-loaderentry.install @@ -38,15 +38,22 @@ if ! [[ $PRETTY_NAME ]]; then PRETTY_NAME="Linux $KERNEL_VERSION" fi +declare -a BOOT_OPTIONS + if [[ -f /etc/kernel/cmdline ]]; then readarray -t BOOT_OPTIONS < /etc/kernel/cmdline fi if ! [[ ${BOOT_OPTIONS[*]} ]]; then - readarray -t BOOT_OPTIONS < /proc/cmdline + readarray -t line < /proc/cmdline + for i in ${line[*]}; do + if [[ "${i#initrd=*}" == "$i" ]]; then + BOOT_OPTIONS[${#BOOT_OPTIONS[@]}]="$i" + fi + done fi -if ! [[ $BOOT_OPTIONS ]]; then +if ! [[ ${BOOT_OPTIONS[*]} ]]; then echo "Could not determine the kernel command line parameters." >&2 echo "Please specify the kernel command line in /etc/kernel/cmdline!" >&2 exit 1 -- cgit v1.2.1 From 8c1396b1c2dfecbb59af61064f6a0f624385004d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 20 Jun 2013 16:15:04 -0400 Subject: journalctl: show lines in full with --all In 31f7bf1 "logs-show: print multiline messages", I forgot to take into account the fact that --all implies --full for journalctl. --- src/shared/logs-show.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index 013a281eac..40efad3273 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -101,7 +101,7 @@ static bool shall_print(const char *p, size_t l, OutputFlags flags) { return true; } -static void print_multiline(FILE *f, unsigned prefix, unsigned n_columns, int flags, int priority, const char* message, size_t message_len) { +static void print_multiline(FILE *f, unsigned prefix, unsigned n_columns, OutputMode flags, int priority, const char* message, size_t message_len) { const char *color_on = "", *color_off = ""; const char *pos, *end; bool continuation = false; @@ -123,7 +123,7 @@ static void print_multiline(FILE *f, unsigned prefix, unsigned n_columns, int fl len = end - pos; assert(len >= 0); - if ((flags & OUTPUT_FULL_WIDTH) || (prefix + len + 1 < n_columns)) + if (flags & (OUTPUT_FULL_WIDTH | OUTPUT_SHOW_ALL) || prefix + len + 1 < n_columns) fprintf(f, "%*s%s%.*s%s\n", continuation * prefix, "", color_on, len, pos, color_off); -- cgit v1.2.1 From 97d0e5f83ba4dd713170f802b90149b7325bc992 Mon Sep 17 00:00:00 2001 From: Umut Tezduyar Date: Sun, 9 Jun 2013 07:08:46 +0200 Subject: manager: add DefaultEnvironment option This complements existing functionality of setting variables through 'systemctl set-environment', the kernel command line, and through normal environment variables for systemd in session mode. --- man/systemd-system.conf.xml | 21 +++++++++++++++++++++ man/systemd.exec.xml | 5 +++-- src/core/load-fragment.c | 8 ++++++-- src/core/main.c | 5 +++++ src/core/manager.c | 12 ++++++++++++ src/core/manager.h | 1 + src/core/system.conf | 1 + 7 files changed, 49 insertions(+), 4 deletions(-) diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml index d8bfd1279d..5886855407 100644 --- a/man/systemd-system.conf.xml +++ b/man/systemd-system.conf.xml @@ -262,6 +262,27 @@ too. + + DefaultEnvironment= + + Sets systemd manager + environment variables for executed + processes. Takes a space-separated + list of variable assignments. + + + Example: + Environment="VAR1=word1 word2" VAR2=word3 "VAR3=word 5 6" + gives three variables VAR1, + VAR2, VAR3. + + + + See + environ7 + for details about environment variables. + + DefaultLimitCPU= DefaultLimitFSIZE= diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index ab1712efeb..8d5948ab07 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -288,8 +288,9 @@ variables is reset, all prior assignments have no effect. Variable expansion is not performed - inside the strings, and $ has no special - meaning. + inside the strings, however, specifier + expansion is possible. $ character has + no special meaning. If you need to assign a value containing spaces to a variable, use double quotes (") for the assignment. diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 4a835b6e8b..15fabe860e 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -1564,7 +1564,7 @@ int config_parse_environ(const char *unit, assert(filename); assert(lvalue); assert(rvalue); - assert(u); + assert(data); if (isempty(rvalue)) { /* Empty assignment resets the list */ @@ -1573,7 +1573,11 @@ int config_parse_environ(const char *unit, return 0; } - k = unit_full_printf(u, rvalue); + if (u) + k = unit_full_printf(u, rvalue); + else + k = strdup(rvalue); + if (!k) return log_oom(); diff --git a/src/core/main.c b/src/core/main.c index 26aa561218..470fecf15d 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -94,6 +94,7 @@ static ExecOutput arg_default_std_output = EXEC_OUTPUT_JOURNAL; static ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT; static usec_t arg_runtime_watchdog = 0; static usec_t arg_shutdown_watchdog = 10 * USEC_PER_MINUTE; +static char **arg_default_environment = NULL; static struct rlimit *arg_default_rlimit[RLIMIT_NLIMITS] = {}; static uint64_t arg_capability_bounding_set_drop = 0; static nsec_t arg_timer_slack_nsec = (nsec_t) -1; @@ -646,6 +647,7 @@ static int parse_config_file(void) { { "Manager", "ShutdownWatchdogSec", config_parse_sec, 0, &arg_shutdown_watchdog }, { "Manager", "CapabilityBoundingSet", config_parse_bounding_set, 0, &arg_capability_bounding_set_drop }, { "Manager", "TimerSlackNSec", config_parse_nsec, 0, &arg_timer_slack_nsec }, + { "Manager", "DefaultEnvironment", config_parse_environ, 0, &arg_default_environment }, { "Manager", "DefaultLimitCPU", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_CPU]}, { "Manager", "DefaultLimitFSIZE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_FSIZE]}, { "Manager", "DefaultLimitDATA", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_DATA]}, @@ -1630,6 +1632,9 @@ int main(int argc, char *argv[]) { if (arg_default_controllers) manager_set_default_controllers(m, arg_default_controllers); + if (arg_default_environment) + manager_set_default_environment(m, arg_default_environment); + manager_set_show_status(m, arg_show_status); /* Remember whether we should queue the default job */ diff --git a/src/core/manager.c b/src/core/manager.c index f16621ac2b..5c3a2c72f3 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -2570,6 +2570,18 @@ void manager_undo_generators(Manager *m) { remove_generator_dir(m, &m->generator_unit_path_late); } +int manager_set_default_environment(Manager *m, char **environment) { + + char **e = NULL; + assert(m); + e = strv_env_merge(2, m->environment, environment); + if (!e) + return -ENOMEM; + strv_free(m->environment); + m->environment = e; + return 0; +} + int manager_set_default_controllers(Manager *m, char **controllers) { char **l; diff --git a/src/core/manager.h b/src/core/manager.h index e21c8f7abf..f0bb2eb035 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -272,6 +272,7 @@ unsigned manager_dispatch_load_queue(Manager *m); unsigned manager_dispatch_run_queue(Manager *m); unsigned manager_dispatch_dbus_queue(Manager *m); +int manager_set_default_environment(Manager *m, char **environment); int manager_set_default_controllers(Manager *m, char **controllers); int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit); diff --git a/src/core/system.conf b/src/core/system.conf index 508e0f5fa4..f2817bc507 100644 --- a/src/core/system.conf +++ b/src/core/system.conf @@ -25,6 +25,7 @@ #ShutdownWatchdogSec=10min #CapabilityBoundingSet= #TimerSlackNSec= +#DefaultEnvironment= #DefaultLimitCPU= #DefaultLimitFSIZE= #DefaultLimitDATA= -- cgit v1.2.1 From 3c86d34cf1e381ade10dcc41c655c98b2d489c8d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 20 Jun 2013 23:25:23 +0200 Subject: man: document that shutdown() is only sometimes OK on sockets passed in via socket activation --- man/systemd.socket.xml | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml index f1e7d408ab..040305c632 100644 --- a/man/systemd.socket.xml +++ b/man/systemd.socket.xml @@ -374,23 +374,30 @@ and only one service unit is spawned for all connections (also see above). This value is ignored for - datagram sockets and FIFOs where - a single service unit unconditionally + datagram sockets and FIFOs where a + single service unit unconditionally handles all incoming traffic. Defaults to . For performance reasons, it is recommended to write new daemons only in a way that is suitable for - . A daemon - listening on an AF_UNIX socket may, but does not need to, call + . A + daemon listening on an AF_UNIX socket + may, but does not need to, call close2 - or + on the received socket before + exiting. However, it must not unlink + the socket from a filesystem. It + should note invoke shutdown2 - on the received socket before exiting. However, - it must not unlink the socket from a - filesystem. This option is mostly useful - to allow daemons designed for usage with - inetd8, + on sockets it got with + Accept=false, but + it may do so for sockets it got with + Accept=true set. + Setting Accept=true + is mostly useful to allow daemons + designed for usage with + inetd8 to work unmodified with systemd socket activation. -- cgit v1.2.1 From 78894537e047690f074c5067989517acc1b3c40e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 20 Jun 2013 23:31:21 +0200 Subject: man: fix example for DefaultEnvironment= The example mentioned Environment= rather than DefaultEnvironment=. Also made some other clean-ups. --- man/systemd-system.conf.xml | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml index 5886855407..48d02269cc 100644 --- a/man/systemd-system.conf.xml +++ b/man/systemd-system.conf.xml @@ -265,22 +265,23 @@ DefaultEnvironment= - Sets systemd manager - environment variables for executed - processes. Takes a space-separated - list of variable assignments. - + Sets manager + environment variables passed to all + executed processes. Takes a + space-separated list of variable + assignments. See + environ7 + for details about environment + variables. Example: - Environment="VAR1=word1 word2" VAR2=word3 "VAR3=word 5 6" - gives three variables VAR1, - VAR2, VAR3. - - - See - environ7 - for details about environment variables. + DefaultEnvironment="VAR1=word1 word2" VAR2=word3 "VAR3=word 5 6" + + Sets three variables + VAR1, + VAR2, + VAR3. @@ -323,7 +324,8 @@ See Also systemd1, - systemd.directives7 + systemd.directives7, + environ7 -- cgit v1.2.1 From 3d3ee759e682701fce77b6559508e697e9e60fbf Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 20 Jun 2013 23:32:13 +0200 Subject: update TODO --- TODO | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/TODO b/TODO index 0b4048bf70..e11e85c7f9 100644 --- a/TODO +++ b/TODO @@ -28,6 +28,10 @@ Fedora 19: Features: +* when creating a session or machine, automatically move the process into the root cgroup for all other hierarchies + +* maybe reintroduce nspawn -C? + * move systemctl dump to systemd-analyze * libsystemd-logind: sd_session_is_active() and friends: verify -- cgit v1.2.1 From ed002560a1945fb8765c5559c293a19bc9e132d8 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Thu, 20 Jun 2013 13:36:33 -0700 Subject: core: only attempt to connect to a session bus if one likely exists. --- src/core/manager.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/core/manager.c b/src/core/manager.c index 5c3a2c72f3..2416dd0f1e 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -509,9 +509,13 @@ int manager_new(SystemdRunningAs running_as, Manager **_m) { goto fail; /* Try to connect to the busses, if possible. */ - r = bus_init(m, running_as != SYSTEMD_SYSTEM); - if (r < 0) - goto fail; + if ((running_as == SYSTEMD_USER && getenv("DBUS_SESSION_BUS_ADDRESS")) || + running_as == SYSTEMD_SYSTEM) { + r = bus_init(m, running_as != SYSTEMD_SYSTEM); + if (r < 0) + goto fail; + } else + log_debug("Skipping DBus session bus connection attempt - no DBUS_SESSION_BUS_ADDRESS set..."); m->taint_usr = dir_is_empty("/usr") > 0; -- cgit v1.2.1 From 1021b21bc6f8dd522b46116e8598b17f9f93f1b7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 21 Jun 2013 01:46:27 +0200 Subject: login: add an api to determine the slice a PID is located in to libsystemd-login --- src/login/libsystemd-login.sym | 5 +++++ src/login/sd-login.c | 10 +++++++++ src/shared/cgroup-util.c | 51 ++++++++++++++++++++++++++++++++++++++++-- src/shared/cgroup-util.h | 2 ++ src/systemd/sd-login.h | 5 ++++- src/test/test-cgroup-util.c | 8 ++++--- 6 files changed, 75 insertions(+), 6 deletions(-) diff --git a/src/login/libsystemd-login.sym b/src/login/libsystemd-login.sym index 925fb91095..417dbb18dc 100644 --- a/src/login/libsystemd-login.sym +++ b/src/login/libsystemd-login.sym @@ -75,3 +75,8 @@ LIBSYSTEMD_LOGIN_203 { global: sd_get_machine_names; } LIBSYSTEMD_LOGIN_202; + +LIBSYSTEMD_LOGIN_204 { +global: + sd_pid_get_slice; +} LIBSYSTEMD_LOGIN_203; diff --git a/src/login/sd-login.c b/src/login/sd-login.c index 875d134efc..06587921cd 100644 --- a/src/login/sd-login.c +++ b/src/login/sd-login.c @@ -72,6 +72,16 @@ _public_ int sd_pid_get_machine_name(pid_t pid, char **name) { return cg_pid_get_machine_name(pid, name); } +_public_ int sd_pid_get_slice(pid_t pid, char **slice) { + + if (pid < 0) + return -EINVAL; + if (!slice) + return -EINVAL; + + return cg_pid_get_slice(pid, slice); +} + _public_ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid) { if (pid < 0) diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index 05d026a587..9cbc64a541 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -1227,11 +1227,11 @@ int cg_path_decode_unit(const char *cgroup, char **unit){ } static const char *skip_slices(const char *p) { - size_t n; - /* Skips over all slice assignments */ for (;;) { + size_t n; + p += strspn(p, "/"); n = strcspn(p, "/"); @@ -1475,6 +1475,53 @@ int cg_pid_get_owner_uid(pid_t pid, uid_t *uid) { return cg_path_get_owner_uid(cgroup, uid); } +int cg_path_get_slice(const char *p, char **slice) { + const char *e = NULL; + size_t m = 0; + + assert(p); + assert(slice); + + for (;;) { + size_t n; + + p += strspn(p, "/"); + + n = strcspn(p, "/"); + if (n <= 6 || memcmp(p + n - 6, ".slice", 6) != 0) { + char *s; + + if (!e) + return -ENOENT; + + s = strndup(e, m); + if (!s) + return -ENOMEM; + + *slice = s; + return 0; + } + + e = p; + m = n; + + p += n; + } +} + +int cg_pid_get_slice(pid_t pid, char **slice) { + _cleanup_free_ char *cgroup = NULL; + int r; + + assert(slice); + + r = cg_pid_get_path_shifted(pid, NULL, &cgroup); + if (r < 0) + return r; + + return cg_path_get_slice(cgroup, slice); +} + int cg_controller_from_attr(const char *attr, char **controller) { const char *dot; char *c; diff --git a/src/shared/cgroup-util.h b/src/shared/cgroup-util.h index 0485c11ade..2d00bb3fff 100644 --- a/src/shared/cgroup-util.h +++ b/src/shared/cgroup-util.h @@ -90,6 +90,7 @@ int cg_path_get_owner_uid(const char *path, uid_t *uid); int cg_path_get_unit(const char *path, char **unit); int cg_path_get_user_unit(const char *path, char **unit); int cg_path_get_machine_name(const char *path, char **machine); +int cg_path_get_slice(const char *path, char **slice); int cg_pid_get_path_shifted(pid_t pid, char **root, char **cgroup); @@ -98,6 +99,7 @@ int cg_pid_get_owner_uid(pid_t pid, uid_t *uid); int cg_pid_get_unit(pid_t pid, char **unit); int cg_pid_get_user_unit(pid_t pid, char **unit); int cg_pid_get_machine_name(pid_t pid, char **machine); +int cg_pid_get_slice(pid_t pid, char **slice); int cg_path_decode_unit(const char *cgroup, char **unit); diff --git a/src/systemd/sd-login.h b/src/systemd/sd-login.h index 4855e327a1..e37aeda2bb 100644 --- a/src/systemd/sd-login.h +++ b/src/systemd/sd-login.h @@ -72,9 +72,12 @@ int sd_pid_get_unit(pid_t pid, char **unit); int sd_pid_get_user_unit(pid_t pid, char **unit); /* Get machine name from PID, for processes assigned to VM or - * container. This will return an error for non-service processes. */ + * container. This will return an error for non-machine processes. */ int sd_pid_get_machine_name(pid_t pid, char **name); +/* Get slice name from PID. */ +int sd_pid_get_slice(pid_t pid, char **name); + /* Get state from uid. Possible states: offline, lingering, online, active, closing */ int sd_uid_get_state(uid_t uid, char**state); diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c index aea8a7a1c3..f6317e5d33 100644 --- a/src/test/test-cgroup-util.c +++ b/src/test/test-cgroup-util.c @@ -134,7 +134,7 @@ static void test_proc(void) { assert_se(d); FOREACH_DIRENT(de, d, break) { - _cleanup_free_ char *path = NULL, *path_shifted = NULL, *session = NULL, *unit = NULL, *user_unit = NULL, *machine = NULL, *prefix = NULL; + _cleanup_free_ char *path = NULL, *path_shifted = NULL, *session = NULL, *unit = NULL, *user_unit = NULL, *machine = NULL, *prefix = NULL, *slice = NULL; pid_t pid; uid_t uid = (uid_t) -1; @@ -156,8 +156,9 @@ static void test_proc(void) { cg_pid_get_unit(pid, &unit); cg_pid_get_user_unit(pid, &user_unit); cg_pid_get_machine_name(pid, &machine); + cg_pid_get_slice(pid, &slice); - printf("%lu\t%s\t%s\t%s\t%lu\t%s\t%s\t%s\t%s\n", + printf("%lu\t%s\t%s\t%s\t%lu\t%s\t%s\t%s\t%s\t%s\n", (unsigned long) pid, path, prefix, @@ -166,7 +167,8 @@ static void test_proc(void) { session, unit, user_unit, - machine); + machine, + slice); } } -- cgit v1.2.1 From fd59d9f29838c3888168554c774003e7ad6d33b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 20 Jun 2013 22:40:10 -0400 Subject: Add hasprefix macro to check prefixes of fixed length --- src/journal/journal-send.c | 2 +- src/journal/journald-native.c | 10 +++++----- src/libsystemd-bus/bus-match.c | 26 +++++++++++++------------- src/shared/logs-show.c | 2 +- src/shared/macro.h | 2 ++ 5 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/journal/journal-send.c b/src/journal/journal-send.c index da1f892685..fef66fc29a 100644 --- a/src/journal/journal-send.c +++ b/src/journal/journal-send.c @@ -245,7 +245,7 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int n) { have_syslog_identifier = have_syslog_identifier || (c == (char *) iov[i].iov_base + 17 && - memcmp(iov[i].iov_base, "SYSLOG_IDENTIFIER", 17) == 0); + hasprefix(iov[i].iov_base, "SYSLOG_IDENTIFIER")); nl = memchr(iov[i].iov_base, '\n', iov[i].iov_len); if (nl) { diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c index f878dfc911..ec9afa187d 100644 --- a/src/journal/journald-native.c +++ b/src/journal/journald-native.c @@ -158,23 +158,23 @@ void server_process_native_message( * of this entry for the rate limiting * logic */ if (l == 10 && - memcmp(p, "PRIORITY=", 9) == 0 && + hasprefix(p, "PRIORITY=") && p[9] >= '0' && p[9] <= '9') priority = (priority & LOG_FACMASK) | (p[9] - '0'); else if (l == 17 && - memcmp(p, "SYSLOG_FACILITY=", 16) == 0 && + hasprefix(p, "SYSLOG_FACILITY=") && p[16] >= '0' && p[16] <= '9') priority = (priority & LOG_PRIMASK) | ((p[16] - '0') << 3); else if (l == 18 && - memcmp(p, "SYSLOG_FACILITY=", 16) == 0 && + hasprefix(p, "SYSLOG_FACILITY=") && p[16] >= '0' && p[16] <= '9' && p[17] >= '0' && p[17] <= '9') priority = (priority & LOG_PRIMASK) | (((p[16] - '0')*10 + (p[17] - '0')) << 3); else if (l >= 19 && - memcmp(p, "SYSLOG_IDENTIFIER=", 18) == 0) { + hasprefix(p, "SYSLOG_IDENTIFIER=")) { char *t; t = strndup(p + 18, l - 18); @@ -183,7 +183,7 @@ void server_process_native_message( identifier = t; } } else if (l >= 8 && - memcmp(p, "MESSAGE=", 8) == 0) { + hasprefix(p, "MESSAGE=")) { char *t; t = strndup(p + 8, l - 8); diff --git a/src/libsystemd-bus/bus-match.c b/src/libsystemd-bus/bus-match.c index 95e625be09..750acfe6d5 100644 --- a/src/libsystemd-bus/bus-match.c +++ b/src/libsystemd-bus/bus-match.c @@ -555,22 +555,22 @@ static int bus_match_find_leaf( enum bus_match_node_type bus_match_node_type_from_string(const char *k, size_t n) { assert(k); - if (n == 4 && memcmp(k, "type", 4) == 0) + if (n == 4 && hasprefix(k, "type")) return BUS_MATCH_MESSAGE_TYPE; - if (n == 6 && memcmp(k, "sender", 6) == 0) + if (n == 6 && hasprefix(k, "sender")) return BUS_MATCH_SENDER; - if (n == 11 && memcmp(k, "destination", 11) == 0) + if (n == 11 && hasprefix(k, "destination")) return BUS_MATCH_DESTINATION; - if (n == 9 && memcmp(k, "interface", 9) == 0) + if (n == 9 && hasprefix(k, "interface")) return BUS_MATCH_INTERFACE; - if (n == 6 && memcmp(k, "member", 6) == 0) + if (n == 6 && hasprefix(k, "member")) return BUS_MATCH_MEMBER; - if (n == 4 && memcmp(k, "path", 4) == 0) + if (n == 4 && hasprefix(k, "path")) return BUS_MATCH_PATH; - if (n == 14 && memcmp(k, "path_namespace", 14) == 0) + if (n == 14 && hasprefix(k, "path_namespace")) return BUS_MATCH_PATH_NAMESPACE; - if (n == 4 && memcmp(k, "arg", 3) == 0) { + if (n == 4 && hasprefix(k, "arg")) { int j; j = undecchar(k[3]); @@ -580,7 +580,7 @@ enum bus_match_node_type bus_match_node_type_from_string(const char *k, size_t n return BUS_MATCH_ARG + j; } - if (n == 5 && memcmp(k, "arg", 3) == 0) { + if (n == 5 && hasprefix(k, "arg")) { int a, b; enum bus_match_node_type t; @@ -596,7 +596,7 @@ enum bus_match_node_type bus_match_node_type_from_string(const char *k, size_t n return t; } - if (n == 8 && memcmp(k, "arg", 3) == 0 && memcmp(k + 4, "path", 4) == 0) { + if (n == 8 && hasprefix(k, "arg") && hasprefix(k + 4, "path")) { int j; j = undecchar(k[3]); @@ -606,7 +606,7 @@ enum bus_match_node_type bus_match_node_type_from_string(const char *k, size_t n return BUS_MATCH_ARG_PATH + j; } - if (n == 9 && memcmp(k, "arg", 3) == 0 && memcmp(k + 5, "path", 4) == 0) { + if (n == 9 && hasprefix(k, "arg") && hasprefix(k + 5, "path")) { enum bus_match_node_type t; int a, b; @@ -622,7 +622,7 @@ enum bus_match_node_type bus_match_node_type_from_string(const char *k, size_t n return t; } - if (n == 13 && memcmp(k, "arg", 3) == 0 && memcmp(k + 4, "namespace", 9) == 0) { + if (n == 13 && hasprefix(k, "arg") && hasprefix(k + 4, "namespace")) { int j; j = undecchar(k[3]); @@ -632,7 +632,7 @@ enum bus_match_node_type bus_match_node_type_from_string(const char *k, size_t n return BUS_MATCH_ARG_NAMESPACE + j; } - if (n == 14 && memcmp(k, "arg", 3) == 0 && memcmp(k + 5, "namespace", 9) == 0) { + if (n == 14 && hasprefix(k, "arg") && hasprefix(k + 5, "namespace")) { enum bus_match_node_type t; int a, b; diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index 40efad3273..89f67f52c0 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -438,7 +438,7 @@ static int output_export( /* We already printed the boot id, from the data in * the header, hence let's suppress it here */ if (length >= 9 && - memcmp(data, "_BOOT_ID=", 9) == 0) + hasprefix(data, "_BOOT_ID=")) continue; if (!utf8_is_printable(data, length)) { diff --git a/src/shared/macro.h b/src/shared/macro.h index bfe03f2ae0..969329d152 100644 --- a/src/shared/macro.h +++ b/src/shared/macro.h @@ -186,6 +186,8 @@ static inline size_t ALIGN_TO(size_t l, size_t ali) { #define char_array_0(x) x[sizeof(x)-1] = 0; +#define hasprefix(s, prefix) (memcmp(s, prefix, strlen(prefix)) == 0) + #define IOVEC_SET_STRING(i, s) \ do { \ struct iovec *_i = &(i); \ -- cgit v1.2.1 From 968f319679d9069af037240d0c3bcd126181cdac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 12 Jun 2013 00:24:34 -0400 Subject: journal: allow callers to specify OBJECT_PID= When journald encounters a message with OBJECT_PID= set coming from a priviledged process (UID==0), additional fields will be added to the message: OBJECT_UID=, OBJECT_GID=, OBJECT_COMM=, OBJECT_EXE=, OBJECT_CMDLINE=, OBJECT_AUDIT_SESSION=, OBJECT_AUDIT_LOGINUID=, OBJECT_SYSTEMD_CGROUP=, OBJECT_SYSTEMD_SESSION=, OBJECT_SYSTEMD_OWNER_UID=, OBJECT_SYSTEMD_UNIT= or OBJECT_SYSTEMD_USER_UNIT=. This is for other logging daemons, like setroubleshoot, to be able to augment their logs with data about the process. https://bugzilla.redhat.com/show_bug.cgi?id=951627 --- src/journal/journald-kmsg.c | 2 +- src/journal/journald-native.c | 40 ++++++----- src/journal/journald-server.c | 163 +++++++++++++++++++++++++++++++++--------- src/journal/journald-server.h | 3 +- src/journal/journald-stream.c | 2 +- src/journal/journald-syslog.c | 2 +- 6 files changed, 157 insertions(+), 55 deletions(-) diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c index 5fd87b8154..21649d06ce 100644 --- a/src/journal/journald-kmsg.c +++ b/src/journal/journald-kmsg.c @@ -304,7 +304,7 @@ static void dev_kmsg_record(Server *s, char *p, size_t l) { if (message) IOVEC_SET_STRING(iovec[n++], message); - server_dispatch_message(s, iovec, n, ELEMENTSOF(iovec), NULL, NULL, NULL, 0, NULL, priority); + server_dispatch_message(s, iovec, n, ELEMENTSOF(iovec), NULL, NULL, NULL, 0, NULL, priority, 0); finish: for (j = 0; j < z; j++) diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c index ec9afa187d..0f9af378cf 100644 --- a/src/journal/journald-native.c +++ b/src/journal/journald-native.c @@ -71,6 +71,10 @@ static bool valid_user_field(const char *p, size_t l) { return true; } +static bool allow_object_pid(struct ucred *ucred) { + return ucred && ucred->uid == 0; +} + void server_process_native_message( Server *s, const void *buffer, size_t buffer_size, @@ -79,11 +83,12 @@ void server_process_native_message( const char *label, size_t label_len) { struct iovec *iovec = NULL; - unsigned n = 0, m = 0, j, tn = (unsigned) -1; + unsigned n = 0, j, tn = (unsigned) -1; const char *p; - size_t remaining; + size_t remaining, m = 0; int priority = LOG_INFO; char *identifier = NULL, *message = NULL; + pid_t object_pid = 0; assert(s); assert(buffer || buffer_size == 0); @@ -104,7 +109,7 @@ void server_process_native_message( if (e == p) { /* Entry separator */ - server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority); + server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority, object_pid); n = 0; priority = LOG_INFO; @@ -124,19 +129,10 @@ void server_process_native_message( /* A property follows */ /* n received properties, +1 for _TRANSPORT */ - if (n + 1 + N_IOVEC_META_FIELDS >= m) { - struct iovec *c; - unsigned u; - - u = MAX((n + 1 + N_IOVEC_META_FIELDS) * 2U, 4U); - c = realloc(iovec, u * sizeof(struct iovec)); - if (!c) { - log_oom(); - break; - } - - iovec = c; - m = u; + if (!GREEDY_REALLOC(iovec, m, n + 1 + N_IOVEC_META_FIELDS + + !!object_pid * N_IOVEC_OBJECT_FIELDS)) { + log_oom(); + break; } q = memchr(p, '=', e - p); @@ -191,6 +187,16 @@ void server_process_native_message( free(message); message = t; } + } else if (l > strlen("OBJECT_PID=") && + l < strlen("OBJECT_PID=") + DECIMAL_STR_MAX(pid_t) && + hasprefix(p, "OBJECT_PID=") && + allow_object_pid(ucred)) { + char buf[DECIMAL_STR_MAX(pid_t)]; + memcpy(buf, p + strlen("OBJECT_PID="), l - strlen("OBJECT_PID=")); + char_array_0(buf); + + /* ignore error */ + parse_pid(buf, &object_pid); } } @@ -260,7 +266,7 @@ void server_process_native_message( server_forward_console(s, priority, identifier, message, ucred); } - server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority); + server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority, object_pid); finish: for (j = 0; j < n; j++) { diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index de96040242..ae65f02895 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -499,24 +499,33 @@ static void dispatch_message_real( struct ucred *ucred, struct timeval *tv, const char *label, size_t label_len, - const char *unit_id) { + const char *unit_id, + pid_t object_pid) { - char pid[sizeof("_PID=") + DECIMAL_STR_MAX(pid_t)], + char pid[sizeof("_PID=") + DECIMAL_STR_MAX(pid_t)], uid[sizeof("_UID=") + DECIMAL_STR_MAX(uid_t)], gid[sizeof("_GID=") + DECIMAL_STR_MAX(gid_t)], owner_uid[sizeof("_SYSTEMD_OWNER_UID=") + DECIMAL_STR_MAX(uid_t)], source_time[sizeof("_SOURCE_REALTIME_TIMESTAMP=") + DECIMAL_STR_MAX(usec_t)], boot_id[sizeof("_BOOT_ID=") + 32] = "_BOOT_ID=", - machine_id[sizeof("_MACHINE_ID=") + 32] = "_MACHINE_ID="; - char *comm, *exe, *cmdline, *cgroup, *session, *unit, *hostname; + machine_id[sizeof("_MACHINE_ID=") + 32] = "_MACHINE_ID=", + o_uid[sizeof("OBJECT_UID=") + DECIMAL_STR_MAX(uid_t)], + o_gid[sizeof("OBJECT_GID=") + DECIMAL_STR_MAX(gid_t)], + o_owner_uid[sizeof("OBJECT_SYSTEMD_OWNER_UID=") + DECIMAL_STR_MAX(uid_t)]; + uid_t object_uid; + gid_t object_gid; + + char *x; sd_id128_t id; int r; char *t, *c; uid_t realuid = 0, owner = 0, journal_uid; bool owner_valid = false; #ifdef HAVE_AUDIT - char audit_session[sizeof("_AUDIT_SESSION=") + DECIMAL_STR_MAX(uint32_t)], - audit_loginuid[sizeof("_AUDIT_LOGINUID=") + DECIMAL_STR_MAX(uid_t)]; + char audit_session[sizeof("_AUDIT_SESSION=") + DECIMAL_STR_MAX(uint32_t)], + audit_loginuid[sizeof("_AUDIT_LOGINUID=") + DECIMAL_STR_MAX(uid_t)], + o_audit_session[sizeof("OBJECT_AUDIT_SESSION=") + DECIMAL_STR_MAX(uint32_t)], + o_audit_loginuid[sizeof("OBJECT_AUDIT_LOGINUID=") + DECIMAL_STR_MAX(uid_t)]; uint32_t audit; uid_t loginuid; @@ -525,7 +534,7 @@ static void dispatch_message_real( assert(s); assert(iovec); assert(n > 0); - assert(n + N_IOVEC_META_FIELDS <= m); + assert(n + N_IOVEC_META_FIELDS + (object_pid ? N_IOVEC_OBJECT_FIELDS : 0) <= m); if (ucred) { realuid = ucred->uid; @@ -541,23 +550,23 @@ static void dispatch_message_real( r = get_process_comm(ucred->pid, &t); if (r >= 0) { - comm = strappenda("_COMM=", t); + x = strappenda("_COMM=", t); free(t); - IOVEC_SET_STRING(iovec[n++], comm); + IOVEC_SET_STRING(iovec[n++], x); } r = get_process_exe(ucred->pid, &t); if (r >= 0) { - exe = strappenda("_EXE=", t); + x = strappenda("_EXE=", t); free(t); - IOVEC_SET_STRING(iovec[n++], exe); + IOVEC_SET_STRING(iovec[n++], x); } r = get_process_cmdline(ucred->pid, 0, false, &t); if (r >= 0) { - cmdline = strappenda("_CMDLINE=", t); + x = strappenda("_CMDLINE=", t); free(t); - IOVEC_SET_STRING(iovec[n++], cmdline); + IOVEC_SET_STRING(iovec[n++], x); } #ifdef HAVE_AUDIT @@ -576,8 +585,10 @@ static void dispatch_message_real( r = cg_pid_get_path_shifted(ucred->pid, NULL, &c); if (r >= 0) { - cgroup = strappenda("_SYSTEMD_CGROUP=", c); - IOVEC_SET_STRING(iovec[n++], cgroup); + char *session = NULL; + + x = strappenda("_SYSTEMD_CGROUP=", c); + IOVEC_SET_STRING(iovec[n++], x); r = cg_path_get_session(c, &t); if (r >= 0) { @@ -594,43 +605,126 @@ static void dispatch_message_real( } if (cg_path_get_unit(c, &t) >= 0) { - unit = strappenda("_SYSTEMD_UNIT=", t); + x = strappenda("_SYSTEMD_UNIT=", t); free(t); } else if (cg_path_get_user_unit(c, &t) >= 0) { - unit = strappenda("_SYSTEMD_USER_UNIT=", t); + x = strappenda("_SYSTEMD_USER_UNIT=", t); free(t); } else if (unit_id) { if (session) - unit = strappenda("_SYSTEMD_USER_UNIT=", unit_id); + x = strappenda("_SYSTEMD_USER_UNIT=", unit_id); else - unit = strappenda("_SYSTEMD_UNIT=", unit_id); + x = strappenda("_SYSTEMD_UNIT=", unit_id); } else - unit = NULL; + x = NULL; - if (unit) - IOVEC_SET_STRING(iovec[n++], unit); + if (x) + IOVEC_SET_STRING(iovec[n++], x); free(c); } #ifdef HAVE_SELINUX if (label) { - char *selinux_context = alloca(sizeof("_SELINUX_CONTEXT=") + label_len); + x = alloca(sizeof("_SELINUX_CONTEXT=") + label_len); - *((char*) mempcpy(stpcpy(selinux_context, "_SELINUX_CONTEXT="), label, label_len)) = 0; - IOVEC_SET_STRING(iovec[n++], selinux_context); + *((char*) mempcpy(stpcpy(x, "_SELINUX_CONTEXT="), label, label_len)) = 0; + IOVEC_SET_STRING(iovec[n++], x); } else { security_context_t con; if (getpidcon(ucred->pid, &con) >= 0) { - char *selinux_context = strappenda("_SELINUX_CONTEXT=", con); + x = strappenda("_SELINUX_CONTEXT=", con); freecon(con); - IOVEC_SET_STRING(iovec[n++], selinux_context); + IOVEC_SET_STRING(iovec[n++], x); } } #endif } + assert(n <= m); + + if (object_pid) { + r = get_process_uid(object_pid, &object_uid); + if (r >= 0) { + sprintf(o_uid, "OBJECT_UID=%lu", (unsigned long) object_uid); + IOVEC_SET_STRING(iovec[n++], o_uid); + } + + r = get_process_gid(object_pid, &object_gid); + if (r >= 0) { + sprintf(o_gid, "OBJECT_GID=%lu", (unsigned long) object_gid); + IOVEC_SET_STRING(iovec[n++], o_gid); + } + + r = get_process_comm(object_pid, &t); + if (r >= 0) { + x = strappenda("OBJECT_COMM=", t); + free(t); + IOVEC_SET_STRING(iovec[n++], x); + } + + r = get_process_exe(object_pid, &t); + if (r >= 0) { + x = strappenda("OBJECT_EXE=", t); + free(t); + IOVEC_SET_STRING(iovec[n++], x); + } + + r = get_process_cmdline(object_pid, 0, false, &t); + if (r >= 0) { + x = strappenda("OBJECT_CMDLINE=", t); + free(t); + IOVEC_SET_STRING(iovec[n++], x); + } + +#ifdef HAVE_AUDIT + r = audit_session_from_pid(object_pid, &audit); + if (r >= 0) { + sprintf(o_audit_session, "OBJECT_AUDIT_SESSION=%lu", (unsigned long) audit); + IOVEC_SET_STRING(iovec[n++], o_audit_session); + } + + r = audit_loginuid_from_pid(object_pid, &loginuid); + if (r >= 0) { + sprintf(o_audit_loginuid, "OBJECT_AUDIT_LOGINUID=%lu", (unsigned long) loginuid); + IOVEC_SET_STRING(iovec[n++], o_audit_loginuid); + } +#endif + + r = cg_pid_get_path_shifted(object_pid, NULL, &c); + if (r >= 0) { + x = strappenda("OBJECT_SYSTEMD_CGROUP=", c); + IOVEC_SET_STRING(iovec[n++], x); + + r = cg_path_get_session(c, &t); + if (r >= 0) { + x = strappenda("OBJECT_SYSTEMD_SESSION=", t); + free(t); + IOVEC_SET_STRING(iovec[n++], x); + } + + if (cg_path_get_owner_uid(c, &owner) >= 0) { + sprintf(o_owner_uid, "OBJECT_SYSTEMD_OWNER_UID=%lu", (unsigned long) owner); + IOVEC_SET_STRING(iovec[n++], o_owner_uid); + } + + if (cg_path_get_unit(c, &t) >= 0) { + x = strappenda("OBJECT_SYSTEMD_UNIT=", t); + free(t); + } else if (cg_path_get_user_unit(c, &t) >= 0) { + x = strappenda("OBJECT_SYSTEMD_USER_UNIT=", t); + free(t); + } else + x = NULL; + + if (x) + IOVEC_SET_STRING(iovec[n++], x); + + free(c); + } + } + assert(n <= m); if (tv) { sprintf(source_time, "_SOURCE_REALTIME_TIMESTAMP=%llu", (unsigned long long) timeval_load(tv)); @@ -642,21 +736,21 @@ static void dispatch_message_real( * anyway. However, we need this indexed, too. */ r = sd_id128_get_boot(&id); if (r >= 0) { - sd_id128_to_string(id, boot_id + sizeof("_BOOT_ID=") - 1); + sd_id128_to_string(id, boot_id + strlen("_BOOT_ID=")); IOVEC_SET_STRING(iovec[n++], boot_id); } r = sd_id128_get_machine(&id); if (r >= 0) { - sd_id128_to_string(id, machine_id + sizeof("_MACHINE_ID=") - 1); + sd_id128_to_string(id, machine_id + strlen("_MACHINE_ID=")); IOVEC_SET_STRING(iovec[n++], machine_id); } t = gethostname_malloc(); if (t) { - hostname = strappenda("_HOSTNAME=", t); + x = strappenda("_HOSTNAME=", t); free(t); - IOVEC_SET_STRING(iovec[n++], hostname); + IOVEC_SET_STRING(iovec[n++], x); } assert(n <= m); @@ -709,7 +803,7 @@ void server_driver_message(Server *s, sd_id128_t message_id, const char *format, ucred.uid = getuid(); ucred.gid = getgid(); - dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL, NULL, 0, NULL); + dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL, NULL, 0, NULL, 0); } void server_dispatch_message( @@ -719,7 +813,8 @@ void server_dispatch_message( struct timeval *tv, const char *label, size_t label_len, const char *unit_id, - int priority) { + int priority, + pid_t object_pid) { int rl, r; _cleanup_free_ char *path = NULL; @@ -769,7 +864,7 @@ void server_dispatch_message( "Suppressed %u messages from %s", rl - 1, path); finish: - dispatch_message_real(s, iovec, n, m, ucred, tv, label, label_len, unit_id); + dispatch_message_real(s, iovec, n, m, ucred, tv, label, label_len, unit_id, object_pid); } diff --git a/src/journal/journald-server.h b/src/journal/journald-server.h index 129f7e8ab4..41f32ba68d 100644 --- a/src/journal/journald-server.h +++ b/src/journal/journald-server.h @@ -128,8 +128,9 @@ typedef struct Server { #define N_IOVEC_META_FIELDS 17 #define N_IOVEC_KERNEL_FIELDS 64 #define N_IOVEC_UDEV_FIELDS 32 +#define N_IOVEC_OBJECT_FIELDS 11 -void server_dispatch_message(Server *s, struct iovec *iovec, unsigned n, unsigned m, struct ucred *ucred, struct timeval *tv, const char *label, size_t label_len, const char *unit_id, int priority); +void server_dispatch_message(Server *s, struct iovec *iovec, unsigned n, unsigned m, struct ucred *ucred, struct timeval *tv, const char *label, size_t label_len, const char *unit_id, int priority, pid_t object_pid); void server_driver_message(Server *s, sd_id128_t message_id, const char *format, ...) _printf_attr_(3,4); /* gperf lookup function */ diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c index 3ce1c9ac47..e98fe94b46 100644 --- a/src/journal/journald-stream.c +++ b/src/journal/journald-stream.c @@ -127,7 +127,7 @@ static int stdout_stream_log(StdoutStream *s, const char *p) { } #endif - server_dispatch_message(s->server, iovec, n, ELEMENTSOF(iovec), &s->ucred, NULL, label, label_len, s->unit_id, priority); + server_dispatch_message(s->server, iovec, n, ELEMENTSOF(iovec), &s->ucred, NULL, label, label_len, s->unit_id, priority, 0); free(message); free(syslog_priority); diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c index 4aeb9a35f0..7cbb34608b 100644 --- a/src/journal/journald-syslog.c +++ b/src/journal/journald-syslog.c @@ -400,7 +400,7 @@ void server_process_syslog_message( if (message) IOVEC_SET_STRING(iovec[n++], message); - server_dispatch_message(s, iovec, n, ELEMENTSOF(iovec), ucred, tv, label, label_len, NULL, priority); + server_dispatch_message(s, iovec, n, ELEMENTSOF(iovec), ucred, tv, label, label_len, NULL, priority, 0); free(message); free(identifier); -- cgit v1.2.1 From fdcd37df3b97abc381c7b7a29b81cc013c7a3230 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 20 Jun 2013 21:48:26 -0400 Subject: Make sure we only show authentic coredump messages Before we only checked the MESSAGE_ID and COREDUMP_UNIT. Those are both user-controlled fields. For COREDUMP_USER_UNIT, relax the rules a bit, and also allow messages from _UID=0. --- src/shared/logs-show.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index 89f67f52c0..7240f33590 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -927,8 +927,8 @@ int add_matches_for_unit(sd_journal *j, const char *unit) { /* Look for coredumps of the service */ (r = sd_journal_add_disjunction(j)) || - (r = sd_journal_add_match(j, - "MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1", 0)) || + (r = sd_journal_add_match(j, "MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1", 0)) || + (r = sd_journal_add_match(j, "_UID=0", 0)) || (r = sd_journal_add_match(j, m2, 0)) || /* Look for messages from PID 1 about this service */ @@ -965,7 +965,8 @@ int add_matches_for_user_unit(sd_journal *j, const char *unit, uid_t uid) { /* Look for coredumps of the service */ (r = sd_journal_add_disjunction(j)) || (r = sd_journal_add_match(j, m3, 0)) || - (r = sd_journal_add_match(j, m4, 0)) + (r = sd_journal_add_match(j, m4, 0)) || + (r = sd_journal_add_match(j, "_UID=0", 0)) ); return r; } -- cgit v1.2.1 From 2d0b2e8765464bc9bf4d529e25bc11d862818077 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 20 Jun 2013 22:25:49 -0400 Subject: journalctl,systemctl: show messages tagged with OBJECT_SYSTEMD_[USER_]_UNIT Replace mallocs with alloca while at it. --- src/shared/logs-show.c | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index 7240f33590..91b2bec159 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -911,15 +911,15 @@ finish: int add_matches_for_unit(sd_journal *j, const char *unit) { int r; - _cleanup_free_ char *m1 = NULL, *m2 = NULL, *m3 = NULL; + char *m1, *m2, *m3, *m4; assert(j); assert(unit); - if (asprintf(&m1, "_SYSTEMD_UNIT=%s", unit) < 0 || - asprintf(&m2, "COREDUMP_UNIT=%s", unit) < 0 || - asprintf(&m3, "UNIT=%s", unit) < 0) - return -ENOMEM; + m1 = strappenda("_SYSTEMD_UNIT=", unit); + m2 = strappenda("COREDUMP_UNIT=", unit); + m3 = strappenda("UNIT=", unit); + m4 = strappenda("OBJECT_SYSTEMD_UNIT=", unit); (void)( /* Look for messages from the service itself */ @@ -934,38 +934,51 @@ int add_matches_for_unit(sd_journal *j, const char *unit) { /* Look for messages from PID 1 about this service */ (r = sd_journal_add_disjunction(j)) || (r = sd_journal_add_match(j, "_PID=1", 0)) || - (r = sd_journal_add_match(j, m3, 0)) + (r = sd_journal_add_match(j, m3, 0)) || + + /* Look for messages from authorized daemons about this service */ + (r = sd_journal_add_disjunction(j)) || + (r = sd_journal_add_match(j, "_UID=0", 0)) || + (r = sd_journal_add_match(j, m4, 0)) ); + return r; } int add_matches_for_user_unit(sd_journal *j, const char *unit, uid_t uid) { int r; - _cleanup_free_ char *m1 = NULL, *m2 = NULL, *m3 = NULL, *m4 = NULL; + char *m1, *m2, *m3, *m4; + char muid[sizeof("_UID=") + DECIMAL_STR_MAX(uid_t)]; assert(j); assert(unit); - if (asprintf(&m1, "_SYSTEMD_USER_UNIT=%s", unit) < 0 || - asprintf(&m2, "USER_UNIT=%s", unit) < 0 || - asprintf(&m3, "COREDUMP_USER_UNIT=%s", unit) < 0 || - asprintf(&m4, "_UID=%d", uid) < 0) - return -ENOMEM; + m1 = strappenda("_SYSTEMD_USER_UNIT=", unit); + m2 = strappenda("USER_UNIT=", unit); + m3 = strappenda("COREDUMP_USER_UNIT=", unit); + m4 = strappenda("OBJECT_SYSTEMD_USER_UNIT=", unit); + sprintf(muid, "_UID=%lu", (unsigned long) uid); (void) ( /* Look for messages from the user service itself */ (r = sd_journal_add_match(j, m1, 0)) || - (r = sd_journal_add_match(j, m4, 0)) || + (r = sd_journal_add_match(j, muid, 0)) || /* Look for messages from systemd about this service */ (r = sd_journal_add_disjunction(j)) || (r = sd_journal_add_match(j, m2, 0)) || - (r = sd_journal_add_match(j, m4, 0)) || + (r = sd_journal_add_match(j, muid, 0)) || /* Look for coredumps of the service */ (r = sd_journal_add_disjunction(j)) || (r = sd_journal_add_match(j, m3, 0)) || + (r = sd_journal_add_match(j, muid, 0)) || + (r = sd_journal_add_match(j, "_UID=0", 0)) || + + /* Look for messages from authorized daemons about this service */ + (r = sd_journal_add_disjunction(j)) || (r = sd_journal_add_match(j, m4, 0)) || + (r = sd_journal_add_match(j, muid, 0)) || (r = sd_journal_add_match(j, "_UID=0", 0)) ); return r; -- cgit v1.2.1 From f6c9f322e83a45f8f4da0194dd987d4565155bb0 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Fri, 21 Jun 2013 06:34:38 +0200 Subject: keymap: Apply to all Latitude and Precision models https://launchpad.net/bugs/1193147 --- src/udev/keymap/95-keyboard-force-release.rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/udev/keymap/95-keyboard-force-release.rules b/src/udev/keymap/95-keyboard-force-release.rules index 77288c792a..a13403c73f 100644 --- a/src/udev/keymap/95-keyboard-force-release.rules +++ b/src/udev/keymap/95-keyboard-force-release.rules @@ -22,7 +22,7 @@ ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", RUN+="keyboard-force-release.s ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*90X3A*|*900X3*|*900X4*|*900XC3*", RUN+="keyboard-force-release.sh $devpath samsung-series-9" ENV{DMI_VENDOR}=="Dell Inc.", ATTR{[dmi/id]product_name}=="Studio 1557|Studio 1558", RUN+="keyboard-force-release.sh $devpath common-volume-keys" -ENV{DMI_VENDOR}=="Dell Inc.", ATTR{[dmi/id]product_name}=="Latitude E*|Latitude *U|Precision M*", RUN+="keyboard-force-release.sh $devpath dell-touchpad" +ENV{DMI_VENDOR}=="Dell Inc.", ATTR{[dmi/id]product_name}=="*Latitude*|*Precision*", RUN+="keyboard-force-release.sh $devpath dell-touchpad" ENV{DMI_VENDOR}=="Dell Inc.", ATTR{[dmi/id]product_name}=="XPS*", RUN+="keyboard-force-release.sh $devpath dell-xps" ENV{DMI_VENDOR}=="FUJITSU SIEMENS", ATTR{[dmi/id]product_name}=="AMILO*", RUN+="keyboard-force-release.sh $devpath common-volume-keys" -- cgit v1.2.1 From 7f1ad696a273703789b624fe0b209fb63e953016 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 21 Jun 2013 15:56:45 +0200 Subject: journald: bump the journal per-unit ratelimit defaults Too many people kept hitting them, so let's increase the limits a bit. https://bugzilla.redhat.com/show_bug.cgi?id=965803 --- src/journal/journald-server.c | 4 ++-- src/journal/journald.conf | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index ae65f02895..c7d047af77 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -65,8 +65,8 @@ #define USER_JOURNALS_MAX 1024 #define DEFAULT_SYNC_INTERVAL_USEC (5*USEC_PER_MINUTE) -#define DEFAULT_RATE_LIMIT_INTERVAL (10*USEC_PER_SEC) -#define DEFAULT_RATE_LIMIT_BURST 200 +#define DEFAULT_RATE_LIMIT_INTERVAL (30*USEC_PER_SEC) +#define DEFAULT_RATE_LIMIT_BURST 1000 #define RECHECK_AVAILABLE_SPACE_USEC (30*USEC_PER_SEC) diff --git a/src/journal/journald.conf b/src/journal/journald.conf index 5410477201..54f6833a17 100644 --- a/src/journal/journald.conf +++ b/src/journal/journald.conf @@ -13,8 +13,8 @@ #Seal=yes #SplitMode=login #SyncIntervalSec=5m -#RateLimitInterval=10s -#RateLimitBurst=200 +#RateLimitInterval=30s +#RateLimitBurst=1000 #SystemMaxUse= #SystemKeepFree= #SystemMaxFileSize= -- cgit v1.2.1 From 96ca81944e40d9bc75d8599e216ee3babe0f5f81 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 21 Jun 2013 15:57:42 +0200 Subject: tmpfiles: fix error check --- src/tmpfiles/tmpfiles.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index f4885ec942..555347ac36 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -783,7 +783,7 @@ static int create_item(Item *i) { r = glob_item(i, item_set_perms); if (r < 0) - return 0; + return r; break; case RECURSIVE_RELABEL_PATH: -- cgit v1.2.1 From f123dba8b13cc629ff53056aabe253426cbb6a5e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 21 Jun 2013 15:57:47 +0200 Subject: update TODO --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index e11e85c7f9..caba4e39eb 100644 --- a/TODO +++ b/TODO @@ -28,6 +28,8 @@ Fedora 19: Features: +* journald: make sure ratelimit is actually really per-service with the new cgroup changes + * when creating a session or machine, automatically move the process into the root cgroup for all other hierarchies * maybe reintroduce nspawn -C? -- cgit v1.2.1 From fb69ed55e5f8e82145440ba15075e8db807bf7fa Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Sat, 22 Jun 2013 00:55:18 +0200 Subject: man: Fix small typo --- man/systemd-nspawn.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml index 1bc61e83a7..ca21f2e6db 100644 --- a/man/systemd-nspawn.xml +++ b/man/systemd-nspawn.xml @@ -136,7 +136,7 @@ As a safety check systemd-nspawn will verify the - existance of /etc/os-release in + existence of /etc/os-release in the container tree before starting the container (see os-release5). It might be necessary to add this file to the container -- cgit v1.2.1 From 92fba83e3a23ce7778a1bde67d277fdc97ab39f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 22 Jun 2013 20:04:08 -0400 Subject: journal-verify: allow unlinked data entries Sometimes an entry is not successfully written, and we end up with data items which are "unlinked", not connected to, and not used by any entry. This will usually happen when we write to write a core dump, and the initial small data fields are written successfully, but the huge COREDUMP= field is not written. This situation is hard to avoid, but the results are mostly harmless. Thus only warn about unused data items. Also, be more verbose about why journal files failed verification. This should help diagnose journal failure modes without resorting to a hexadecimal editor. https://bugs.freedesktop.org/show_bug.cgi?id=65235 (esp. see system.journal attached to the bug report). --- man/sd_journal_print.xml | 2 +- man/udev.xml | 2 +- src/journal/journal-verify.c | 217 +++++++++++++++++++++++++++++++++---------- 3 files changed, 169 insertions(+), 52 deletions(-) diff --git a/man/sd_journal_print.xml b/man/sd_journal_print.xml index 7742268f5d..cdaea8c2ef 100644 --- a/man/sd_journal_print.xml +++ b/man/sd_journal_print.xml @@ -138,7 +138,7 @@ of any size and format. It is highly recommended to submit text strings formatted in the UTF-8 character encoding only, and submit binary fields only when - formatting in UTf-8 strings is not sensible. A number + formatting in UTF-8 strings is not sensible. A number of well known fields are defined, see systemd.journal-fields7 for details, but additional application defined fields diff --git a/man/udev.xml b/man/udev.xml index e253a0677a..964aeda802 100644 --- a/man/udev.xml +++ b/man/udev.xml @@ -317,7 +317,7 @@ The name of a symlink targeting the node. Every matching rule adds this value to the list of symlinks to be created. The set of characters to name a symlink is limited. Allowed - characters are [0-9A-Za-z#+-.:=@_/], valid utf8 character sequences, + characters are [0-9A-Za-z#+-.:=@_/], valid UTF-8 character sequences, and "\x00" hex encoding. All other characters are replaced by a '_' character. Multiple symlinks may be specified by separating the names by the diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c index 01c89bc8a4..781b1ee1de 100644 --- a/src/journal/journal-verify.c +++ b/src/journal/journal-verify.c @@ -34,10 +34,15 @@ #include "compress.h" #include "fsprg.h" -static int journal_file_object_verify(JournalFile *f, Object *o) { +/* Use six characters to cover the offsets common in smallish journal + * files without adding to many zeros. */ +#define OFSfmt "%06"PRIx64 + +static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o) { uint64_t i; assert(f); + assert(offset); assert(o); /* This does various superficial tests about the length an @@ -53,12 +58,21 @@ static int journal_file_object_verify(JournalFile *f, Object *o) { case OBJECT_DATA: { uint64_t h1, h2; - if (le64toh(o->data.entry_offset) <= 0 || - le64toh(o->data.n_entries) <= 0) + if (le64toh(o->data.entry_offset) == 0) + log_warning(OFSfmt": unused data (entry_offset==0)", offset); + + if ((le64toh(o->data.entry_offset) == 0) ^ (le64toh(o->data.n_entries) == 0)) { + log_error(OFSfmt": bad n_entries: %"PRIu64, offset, o->data.n_entries); return -EBADMSG; + } - if (le64toh(o->object.size) - offsetof(DataObject, payload) <= 0) + if (le64toh(o->object.size) - offsetof(DataObject, payload) <= 0) { + log_error(OFSfmt": bad object size (<= %"PRIu64"): %"PRIu64, + offset, + offsetof(DataObject, payload), + le64toh(o->object.size)); return -EBADMSG; + } h1 = le64toh(o->data.hash); @@ -69,104 +83,197 @@ static int journal_file_object_verify(JournalFile *f, Object *o) { if (!uncompress_blob(o->data.payload, le64toh(o->object.size) - offsetof(Object, data.payload), - &b, &alloc, &b_size, 0)) + &b, &alloc, &b_size, 0)) { + log_error(OFSfmt": uncompression failed", offset); return -EBADMSG; + } h2 = hash64(b, b_size); free(b); #else + log_error("Compression is not supported"); return -EPROTONOSUPPORT; #endif } else h2 = hash64(o->data.payload, le64toh(o->object.size) - offsetof(Object, data.payload)); - if (h1 != h2) + if (h1 != h2) { + log_error(OFSfmt": invalid hash (%08"PRIx64" vs. %08"PRIx64, offset, h1, h2); return -EBADMSG; + } if (!VALID64(o->data.next_hash_offset) || !VALID64(o->data.next_field_offset) || !VALID64(o->data.entry_offset) || - !VALID64(o->data.entry_array_offset)) + !VALID64(o->data.entry_array_offset)) { + log_error(OFSfmt": invalid offset (next_hash_offset="OFSfmt", next_field_offset="OFSfmt", entry_offset="OFSfmt", entry_array_offset="OFSfmt, + offset, + o->data.next_hash_offset, + o->data.next_field_offset, + o->data.entry_offset, + o->data.entry_array_offset); return -EBADMSG; + } break; } case OBJECT_FIELD: - if (le64toh(o->object.size) - offsetof(FieldObject, payload) <= 0) + if (le64toh(o->object.size) - offsetof(FieldObject, payload) <= 0) { + log_error(OFSfmt": bad field size (<= %"PRIu64"): %"PRIu64, + offset, + offsetof(FieldObject, payload), + le64toh(o->object.size)); return -EBADMSG; + } if (!VALID64(o->field.next_hash_offset) || - !VALID64(o->field.head_data_offset)) + !VALID64(o->field.head_data_offset)) { + log_error(OFSfmt": invalid offset (next_hash_offset="OFSfmt", head_data_offset="OFSfmt, + offset, + o->field.next_hash_offset, + o->field.head_data_offset); return -EBADMSG; + } break; case OBJECT_ENTRY: - if ((le64toh(o->object.size) - offsetof(EntryObject, items)) % sizeof(EntryItem) != 0) + if ((le64toh(o->object.size) - offsetof(EntryObject, items)) % sizeof(EntryItem) != 0) { + log_error(OFSfmt": bad entry size (<= %"PRIu64"): %"PRIu64, + offset, + offsetof(EntryObject, items), + le64toh(o->object.size)); return -EBADMSG; + } - if ((le64toh(o->object.size) - offsetof(EntryObject, items)) / sizeof(EntryItem) <= 0) + if ((le64toh(o->object.size) - offsetof(EntryObject, items)) / sizeof(EntryItem) <= 0) { + log_error(OFSfmt": invalid number items in entry: %"PRIu64, + offset, + (le64toh(o->object.size) - offsetof(EntryObject, items)) / sizeof(EntryItem)); return -EBADMSG; + } + + if (le64toh(o->entry.seqnum) <= 0) { + log_error(OFSfmt": invalid entry seqnum: %"PRIx64, + offset, + le64toh(o->entry.seqnum)); + return -EBADMSG; + } - if (le64toh(o->entry.seqnum) <= 0 || - !VALID_REALTIME(le64toh(o->entry.realtime)) || - !VALID_MONOTONIC(le64toh(o->entry.monotonic))) + if (!VALID_REALTIME(le64toh(o->entry.realtime))) { + log_error(OFSfmt": invalid entry realtime timestamp: %"PRIu64, + offset, + le64toh(o->entry.realtime)); return -EBADMSG; + } + + if (!VALID_MONOTONIC(le64toh(o->entry.monotonic))) { + log_error(OFSfmt": invalid entry monotonic timestamp: %"PRIu64, + offset, + le64toh(o->entry.monotonic)); + return -EBADMSG; + } for (i = 0; i < journal_file_entry_n_items(o); i++) { if (o->entry.items[i].object_offset == 0 || - !VALID64(o->entry.items[i].object_offset)) + !VALID64(o->entry.items[i].object_offset)) { + log_error(OFSfmt": invalid entry item (%"PRIu64"/%"PRIu64" offset: "OFSfmt, + offset, + i, journal_file_entry_n_items(o), + o->entry.items[i].object_offset); return -EBADMSG; + } } break; case OBJECT_DATA_HASH_TABLE: case OBJECT_FIELD_HASH_TABLE: - if ((le64toh(o->object.size) - offsetof(HashTableObject, items)) % sizeof(HashItem) != 0) - return -EBADMSG; - - if ((le64toh(o->object.size) - offsetof(HashTableObject, items)) / sizeof(HashItem) <= 0) + if ((le64toh(o->object.size) - offsetof(HashTableObject, items)) % sizeof(HashItem) != 0 || + (le64toh(o->object.size) - offsetof(HashTableObject, items)) / sizeof(HashItem) <= 0) { + log_error(OFSfmt": invalid %s hash table size: %"PRIu64, + offset, + o->object.type == OBJECT_DATA_HASH_TABLE ? "data" : "field", + le64toh(o->object.size)); return -EBADMSG; + } for (i = 0; i < journal_file_hash_table_n_items(o); i++) { if (o->hash_table.items[i].head_hash_offset != 0 && - !VALID64(le64toh(o->hash_table.items[i].head_hash_offset))) + !VALID64(le64toh(o->hash_table.items[i].head_hash_offset))) { + log_error(OFSfmt": invalid %s hash table item (%"PRIu64"/%"PRIu64") head_hash_offset: "OFSfmt, + offset, + o->object.type == OBJECT_DATA_HASH_TABLE ? "data" : "field", + i, journal_file_hash_table_n_items(o), + le64toh(o->hash_table.items[i].head_hash_offset)); return -EBADMSG; + } if (o->hash_table.items[i].tail_hash_offset != 0 && - !VALID64(le64toh(o->hash_table.items[i].tail_hash_offset))) + !VALID64(le64toh(o->hash_table.items[i].tail_hash_offset))) { + log_error(OFSfmt": invalid %s hash table item (%"PRIu64"/%"PRIu64") tail_hash_offset: "OFSfmt, + offset, + o->object.type == OBJECT_DATA_HASH_TABLE ? "data" : "field", + i, journal_file_hash_table_n_items(o), + le64toh(o->hash_table.items[i].tail_hash_offset)); return -EBADMSG; + } if ((o->hash_table.items[i].head_hash_offset != 0) != - (o->hash_table.items[i].tail_hash_offset != 0)) + (o->hash_table.items[i].tail_hash_offset != 0)) { + log_error(OFSfmt": invalid %s hash table item (%"PRIu64"/%"PRIu64"): head_hash_offset="OFSfmt" tail_hash_offset="OFSfmt, + offset, + o->object.type == OBJECT_DATA_HASH_TABLE ? "data" : "field", + i, journal_file_hash_table_n_items(o), + le64toh(o->hash_table.items[i].head_hash_offset), + le64toh(o->hash_table.items[i].tail_hash_offset)); return -EBADMSG; + } } break; case OBJECT_ENTRY_ARRAY: - if ((le64toh(o->object.size) - offsetof(EntryArrayObject, items)) % sizeof(le64_t) != 0) - return -EBADMSG; - - if ((le64toh(o->object.size) - offsetof(EntryArrayObject, items)) / sizeof(le64_t) <= 0) + if ((le64toh(o->object.size) - offsetof(EntryArrayObject, items)) % sizeof(le64_t) != 0 || + (le64toh(o->object.size) - offsetof(EntryArrayObject, items)) / sizeof(le64_t) <= 0) { + log_error(OFSfmt": invalid object entry array size: %"PRIu64, + offset, + le64toh(o->object.size)); return -EBADMSG; + } - if (!VALID64(o->entry_array.next_entry_array_offset)) + if (!VALID64(o->entry_array.next_entry_array_offset)) { + log_error(OFSfmt": invalid object entry array next_entry_array_offset: "OFSfmt, + offset, + o->entry_array.next_entry_array_offset); return -EBADMSG; + } for (i = 0; i < journal_file_entry_array_n_items(o); i++) if (o->entry_array.items[i] != 0 && - !VALID64(o->entry_array.items[i])) + !VALID64(o->entry_array.items[i])) { + log_error(OFSfmt": invalid object entry array item (%"PRIu64"/%"PRIu64"): "OFSfmt, + offset, + i, journal_file_entry_array_n_items(o), + o->entry_array.items[i]); return -EBADMSG; + } break; case OBJECT_TAG: - if (le64toh(o->object.size) != sizeof(TagObject)) + if (le64toh(o->object.size) != sizeof(TagObject)) { + log_error(OFSfmt": invalid object tag size: %"PRIu64, + offset, + le64toh(o->object.size)); return -EBADMSG; + } - if (!VALID_EPOCH(o->tag.epoch)) + if (!VALID_EPOCH(o->tag.epoch)) { + log_error(OFSfmt": invalid object tag epoch: %"PRIu64, + offset, + o->tag.epoch); return -EBADMSG; + } break; } @@ -375,8 +482,18 @@ static int verify_data( n = le64toh(o->data.n_entries); a = le64toh(o->data.entry_array_offset); - /* We already checked this earlier */ - assert(n > 0); + /* Entry array means at least two objects */ + if (a && n < 2) { + log_error("Entry array present (entry_array_offset=%"PRIu64", but n_entries=%"PRIu64, + a, n); + return -EBADMSG; + } + + if (n == 0) + return 0; + + /* We already checked that earlier */ + assert(o->data.entry_offset); last = q = le64toh(o->data.entry_offset); r = entry_points_to_data(f, entry_fd, n_entries, q, p); @@ -747,7 +864,7 @@ int journal_file_verify( r = journal_file_move_to_object(f, -1, p, &o); if (r < 0) { - log_error("Invalid object at %"PRIu64, p); + log_error("Invalid object at "OFSfmt, p); goto fail; } @@ -762,14 +879,14 @@ int journal_file_verify( n_objects ++; - r = journal_file_object_verify(f, o); + r = journal_file_object_verify(f, p, o); if (r < 0) { - log_error("Invalid object contents at %"PRIu64, p); + log_error("Invalid object contents at "OFSfmt": %s", p, strerror(-r)); goto fail; } if ((o->object.flags & OBJECT_COMPRESSED) && !JOURNAL_HEADER_COMPRESSED(f->header)) { - log_error("Compressed object in file without compression at %"PRIu64, p); + log_error("Compressed object in file without compression at "OFSfmt, p); r = -EBADMSG; goto fail; } @@ -790,7 +907,7 @@ int journal_file_verify( case OBJECT_ENTRY: if (JOURNAL_HEADER_SEALED(f->header) && n_tags <= 0) { - log_error("First entry before first tag at %"PRIu64, p); + log_error("First entry before first tag at "OFSfmt, p); r = -EBADMSG; goto fail; } @@ -800,21 +917,21 @@ int journal_file_verify( goto fail; if (le64toh(o->entry.realtime) < last_tag_realtime) { - log_error("Older entry after newer tag at %"PRIu64, p); + log_error("Older entry after newer tag at "OFSfmt, p); r = -EBADMSG; goto fail; } if (!entry_seqnum_set && le64toh(o->entry.seqnum) != le64toh(f->header->head_entry_seqnum)) { - log_error("Head entry sequence number incorrect at %"PRIu64, p); + log_error("Head entry sequence number incorrect at "OFSfmt, p); r = -EBADMSG; goto fail; } if (entry_seqnum_set && entry_seqnum >= le64toh(o->entry.seqnum)) { - log_error("Entry sequence number out of synchronization at %"PRIu64, p); + log_error("Entry sequence number out of synchronization at "OFSfmt, p); r = -EBADMSG; goto fail; } @@ -825,7 +942,7 @@ int journal_file_verify( if (entry_monotonic_set && sd_id128_equal(entry_boot_id, o->entry.boot_id) && entry_monotonic > le64toh(o->entry.monotonic)) { - log_error("Entry timestamp out of synchronization at %"PRIu64, p); + log_error("Entry timestamp out of synchronization at "OFSfmt, p); r = -EBADMSG; goto fail; } @@ -849,7 +966,7 @@ int journal_file_verify( case OBJECT_DATA_HASH_TABLE: if (n_data_hash_tables > 1) { - log_error("More than one data hash table at %"PRIu64, p); + log_error("More than one data hash table at "OFSfmt, p); r = -EBADMSG; goto fail; } @@ -866,7 +983,7 @@ int journal_file_verify( case OBJECT_FIELD_HASH_TABLE: if (n_field_hash_tables > 1) { - log_error("More than one field hash table at %"PRIu64, p); + log_error("More than one field hash table at "OFSfmt, p); r = -EBADMSG; goto fail; } @@ -888,7 +1005,7 @@ int journal_file_verify( if (p == le64toh(f->header->entry_array_offset)) { if (found_main_entry_array) { - log_error("More than one main entry array at %"PRIu64, p); + log_error("More than one main entry array at "OFSfmt, p); r = -EBADMSG; goto fail; } @@ -901,19 +1018,19 @@ int journal_file_verify( case OBJECT_TAG: if (!JOURNAL_HEADER_SEALED(f->header)) { - log_error("Tag object in file without sealing at %"PRIu64, p); + log_error("Tag object in file without sealing at "OFSfmt, p); r = -EBADMSG; goto fail; } if (le64toh(o->tag.seqnum) != n_tags + 1) { - log_error("Tag sequence number out of synchronization at %"PRIu64, p); + log_error("Tag sequence number out of synchronization at "OFSfmt, p); r = -EBADMSG; goto fail; } if (le64toh(o->tag.epoch) < last_epoch) { - log_error("Epoch sequence out of synchronization at %"PRIu64, p); + log_error("Epoch sequence out of synchronization at "OFSfmt, p); r = -EBADMSG; goto fail; } @@ -926,7 +1043,7 @@ int journal_file_verify( rt = f->fss_start_usec + o->tag.epoch * f->fss_interval_usec; if (entry_realtime_set && entry_realtime >= rt + f->fss_interval_usec) { - log_error("Tag/entry realtime timestamp out of synchronization at %"PRIu64, p); + log_error("Tag/entry realtime timestamp out of synchronization at "OFSfmt, p); r = -EBADMSG; goto fail; } @@ -969,7 +1086,7 @@ int journal_file_verify( goto fail; if (memcmp(o->tag.tag, gcry_md_read(f->hmac, 0), TAG_LENGTH) != 0) { - log_error("Tag failed verification at %"PRIu64, p); + log_error("Tag failed verification at "OFSfmt, p); r = -EBADMSG; goto fail; } @@ -1132,7 +1249,7 @@ fail: if (show_progress) flush_progress(); - log_error("File corruption detected at %s:%"PRIu64" (of %llu bytes, %"PRIu64"%%).", + log_error("File corruption detected at %s:"OFSfmt" (of %llu bytes, %"PRIu64"%%).", f->path, p, (unsigned long long) f->last_stat.st_size, -- cgit v1.2.1 From 9c3fd04e7d8c469d8902b43607de5134d9528618 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Sat, 22 Jun 2013 15:34:01 +0200 Subject: libudev: Use correct type for sizeof --- src/udev/udev-rules.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index 7a4fb70258..fe65e2dd85 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -1614,7 +1614,7 @@ struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names) } strv_uniq(rules->dirs); - rules->dirs_ts_usec = calloc(strv_length(rules->dirs), sizeof(long long)); + rules->dirs_ts_usec = calloc(strv_length(rules->dirs), sizeof(usec_t)); if(!rules->dirs_ts_usec) return udev_rules_unref(rules); udev_rules_check_timestamp(rules); -- cgit v1.2.1 From 30cb029b8bf6578ed1595d87abdedc6923fd4608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 24 Jun 2013 07:59:41 -0400 Subject: journal/vacuum: cleanup --- src/journal/journal-vacuum.c | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/src/journal/journal-vacuum.c b/src/journal/journal-vacuum.c index 4a3a5a9e63..1ddb043e2c 100644 --- a/src/journal/journal-vacuum.c +++ b/src/journal/journal-vacuum.c @@ -135,10 +135,11 @@ int journal_directory_vacuum( usec_t max_retention_usec, usec_t *oldest_usec) { - DIR *d; + _cleanup_closedir_ DIR *d = NULL; int r = 0; struct vacuum_info *list = NULL; - unsigned n_list = 0, n_allocated = 0, i; + unsigned n_list = 0, i; + size_t n_allocated = 0; uint64_t sum = 0; usec_t retention_limit = 0; @@ -248,19 +249,7 @@ int journal_directory_vacuum( patch_realtime(directory, de->d_name, &st, &realtime); - if (n_list >= n_allocated) { - struct vacuum_info *j; - - n_allocated = MAX(n_allocated * 2U, 8U); - j = realloc(list, n_allocated * sizeof(struct vacuum_info)); - if (!j) { - free(p); - r = -ENOMEM; - goto finish; - } - - list = j; - } + GREEDY_REALLOC(list, n_allocated, n_list + 1); list[n_list].filename = p; list[n_list].usage = 512UL * (uint64_t) st.st_blocks; @@ -308,11 +297,7 @@ int journal_directory_vacuum( finish: for (i = 0; i < n_list; i++) free(list[i].filename); - free(list); - if (d) - closedir(d); - return r; } -- cgit v1.2.1 From 670b110c3b59dfa335ac43065b2038400d1d04a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 24 Jun 2013 21:02:16 -0400 Subject: journald: fix space limits reporting Reporting of the free space was bogus, since the remaining space was compared with the maximum allowed, instead of the current use being compared with the maximum allowed. Simplify and fix by reporting limits directly at the point where they are calculated. Also, assign a UUID to the message. --- man/journald.conf.xml | 22 ++++++++---- src/journal/journald-server.c | 84 ++++++++++++++++++------------------------- src/systemd/sd-messages.h | 1 + 3 files changed, 51 insertions(+), 56 deletions(-) diff --git a/man/journald.conf.xml b/man/journald.conf.xml index 26f47f8975..6e43914f23 100644 --- a/man/journald.conf.xml +++ b/man/journald.conf.xml @@ -237,7 +237,17 @@ while the former apply if persistent logging is enabled and the system is fully booted - up. SystemMaxUse= + up. journalctl and + systemd-journald + ignore all files with names not ending + with .journal or + .journal~, so only + such files, located in the appropriate + directories, are taken into account + when calculating current disk usage. + + + SystemMaxUse= and RuntimeMaxUse= control how much disk space the journal may use up at @@ -271,11 +281,11 @@ values in bytes or use K, M, G, T, P, E as units for the specified sizes (equal to 1024, 1024²,... bytes). - Note that size limits are - enforced synchronously to journal - files as they are extended, and need - no explicit rotation step triggered by - time. + Note that size limits are enforced + synchronously when journal files + are extended, and no explicit + rotation step triggered by + time is needed. diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index c7d047af77..44ba916f10 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -89,21 +89,22 @@ static const char* const split_mode_table[] = { DEFINE_STRING_TABLE_LOOKUP(split_mode, SplitMode); DEFINE_CONFIG_PARSE_ENUM(config_parse_split_mode, split_mode, SplitMode, "Failed to parse split mode setting"); -static uint64_t available_space(Server *s) { +static uint64_t available_space(Server *s, bool verbose) { char ids[33]; _cleanup_free_ char *p = NULL; - const char *f; sd_id128_t machine; struct statvfs ss; - uint64_t sum = 0, avail = 0, ss_avail = 0; + uint64_t sum = 0, ss_avail = 0, avail = 0; int r; _cleanup_closedir_ DIR *d = NULL; usec_t ts; + const char *f; JournalMetrics *m; ts = now(CLOCK_MONOTONIC); - if (s->cached_available_space_timestamp + RECHECK_AVAILABLE_SPACE_USEC > ts) + if (s->cached_available_space_timestamp + RECHECK_AVAILABLE_SPACE_USEC > ts + && !verbose) return s->cached_available_space; r = sd_id128_get_machine(&machine); @@ -156,19 +157,27 @@ static uint64_t available_space(Server *s) { sum += (uint64_t) st.st_blocks * 512UL; } - avail = sum >= m->max_use ? 0 : m->max_use - sum; - ss_avail = ss.f_bsize * ss.f_bavail; + avail = ss_avail > m->keep_free ? ss_avail - m->keep_free : 0; - ss_avail = ss_avail < m->keep_free ? 0 : ss_avail - m->keep_free; - - if (ss_avail < avail) - avail = ss_avail; - - s->cached_available_space = avail; + s->cached_available_space = MIN(m->max_use, avail) > sum ? MIN(m->max_use, avail) - sum : 0; s->cached_available_space_timestamp = ts; - return avail; + if (verbose) { + char fb1[FORMAT_BYTES_MAX], fb2[FORMAT_BYTES_MAX], fb3[FORMAT_BYTES_MAX], + fb4[FORMAT_BYTES_MAX], fb5[FORMAT_BYTES_MAX]; + + server_driver_message(s, SD_MESSAGE_JOURNAL_USAGE, + "%s journal is using %s (max %s, leaving %s of free %s, current limit %s).", + s->system_journal ? "Permanent" : "Runtime", + format_bytes(fb1, sizeof(fb1), sum), + format_bytes(fb2, sizeof(fb2), m->max_use), + format_bytes(fb3, sizeof(fb3), m->keep_free), + format_bytes(fb4, sizeof(fb4), ss_avail), + format_bytes(fb5, sizeof(fb5), MIN(m->max_use, avail))); + } + + return s->cached_available_space; } static void server_read_file_gid(Server *s) { @@ -853,7 +862,7 @@ void server_dispatch_message( } rl = journal_rate_limit_test(s->rate_limit, path, - priority & LOG_PRIMASK, available_space(s)); + priority & LOG_PRIMASK, available_space(s, false)); if (rl == 0) return; @@ -899,28 +908,13 @@ static int system_journal_open(Server *s) { fn = strappenda(fn, "/system.journal"); r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, NULL, &s->system_journal); - if (r >= 0) { - char fb[FORMAT_BYTES_MAX]; - uint64_t avail; - + if (r >= 0) server_fix_perms(s, s->system_journal, 0); + } else if (r < 0) { + if (r != -ENOENT && r != -EROFS) + log_warning("Failed to open system journal: %s", strerror(-r)); - server_driver_message(s, SD_ID128_NULL, "Allowing system journal files to grow to %s.", - format_bytes(fb, sizeof(fb), s->system_metrics.max_use)); - - avail = available_space(s); - - if (s->system_metrics.max_use > avail) - server_driver_message(s, SD_ID128_NULL, "Journal size currently limited to %s due to SystemKeepFree.", - format_bytes(fb, sizeof(fb), avail)); - - } else if (r < 0) { - - if (r != -ENOENT && r != -EROFS) - log_warning("Failed to open system journal: %s", strerror(-r)); - - r = 0; - } + r = 0; } if (!s->runtime_journal && @@ -961,22 +955,12 @@ static int system_journal_open(Server *s) { } } - if (s->runtime_journal) { - char fb[FORMAT_BYTES_MAX]; - uint64_t avail; - + if (s->runtime_journal) server_fix_perms(s, s->runtime_journal, 0); - server_driver_message(s, SD_ID128_NULL, "Allowing runtime journal files to grow to %s.", - format_bytes(fb, sizeof(fb), s->runtime_metrics.max_use)); - - avail = available_space(s); - - if (s->system_metrics.max_use > avail) - server_driver_message(s, SD_ID128_NULL, "Journal size currently limited to %s due to RuntimeKeepFree.", - format_bytes(fb, sizeof(fb), avail)); - } } + available_space(s, true); + return r; } @@ -1228,8 +1212,8 @@ int process_event(Server *s, struct epoll_event *ev) { label = (char*) CMSG_DATA(cmsg); label_len = cmsg->cmsg_len - CMSG_LEN(0); } else if (cmsg->cmsg_level == SOL_SOCKET && - cmsg->cmsg_type == SO_TIMESTAMP && - cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval))) + cmsg->cmsg_type == SO_TIMESTAMP && + cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval))) tv = (struct timeval*) CMSG_DATA(cmsg); else if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) { @@ -1455,7 +1439,7 @@ int server_init(Server *s) { zero(*s); s->sync_timer_fd = s->syslog_fd = s->native_fd = s->stdout_fd = - s->signal_fd = s->epoll_fd = s->dev_kmsg_fd = -1; + s->signal_fd = s->epoll_fd = s->dev_kmsg_fd = -1; s->compress = true; s->seal = true; diff --git a/src/systemd/sd-messages.h b/src/systemd/sd-messages.h index 2f80749c0f..c811a064e3 100644 --- a/src/systemd/sd-messages.h +++ b/src/systemd/sd-messages.h @@ -39,6 +39,7 @@ extern "C" { #define SD_MESSAGE_JOURNAL_STOP SD_ID128_MAKE(d9,3f,b3,c9,c2,4d,45,1a,97,ce,a6,15,ce,59,c0,0b) #define SD_MESSAGE_JOURNAL_DROPPED SD_ID128_MAKE(a5,96,d6,fe,7b,fa,49,94,82,8e,72,30,9e,95,d6,1e) #define SD_MESSAGE_JOURNAL_MISSED SD_ID128_MAKE(e9,bf,28,e6,e8,34,48,1b,b6,f4,8f,54,8a,d1,36,06) +#define SD_MESSAGE_JOURNAL_USAGE SD_ID128_MAKE(ec,38,7f,57,7b,84,4b,8f,a9,48,f3,3c,ad,9a,75,e6) #define SD_MESSAGE_COREDUMP SD_ID128_MAKE(fc,2e,22,bc,6e,e6,47,b6,b9,07,29,ab,34,a2,50,b1) -- cgit v1.2.1 From 9d64774057400ee15e7ffb159294f73bb665eb84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 24 Jun 2013 21:00:28 -0400 Subject: journald: always vacuum empty offline files Corrupted empty files are relatively common. I think they are created when a coredump for a user who never logged anything before is attempted to be written, but the write does not succeed because the coredump is too big, but there are probably other ways to create those, especially if the machine crashes at the right time. Non-corrupted empty files can also happen, e.g. if a journal file is opened, but nothing is ever successfully written to it and it is rotated because of MaxFileSec=. Either way, each "empty" journal file costs around 3 MB, and there's little point in keeping them around. --- src/journal/journal-vacuum.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/journal/journal-vacuum.c b/src/journal/journal-vacuum.c index 1ddb043e2c..79572f1fb6 100644 --- a/src/journal/journal-vacuum.c +++ b/src/journal/journal-vacuum.c @@ -128,6 +128,24 @@ static void patch_realtime( #endif } +static int journal_file_empty(int dir_fd, const char *name) { + int fd, r; + le64_t n_entries; + + fd = openat(dir_fd, name, O_RDONLY|O_CLOEXEC|O_NOFOLLOW|O_NONBLOCK); + if (fd < 0) + return -errno; + + if (lseek(fd, offsetof(Header, n_entries), SEEK_SET) < 0) + return -errno; + + r = read(fd, &n_entries, sizeof(n_entries)); + if (r != sizeof(n_entries)) + return r == 0 ? -EINVAL : -errno; + + return le64toh(n_entries) == 0; +} + int journal_directory_vacuum( const char *directory, uint64_t max_use, @@ -247,6 +265,17 @@ int journal_directory_vacuum( /* We do not vacuum active files or unknown files! */ continue; + if (journal_file_empty(dirfd(d), de->d_name)) { + + /* Always vacuum empty non-online files. */ + + if (unlinkat(dirfd(d), de->d_name, 0) >= 0) + log_debug("Deleted empty journal %s/%s.", directory, de->d_name); + else if (errno != ENOENT) + log_warning("Failed to delete %s/%s: %m", directory, de->d_name); + continue; + } + patch_realtime(directory, de->d_name, &st, &realtime); GREEDY_REALLOC(list, n_allocated, n_list + 1); -- cgit v1.2.1 From 175728c45fae8a2e1aa9d725ee2fbc7aa34e6dbf Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Tue, 25 Jun 2013 13:06:51 +0200 Subject: systemctl: conform to LSB with the "status" return code http://fedoraproject.org/wiki/Packaging:SysVInitScript#Exit_Codes_for_the_Status_Action https://bugzilla.redhat.com/show_bug.cgi?id=975016 --- src/systemctl/systemctl.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 53033baae8..71bf17d475 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -2658,6 +2658,7 @@ typedef struct UnitStatusInfo { pid_t main_pid; pid_t control_pid; const char *status_text; + const char *pid_file; bool running:1; usec_t start_timestamp; @@ -3057,6 +3058,8 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn i->default_control_group = s; else if (streq(name, "StatusText")) i->status_text = s; + else if (streq(name, "PIDFile")) + i->pid_file = s; else if (streq(name, "SysFSPath")) i->sysfs_path = s; else if (streq(name, "Where")) @@ -3549,7 +3552,16 @@ static int show_one(const char *verb, DBusConnection *bus, const char *path, boo !streq_ptr(info.active_state, "reloading") && streq(verb, "status")) /* According to LSB: "program not running" */ - r = 3; + /* 0: program is running or service is OK + * 1: program is dead and /var/run pid file exists + * 2: program is dead and /var/lock lock file exists + * 3: program is not running + * 4: program or service status is unknown + */ + if (info.pid_file) + r = 1; + else + r = 3; while ((p = info.exec)) { LIST_REMOVE(ExecStatusInfo, exec, info.exec, p); -- cgit v1.2.1 From aed63d6758ecfe9fa19aef861f4a9b4cef3a0806 Mon Sep 17 00:00:00 2001 From: David King Date: Tue, 25 Jun 2013 11:48:17 +0100 Subject: man: Small language improvements to sd_journal_open --- man/sd_journal_open.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/man/sd_journal_open.xml b/man/sd_journal_open.xml index 0f4178274e..36c9d16019 100644 --- a/man/sd_journal_open.xml +++ b/man/sd_journal_open.xml @@ -94,7 +94,7 @@ files automatically and interleave them automatically when reading. As first argument it takes a pointer to a sd_journal pointer, which on - success will contain journal context object afterwards. The + success will contain a journal context object. The second argument is a flags field, which may consist of the following flags ORed together: SD_JOURNAL_LOCAL_ONLY makes sure @@ -126,10 +126,10 @@ interleaved automatically. This call also takes a flags argument, but it must be passed as 0 as no flags are currently understood for this call. Please note - that in case of a live journal, this function is only + that in the case of a live journal, this function is only useful for debugging, because individual journal files can be rotated at any moment, and the opening of - specific files in inherently racy. + specific files is inherently racy. sd_journal_close() will close the journal context allocated with @@ -144,7 +144,7 @@ See sd_journal_next3 - for an example how to iterate through the journal + for an example of how to iterate through the journal after opening it with sd_journal_open(). @@ -189,7 +189,7 @@ The sd_journal_open(), sd_journal_open_directory() and sd_journal_close() interfaces are - available as shared library, which can be compiled and + available as a shared library, which can be compiled and linked to with the libsystemd-journal pkg-config1 -- cgit v1.2.1 From 3b05b8b3b503caf525fa72440a3f9f4bae75268b Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Tue, 25 Jun 2013 16:25:38 +0200 Subject: systemctl: conform to LSB with the "status" return code check for pid file existance before returning 1 --- src/systemctl/systemctl.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 71bf17d475..24543ee06d 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -3550,7 +3550,7 @@ static int show_one(const char *verb, DBusConnection *bus, const char *path, boo if (!streq_ptr(info.active_state, "active") && !streq_ptr(info.active_state, "reloading") && - streq(verb, "status")) + streq(verb, "status")) { /* According to LSB: "program not running" */ /* 0: program is running or service is OK * 1: program is dead and /var/run pid file exists @@ -3558,10 +3558,11 @@ static int show_one(const char *verb, DBusConnection *bus, const char *path, boo * 3: program is not running * 4: program or service status is unknown */ - if (info.pid_file) + if (info.pid_file && access(info.pid_file, F_OK) == 0) r = 1; else r = 3; + } while ((p = info.exec)) { LIST_REMOVE(ExecStatusInfo, exec, info.exec, p); -- cgit v1.2.1 From 909f413d3c572baadf9b13e36e1e90beba42af86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 26 Jun 2013 08:03:53 -0400 Subject: man: always supply quotes around literals When manpages are displayed on a terminal, s are indistinguishable from surrounding text. Add quotes everywhere, remove duplicate quotes, and tweak a few lists for consistent formatting. https://bugzilla.redhat.com/show_bug.cgi?id=874631 --- man/crypttab.xml | 2 +- man/custom-html.xsl | 6 +++ man/custom-man.xsl | 9 ++++ man/daemon.xml | 2 +- man/journalctl.xml | 21 ++++---- man/systemd-analyze.xml | 2 +- man/systemd-halt.service.xml | 10 ++-- man/systemd-suspend.service.xml | 14 ++--- man/systemd.device.xml | 2 +- man/systemd.journal-fields.xml | 12 ++--- man/systemd.service.xml | 24 ++++----- man/systemd.unit.xml | 8 +-- man/udev.xml | 117 ++++++++++++++++++++-------------------- 13 files changed, 123 insertions(+), 106 deletions(-) diff --git a/man/crypttab.xml b/man/crypttab.xml index deb577b9de..1063b46e06 100644 --- a/man/crypttab.xml +++ b/man/crypttab.xml @@ -68,7 +68,7 @@ describes encrypted block devices that are set up during system boot. - Empty lines and lines starting with the # + Empty lines and lines starting with the # character are ignored. Each of the remaining lines describes one encrypted block device, fields on the line are delimited by white space. The first two diff --git a/man/custom-html.xsl b/man/custom-html.xsl index dde9d7af0e..060af2e56a 100644 --- a/man/custom-html.xsl +++ b/man/custom-html.xsl @@ -172,6 +172,12 @@
+ + " + + " + + diff --git a/man/custom-man.xsl b/man/custom-man.xsl index 753e5715e3..e1b8d3618a 100644 --- a/man/custom-man.xsl +++ b/man/custom-man.xsl @@ -52,4 +52,13 @@ + + + + + " + + " + + diff --git a/man/daemon.xml b/man/daemon.xml index 1283799473..de362c1b71 100644 --- a/man/daemon.xml +++ b/man/daemon.xml @@ -547,7 +547,7 @@ systemd, kernel devices appearing in the sysfs/udev device tree can be exposed as units if they are tagged with the string - "systemd". Like any other + systemd. Like any other kind of unit they may then pull in other units when activated (i.e. Plugged in) and thus implement device-based activation. Systemd diff --git a/man/journalctl.xml b/man/journalctl.xml index 564634b757..fa29c4103c 100644 --- a/man/journalctl.xml +++ b/man/journalctl.xml @@ -84,7 +84,7 @@ alternatives, i.e. the resulting output will show entries matching any of the specified matches for the same field. Finally, if the character - "+" appears as separate word on the + + appears as separate word on the command line all matches before and after are combined in a disjunction (i.e. logical OR).
@@ -415,14 +415,15 @@ Start showing entries on or newer than the specified date, or on or older than the specified - date, respectively. Date specifications should be of - the format "2012-10-30 18:17:16". If - the time part is omitted, 00:00:00 is - assumed. If only the seconds component - is omitted, :00 is assumed. If the - date component is omitted, the - current day is assumed. Alternatively - the strings + date, respectively. Date specifications + should be of the format + 2012-10-30 18:17:16. + If the time part is omitted, + 00:00:00 is assumed. + If only the seconds component is omitted, + :00 is assumed. If the + date component is omitted, the current + day is assumed. Alternatively the strings yesterday, today, tomorrow are @@ -681,7 +682,7 @@ journalctl _SYSTEMD_UNIT=avahi-daemon.service _SYSTEMD_UNIT=dbus.service - If the separator "+" is used + If the separator + is used two expressions may be combined in a logical OR. The following will show all messages from the Avahi service process with the PID 28097 plus all messages diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml index ae7a3377c6..cecf1bf4d3 100644 --- a/man/systemd-analyze.xml +++ b/man/systemd-analyze.xml @@ -243,7 +243,7 @@ Examples This plots all dependencies of any unit whose - name starts with "avahi-daemon.": + name starts with avahi-daemon.: $ systemd-analyze dot 'avahi-daemon.*' | dot -Tsvg > avahi.svg $ eog avahi.svg diff --git a/man/systemd-halt.service.xml b/man/systemd-halt.service.xml index 6a6bfdc7d7..812281e60d 100644 --- a/man/systemd-halt.service.xml +++ b/man/systemd-halt.service.xml @@ -89,10 +89,10 @@ executables in /usr/lib/systemd/system-shutdown/ and pass one arguments to them: either - "halt", - "poweroff", - "reboot" or - "kexec", depending on the chosen + halt, + poweroff, + reboot or + kexec, depending on the chosen action. All executables in this directory are executed in parallel, and execution of the action is not continued before all executables finished. @@ -101,7 +101,7 @@ systemd-halt.service (and the related units) should never be executed directly. Instead, trigger system shutdown with a - command such as "systemctl halt" or + command such as systemctl halt or suchlike. diff --git a/man/systemd-suspend.service.xml b/man/systemd-suspend.service.xml index 4a4ed5cbdb..9b08f04939 100644 --- a/man/systemd-suspend.service.xml +++ b/man/systemd-suspend.service.xml @@ -80,14 +80,14 @@ executables in /usr/lib/systemd/system-sleep/ and pass two arguments to them. The first argument - will be "pre", the second either - "suspend", - "hibernate", or - "hybrid-sleep" depending on the + will be pre, the second either + suspend, + hibernate, or + hybrid-sleep depending on the chosen action. Immediately after leaving system suspend and/or hibernation the same executables are run, but the first argument is now - "post". All executables in this + post. All executables in this directory are executed in parallel, and execution of the action is not continued until all executables have finished.
@@ -105,11 +105,11 @@ systemd-hybrid-sleep.service should never be executed directly. Instead, trigger system sleep states with a command such as - "systemctl suspend" or + systemctl suspend or similar.
Internally, this service will echo a string like - "mem" into + mem into /sys/power/state, to trigger the actual system suspend. What exactly is written where can be configured in the [Sleep] diff --git a/man/systemd.device.xml b/man/systemd.device.xml index 7dffa236cf..1c29aa4e79 100644 --- a/man/systemd.device.xml +++ b/man/systemd.device.xml @@ -107,7 +107,7 @@ available. Note that this and the other tags are not taken into account unless the device is tagged with the - "systemd" string in + systemd string in the udev database, because otherwise the device is not exposed as systemd unit. diff --git a/man/systemd.journal-fields.xml b/man/systemd.journal-fields.xml index beb2fd6584..de01dc236b 100644 --- a/man/systemd.journal-fields.xml +++ b/man/systemd.journal-fields.xml @@ -375,15 +375,15 @@ name. If the entry is associated to a block device, the major and minor of the - device node, separated by ':' - and prefixed by 'b'. Similar + device node, separated by : + and prefixed by b. Similar for character devices, but - prefixed by 'c'. For network + prefixed by c. For network devices the interface index, - prefixed by 'n'. For all other - devices '+' followed by the + prefixed by n. For all other + devices + followed by the subsystem name, followed by - ':', followed by the kernel + :, followed by the kernel device name.
diff --git a/man/systemd.service.xml b/man/systemd.service.xml index 0454cf292e..dcf57c30bb 100644 --- a/man/systemd.service.xml +++ b/man/systemd.service.xml @@ -319,7 +319,7 @@ suitable for XDG .desktop files. Lone semicolons may be escaped as - '\;'. If the empty + \;. If the empty string is assigned to this option the list of commands to start is reset, prior assignments of this option will @@ -330,7 +330,7 @@ one by one sequentially in the order they appear in the unit file. If one of the commands fails (and is not - prefixed with '-'), + prefixed with -), other lines are not executed and the unit is considered failed. @@ -341,7 +341,7 @@ main process of the daemon. The command line accepts - '%' specifiers as + % specifiers as described in systemd.unit5. Note that the first argument of the command @@ -370,19 +370,19 @@ Optionally, if the absolute file name is prefixed with - '@', the second token + @, the second token will be passed as argv[0] to the executed process, followed by the further arguments specified. If the absolute file name is prefixed with - '-' an exit code of + - an exit code of the command normally considered a failure (i.e. non-zero exit status or abnormal exit due to signal) is ignored and considered success. If both - '-' and - '@' are used they + - and + @ are used they can appear in either order. Note that this setting does not @@ -417,7 +417,7 @@ after the other, serially. If any of those commands (not - prefixed with '-') + prefixed with -) fail, the rest are not executed and the unit is considered failed. @@ -662,8 +662,8 @@ definitions can either be numeric exit codes or termination signal names, separated by spaces. Example: - "SuccessExitStatus=1 2 8 - SIGKILL", ensures that exit + SuccessExitStatus=1 2 8 + SIGKILL, ensures that exit codes 1, 2, 8 and the termination signal SIGKILL are considered clean service terminations. This option may @@ -692,8 +692,8 @@ that by default no exit status is excluded from the configured restart logic. Example: - "RestartPreventExitStatus=1 6 - SIGABRT", ensures that exit + RestartPreventExitStatus=1 6 + SIGABRT, ensures that exit codes 1 and 6 and the termination signal SIGABRT will not result in automatic service restarting. This diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index 6a5eefb6db..1cfdac9267 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -646,7 +646,7 @@ Lists one or more units that are activated when this unit enters the - 'failed' + failed state. @@ -812,7 +812,7 @@ time. If this time limit is reached the job will be cancelled, the unit however will not change state or even - enter the 'failed' + enter the failed mode. This value defaults to 0 (job timeouts disabled), except for device units. NB: this timeout is independent @@ -871,7 +871,7 @@ to ConditionPathExists= is prefixed with an exclamation mark - ('!'), the test is negated, and the unit + (!), the test is negated, and the unit is only started if the path does not exist. @@ -940,7 +940,7 @@ exclamation mark unset). The argument must either be a single word, or an assignment (i.e. two words, separated - '='). In the former + =). In the former case the kernel command line is searched for the word appearing as is, or as left hand side of an diff --git a/man/udev.xml b/man/udev.xml index 964aeda802..2353b10023 100644 --- a/man/udev.xml +++ b/man/udev.xml @@ -73,7 +73,7 @@ extensions are ignored. Every line in the rules file contains at least one key-value pair. - Except for empty lines or lines beginning with '#', which are ignored. + Except for empty lines or lines beginning with #, which are ignored. There are two kinds of keys: match and assignment. If all match keys match against their values, the rule gets applied and the assignment keys get the specified values assigned. @@ -130,28 +130,28 @@ one and the same parent device. - + ACTION Match the name of the event action. - + DEVPATH Match the devpath of the event device. - + KERNEL Match the name of the event device. - + NAME Match the name of a network interface. It can be used once the NAME key has been set in one of the preceding rules. @@ -159,7 +159,7 @@ - + SYMLINK Match the name of a symlink targeting the node. It can be used once a SYMLINK key has been set in one of the preceding @@ -169,20 +169,20 @@ - + SUBSYSTEM Match the subsystem of the event device. - + DRIVER Match the driver name of the event device. Only set this key for devices which are bound to a driver at the time the event is generated. - + ATTR{filename} Match sysfs attribute values of the event device. Trailing whitespace in the attribute values is ignored unless the specified match @@ -192,59 +192,59 @@ - + KERNELS Search the devpath upwards for a matching device name. - + SUBSYSTEMS Search the devpath upwards for a matching device subsystem name. - + DRIVERS Search the devpath upwards for a matching device driver name. - + ATTRS{filename} Search the devpath upwards for a device with matching sysfs attribute values. - If multiple matches are specified, all of them + If multiple ATTRS matches are specified, all of them must match on the same device. Trailing whitespace in the attribute values is ignored unless the specified match value itself contains trailing whitespace. - + TAGS Search the devpath upwards for a device with matching tag. - + ENV{key} Match against a device property value. - + TAG Match against a device tag. - + TEST{octal mode mask} Test the existence of a file. An octal mode mask can be specified if needed. @@ -252,7 +252,7 @@ - + PROGRAM Execute a program to determine whether there is a match; the key is true if the program returns @@ -260,12 +260,12 @@ executed program in the environment. The program's stdout is available in the RESULT key. This can only be used for very short-running foreground tasks. For details - see . + see RUN. - + RESULT Match the returned string of the last PROGRAM call. This key can be used in the same or in any later rule after a PROGRAM call. @@ -292,11 +292,12 @@ [] Matches any single character specified within the brackets. For - example, the pattern string 'tty[SR]' would match either 'ttyS' or 'ttyR'. - Ranges are also supported via the '-' character. + example, the pattern string tty[SR] + would match either ttyS or ttyR. + Ranges are also supported via the - character. For example, to match on the range of all digits, the pattern [0-9] could - be used. If the first character following the '[' is a '!', any characters - not enclosed are matched. + be used. If the first character following the [ is a + !, any characters not enclosed are matched. @@ -304,7 +305,7 @@ The following keys can get values assigned: - + NAME The name to use for a network interface. The name of a device node cannot be changed by udev, only additional symlinks can be created. @@ -312,14 +313,14 @@ - + SYMLINK The name of a symlink targeting the node. Every matching rule adds this value to the list of symlinks to be created. The set of characters to name a symlink is limited. Allowed - characters are [0-9A-Za-z#+-.:=@_/], valid UTF-8 character sequences, - and "\x00" hex encoding. All other characters are replaced by - a '_' character. + characters are 0-9A-Za-z#+-.:=@_/, valid UTF-8 character + sequences, and \x00 hex encoding. All other + characters are replaced by a _ character. Multiple symlinks may be specified by separating the names by the space character. In case multiple devices claim the same name, the link always points to the device with the highest link_priority. If the current @@ -334,7 +335,7 @@ - , , + OWNER, GROUP, MODE The permissions for the device node. Every specified value overrides the compiled-in default value. @@ -342,7 +343,7 @@ - + ATTR{key} The value that should be written to a sysfs attribute of the event device. @@ -350,16 +351,16 @@ - + ENV{key} - Set a device property value. Property names with a leading '.' + Set a device property value. Property names with a leading . are neither stored in the database nor exported to events or external tools (run by, say, the PROGRAM match key). - + TAG Attach a tag to a device. This is used to filter events for users of libudev's monitor functionality, or to enumerate a group of tagged @@ -372,7 +373,7 @@ - + RUN{type} Add a program to the list of programs to be executed after processing all the rules for a specific event, depending on type: @@ -390,7 +391,7 @@ builtin - As , but use one of the built-in programs rather + As program, but use one of the built-in programs rather than an external one. @@ -407,21 +408,21 @@ - + LABEL A named label to which a GOTO may jump. - + GOTO Jumps to the next LABEL with a matching name. - + IMPORT{type} Import a set of variables as device properties, depending on type: @@ -432,14 +433,14 @@ Execute an external program specified as the assigned value and import its output, which must be in environment key format. Path specification, command/argument separation, - and quoting work like in . + and quoting work like in RUN. builtin - As , but use one of the built-in programs rather - than an external one. + Similar to program, but use one of the + built-in programs rather than an external one. @@ -461,7 +462,7 @@ cmdline Import a single property from the kernel command line. For simple flags - the value of the property is set to '1'. + the value of the property is set to 1. @@ -481,7 +482,7 @@ - + WAIT_FOR Wait for a file to become available or until a timeout of 10 seconds expires. The path is relative to the sysfs device; @@ -490,7 +491,7 @@ - + OPTIONS Rule and device options: @@ -543,9 +544,9 @@ - The , , , - , , and - fields support simple string substitutions. The + The NAME, SYMLINK, PROGRAM, + OWNER, GROUP, MODE and RUN + fields support simple string substitutions. The RUN substitutions are performed after all rules have been processed, right before the program is executed, allowing for the use of device properties set by earlier matching rules. For all other fields, substitutions are performed while the individual rule is @@ -561,8 +562,8 @@ , - The kernel number for this device. For example, 'sda3' has - kernel number of '3' + The kernel number for this device. For example, + sda3 has kernel number 3. @@ -630,9 +631,9 @@ The string returned by the external program requested with PROGRAM. A single part of the string, separated by a space character, may be selected - by specifying the part number as an attribute: . - If the number is followed by the '+' character, this part plus all remaining parts - of the result string are substituted: + by specifying the part number as an attribute: %c{N}. + If the number is followed by the + character, this part plus all remaining parts + of the result string are substituted: %c{N+}. @@ -681,16 +682,16 @@ - %% + - The '%' character itself. + The % character itself. - $$ + - The '$' character itself. + The $ character itself. -- cgit v1.2.1 From 74d005783e355acc784d123024e33bbb66ef9ef1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 26 Jun 2013 19:47:34 -0400 Subject: man: use for various constants which look ugly with quotes --- man/bootchart.conf.xml | 2 +- man/daemon.xml | 4 +- man/pam_systemd.xml | 2 +- man/sd-daemon.xml | 2 +- man/sd-id128.xml | 2 +- man/sd-journal.xml | 2 +- man/sd-login.xml | 6 +-- man/sd_booted.xml | 2 +- man/sd_get_seats.xml | 6 +-- man/sd_id128_randomize.xml | 2 +- man/sd_is_fifo.xml | 18 ++++--- man/sd_journal_add_match.xml | 2 +- man/sd_journal_get_catalog.xml | 2 +- man/sd_journal_get_cursor.xml | 2 +- man/sd_journal_get_cutoff_realtime_usec.xml | 17 ++++--- man/sd_journal_get_data.xml | 2 +- man/sd_journal_get_fd.xml | 46 +++++++++-------- man/sd_journal_get_realtime_usec.xml | 25 ++++----- man/sd_journal_get_usage.xml | 4 +- man/sd_journal_next.xml | 2 +- man/sd_journal_open.xml | 30 +++++------ man/sd_journal_print.xml | 28 +++++------ man/sd_journal_query_unique.xml | 2 +- man/sd_journal_seek_head.xml | 12 +++-- man/sd_journal_stream_fd.xml | 20 ++++---- man/sd_listen_fds.xml | 2 +- man/sd_login_monitor_new.xml | 28 +++++------ man/sd_notify.xml | 4 +- man/sd_pid_get_session.xml | 4 +- man/sd_seat_get_active.xml | 17 ++++--- man/sd_session_is_active.xml | 11 ++-- man/sd_uid_get_state.xml | 8 +-- man/systemd-journald.service.xml | 4 +- man/systemd.exec.xml | 9 ++-- man/systemd.journal-fields.xml | 39 ++++++++------- man/systemd.socket.xml | 24 ++++----- man/systemd.xml | 78 ++++++++++++++--------------- 37 files changed, 244 insertions(+), 226 deletions(-) diff --git a/man/bootchart.conf.xml b/man/bootchart.conf.xml index 1e440eb2cc..7fd47ebe96 100644 --- a/man/bootchart.conf.xml +++ b/man/bootchart.conf.xml @@ -87,7 +87,7 @@ Relative=no Configures whether the left axis of the - output graph equals time=0.0 (CLOCK_MONOTONIC start). This + output graph equals time=0.0 (CLOCK_MONOTONIC start). This is useful for using bootchart at post-boot time to profile an already booted system, otherwise the graph would become extremely large. If set to yes, the horizontal axis starts diff --git a/man/daemon.xml b/man/daemon.xml index de362c1b71..258694080e 100644 --- a/man/daemon.xml +++ b/man/daemon.xml @@ -894,7 +894,7 @@ fi If the daemon offers interfaces to other software running on the - local system via local AF_UNIX sockets, + local system via local AF_UNIX sockets, consider implementing socket-based activation (see above). Usually a minimal patch is sufficient to implement this: Extend the @@ -906,7 +906,7 @@ fi positive value), skip the socket creation step and use the passed sockets. Secondly, ensure that the file system socket nodes for local - AF_UNIX sockets used in the socket-based + AF_UNIX sockets used in the socket-based activation are not removed when the daemon shuts down, if sockets have been passed. Third, if the daemon normally closes diff --git a/man/pam_systemd.xml b/man/pam_systemd.xml index 2dc6651885..0354811976 100644 --- a/man/pam_systemd.xml +++ b/man/pam_systemd.xml @@ -285,7 +285,7 @@ include the value of $XDG_SESSION_ID in the filename. This directory shall be used for runtime file system - objects such as AF_UNIX sockets, + objects such as AF_UNIX sockets, FIFOs, PID files and similar. It is guaranteed that this directory is local and offers the greatest possible diff --git a/man/sd-daemon.xml b/man/sd-daemon.xml index a3bf662fe9..55ee1fd893 100644 --- a/man/sd-daemon.xml +++ b/man/sd-daemon.xml @@ -146,7 +146,7 @@ sd-daemon.h files. These interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-daemon + libsystemd-daemon pkg-config1 file. Alternatively, applications consuming these APIs may copy the implementation into their source tree, diff --git a/man/sd-id128.xml b/man/sd-id128.xml index ac2000e275..51a16e35d4 100644 --- a/man/sd-id128.xml +++ b/man/sd-id128.xml @@ -149,7 +149,7 @@ Note that new, randomized IDs may be generated with journalctl1's - --new-id option. + option. diff --git a/man/sd-journal.xml b/man/sd-journal.xml index a7220ec6bc..490b971f19 100644 --- a/man/sd-journal.xml +++ b/man/sd-journal.xml @@ -100,7 +100,7 @@ These APIs are implemented as shared library, which can be compiled and linked to with the - libsystemd-journal + libsystemd-journal pkg-config1 file. diff --git a/man/sd-login.xml b/man/sd-login.xml index 697259564d..c186324f83 100644 --- a/man/sd-login.xml +++ b/man/sd-login.xml @@ -95,7 +95,7 @@ each other. If the functions return string arrays, these are - generally NULL terminated and need to be freed by the + generally NULL terminated and need to be freed by the caller with the libc free3 call after use, including the strings referenced @@ -103,7 +103,7 @@ be freed, as well. As a special exception, instead of an empty - string array NULL may be returned, which should be + string array NULL may be returned, which should be treated equivalent to an empty string array. See @@ -122,7 +122,7 @@ These APIs are implemented as shared library, which can be compiled and linked to with the - libsystemd-login + libsystemd-login pkg-config1 file. diff --git a/man/sd_booted.xml b/man/sd_booted.xml index ce5a34dc86..32d0fd095d 100644 --- a/man/sd_booted.xml +++ b/man/sd_booted.xml @@ -102,7 +102,7 @@ sd-daemon.h files. These interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-daemon + libsystemd-daemon pkg-config1 file. Alternatively, applications consuming these APIs may copy the implementation into their source diff --git a/man/sd_get_seats.xml b/man/sd_get_seats.xml index 9bc866dc68..9fb0732c10 100644 --- a/man/sd_get_seats.xml +++ b/man/sd_get_seats.xml @@ -82,12 +82,12 @@ sd_get_seats() may be used to determine all currently available local - seats. Returns a NULL terminated array of seat + seats. Returns a NULL terminated array of seat identifiers. The returned array and all strings it references need to be freed with the libc free3 call after use. Note that instead of an empty array - NULL may be returned and should be considered + NULL may be returned and should be considered equivalent to an empty array. Similar, sd_get_sessions() may @@ -124,7 +124,7 @@ sd_get_machine_names() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-login + libsystemd-login pkg-config1 file. diff --git a/man/sd_id128_randomize.xml b/man/sd_id128_randomize.xml index be74937dd0..37efe164cd 100644 --- a/man/sd_id128_randomize.xml +++ b/man/sd_id128_randomize.xml @@ -79,7 +79,7 @@ sd-id1283. journalctl1's - --new-id command may be used as + option may be used as command line front-end for sd_id128_randomize(). diff --git a/man/sd_is_fifo.xml b/man/sd_is_fifo.xml index 595c8f112d..5eaf1585a2 100644 --- a/man/sd_is_fifo.xml +++ b/man/sd_is_fifo.xml @@ -109,11 +109,13 @@ called to check whether the specified file descriptor refers to a socket. If the family parameter is not - AF_UNSPEC it is checked whether the socket is of the - specified family (AF_UNIX, AF_INET, ...). If the + AF_UNSPEC it is checked whether + the socket is of the specified family (AF_UNIX, + AF_INET, ...). If the type parameter is not 0 it is checked whether the socket is of the specified type - (SOCK_STREAM, SOCK_DGRAM, ...). If the + (SOCK_STREAM, + SOCK_DGRAM, ...). If the listening parameter is positive it is checked whether the socket is in accepting mode, i.e. listen() has been called for @@ -129,14 +131,14 @@ optionally checks the IPv4 or IPv6 port number the socket is bound to, unless port is zero. For this call family - must be passed as either AF_UNSPEC, AF_INET, or - AF_INET6. + must be passed as either AF_UNSPEC, AF_INET, or + AF_INET6. sd_is_socket_unix() is similar to sd_is_socket(), but - optionally checks the AF_UNIX path the socket is bound + optionally checks the AF_UNIX path the socket is bound to, unless the path parameter - is NULL. For normal file system AF_UNIX sockets set + is NULL. For normal file system AF_UNIX sockets set the length parameter to 0. For Linux abstract namespace sockets set the length to the size of the @@ -190,7 +192,7 @@ sd-daemon.h files. These interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-daemon + libsystemd-daemon pkg-config1 file. Alternatively, applications consuming these APIs may copy the implementation into their source diff --git a/man/sd_journal_add_match.xml b/man/sd_journal_add_match.xml index 549785ca83..82edf21834 100644 --- a/man/sd_journal_add_match.xml +++ b/man/sd_journal_add_match.xml @@ -176,7 +176,7 @@ sd_journal_flush_matches() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-journal + libsystemd-journal pkg-config1 file. diff --git a/man/sd_journal_get_catalog.xml b/man/sd_journal_get_catalog.xml index 719d77f723..d1962e4ca1 100644 --- a/man/sd_journal_get_catalog.xml +++ b/man/sd_journal_get_catalog.xml @@ -120,7 +120,7 @@ sd_journal_get_catalog_for_message_id() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-journal + libsystemd-journal pkg-config1 file. diff --git a/man/sd_journal_get_cursor.xml b/man/sd_journal_get_cursor.xml index 1b0e775bb4..d83c5191f5 100644 --- a/man/sd_journal_get_cursor.xml +++ b/man/sd_journal_get_cursor.xml @@ -132,7 +132,7 @@ and sd_journal_test_cursor() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-journal + libsystemd-journal pkg-config1 file. diff --git a/man/sd_journal_get_cutoff_realtime_usec.xml b/man/sd_journal_get_cutoff_realtime_usec.xml index ed014cb509..506c02c38c 100644 --- a/man/sd_journal_get_cutoff_realtime_usec.xml +++ b/man/sd_journal_get_cutoff_realtime_usec.xml @@ -79,9 +79,11 @@ three arguments: the journal context object and two pointers to 64 Bit unsigned integers to store the timestamps in. The timestamps are in microseconds - since the epoch, i.e. CLOCK_REALTIME. Either one of - the two timestamp arguments may be passed as NULL in - case the timestamp is not needed, but not both. + since the epoch, + i.e. CLOCK_REALTIME. Either one + of the two timestamp arguments may be passed as + NULL in case the timestamp is not + needed, but not both. sd_journal_get_cutoff_monotonic_usec() gets the monotonic timestamps of the first and last @@ -90,7 +92,8 @@ identifier for the boot, and two pointers to 64 Bit unsigned integers to store the timestamps. The timestamps are in microseconds since boot-up of the - specific boot, i.e. CLOCK_MONOTONIC. Since the + specific boot, + i.e. CLOCK_MONOTONIC. Since the monotonic clock begins new with every reboot it only defines a well-defined point in time when used together with an identifier identifying the boot, see @@ -98,8 +101,8 @@ for more information. The function will return the timestamps for the boot identified by the passed boot ID. Either one of the two timestamp arguments may be - passed as NULL in case the timestamp is not needed, - but not both. + passed as NULL in case the + timestamp is not needed, but not both. @@ -121,7 +124,7 @@ sd_journal_get_cutoff_monotonic_usec() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-journal + libsystemd-journal pkg-config1 file. diff --git a/man/sd_journal_get_data.xml b/man/sd_journal_get_data.xml index 1259b0cdbe..ba50b8d092 100644 --- a/man/sd_journal_get_data.xml +++ b/man/sd_journal_get_data.xml @@ -205,7 +205,7 @@ sd_journal_get_data_threshold() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-journal + libsystemd-journal pkg-config1 file. diff --git a/man/sd_journal_get_fd.xml b/man/sd_journal_get_fd.xml index 33d2980b3b..f3fbe69c32 100644 --- a/man/sd_journal_get_fd.xml +++ b/man/sd_journal_get_fd.xml @@ -123,22 +123,28 @@ sd_journal_get_events() will return the poll() mask to wait for. This function will return a combination of - POLLIN and - POLLOUT and similar to fill into + POLLIN and + POLLOUT and similar to fill into the .events field of - struct pollfd. + struct pollfd. sd_journal_get_timeout() - will return a timeout value for usage in poll(). This returns a value in microseconds since the epoch of CLOCK_MONOTONIC for timing out poll() in timeout_usec. See + will return a timeout value for usage in + poll(). This returns a value in + microseconds since the epoch of + CLOCK_MONOTONIC for timing out + poll() in + timeout_usec. See clock_gettime2 for details about - CLOCK_MONOTONIC. If there's no + CLOCK_MONOTONIC. If there's no timeout to wait for this will fill in - (uint64_t) -1 instead. Note that + (uint64_t) -1 instead. Note that poll() takes a relative timeout in milliseconds rather than an absolute timeout in - microseconds. To convert the absolute 'us' timeout into - relative 'ms', use code like the following: + microseconds. To convert the absolute 'us' timeout + into relative 'ms', use code like the + following: uint64_t t; int msec; @@ -154,7 +160,7 @@ else { } The code above does not do any error checking - for brevity's sake. The calculated msec + for brevity's sake. The calculated msec integer can be passed directly as poll()'s timeout parameter. @@ -174,7 +180,7 @@ else { synchronously wait until the journal gets changed. The maximum time this call sleeps may be controlled with the timeout_usec - parameter. Pass (uint64_t) -1 to + parameter. Pass (uint64_t) -1 to wait indefinitely. Internally this call simply combines sd_journal_get_fd(), sd_journal_get_events(), @@ -209,8 +215,8 @@ else { errno-style error code. sd_journal_get_events() - returns a combination of POLLIN, - POLLOUT and suchlike on success or + returns a combination of POLLIN, + POLLOUT and suchlike on success or a negative errno-style error code. sd_journal_reliable_fd() @@ -222,19 +228,19 @@ else { sd_journal_process() and sd_journal_wait() return one of - SD_JOURNAL_NOP, - SD_JOURNAL_APPEND or - SD_JOURNAL_INVALIDATE on success or + SD_JOURNAL_NOP, + SD_JOURNAL_APPEND or + SD_JOURNAL_INVALIDATE on success or a negative errno-style error code. If - SD_JOURNAL_NOP is returned the + SD_JOURNAL_NOP is returned the journal didn't change since the last invocation. If - SD_JOURNAL_APPEND is returned new + SD_JOURNAL_APPEND is returned new entries have been appended to the end of the - journal. If SD_JOURNAL_INVALIDATE + journal. If SD_JOURNAL_INVALIDATE journal files were added or removed (possibly due to rotation). In the latter event live-view UIs should probably refresh their entire display while in the - case of SD_JOURNAL_APPEND it is + case of SD_JOURNAL_APPEND it is sufficient to simply continue reading at the previous end of the journal. @@ -249,7 +255,7 @@ else { sd_journal_wait() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-journal + libsystemd-journal pkg-config1 file. diff --git a/man/sd_journal_get_realtime_usec.xml b/man/sd_journal_get_realtime_usec.xml index 515932c6d8..b57a7c15b2 100644 --- a/man/sd_journal_get_realtime_usec.xml +++ b/man/sd_journal_get_realtime_usec.xml @@ -77,24 +77,25 @@ journal context object and a pointer to a 64 Bit unsigned integer to store the timestamp in. The timestamp is in microseconds since the epoch, - i.e. CLOCK_REALTIME. + i.e. CLOCK_REALTIME. sd_journal_get_monotonic_usec() - gets the monotonic timestamp of the current - journal entry. It takes three arguments: the journal - context object, a pointer to a 64 Bit unsigned integer - to store the timestamp in as well as a 128 Bit ID - buffer to store the boot ID of the monotonic timestamp + gets the monotonic timestamp of the current journal + entry. It takes three arguments: the journal context + object, a pointer to a 64 Bit unsigned integer to + store the timestamp in as well as a 128 Bit ID buffer + to store the boot ID of the monotonic timestamp in. The timestamp is in microseconds since boot-up of - the specific boot, i.e. CLOCK_MONOTONIC. Since the + the specific boot, + i.e. CLOCK_MONOTONIC. Since the monotonic clock begins new with every reboot it only defines a well-defined point in time when used together with an identifier identifying the boot, see sd_id128_get_boot3 for more information. If the boot ID parameter is - passed NULL the function will fail if the monotonic - timestamp of the current entry is not of the current - system boot. + passed NULL the function will + fail if the monotonic timestamp of the current entry + is not of the current system boot. Note that these functions will not work before sd_journal_next3 @@ -109,7 +110,7 @@ and sd_journal_get_monotonic_usec() returns 0 on success or a negative errno-style error - code. If the boot ID parameter was passed NULL and the + code. If the boot ID parameter was passed NULL and the monotonic timestamp of the current journal entry is not of the current system boot, -ESTALE is returned by sd_journal_get_monotonic_usec(). @@ -123,7 +124,7 @@ sd_journal_get_monotonic_usec() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-journal + libsystemd-journal pkg-config1 file. diff --git a/man/sd_journal_get_usage.xml b/man/sd_journal_get_usage.xml index a2b868f218..490317ac91 100644 --- a/man/sd_journal_get_usage.xml +++ b/man/sd_journal_get_usage.xml @@ -66,7 +66,7 @@ sd_journal_get_usage() determines the total disk space currently used by journal files (in bytes). If - SD_JOURNAL_LOCAL_ONLY was passed + SD_JOURNAL_LOCAL_ONLY was passed when opening the journal this value will only reflect the size of journal files of the local host, otherwise of all hosts. @@ -86,7 +86,7 @@ The sd_journal_get_usage() interface is available as shared library, which can be compiled and linked to with the - libsystemd-journal + libsystemd-journal pkg-config1 file. diff --git a/man/sd_journal_next.xml b/man/sd_journal_next.xml index 9b1cb1fc46..11066611f1 100644 --- a/man/sd_journal_next.xml +++ b/man/sd_journal_next.xml @@ -158,7 +158,7 @@ sd_journal_previous_skip() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-journal + libsystemd-journal pkg-config1 file. diff --git a/man/sd_journal_open.xml b/man/sd_journal_open.xml index 36c9d16019..d7ea8ff95b 100644 --- a/man/sd_journal_open.xml +++ b/man/sd_journal_open.xml @@ -93,22 +93,22 @@ the log journal for reading. It will find all journal files automatically and interleave them automatically when reading. As first argument it takes a pointer to - a sd_journal pointer, which on + a sd_journal pointer, which on success will contain a journal context object. The second argument is a flags field, which may consist of the following flags ORed together: - SD_JOURNAL_LOCAL_ONLY makes sure + SD_JOURNAL_LOCAL_ONLY makes sure only journal files generated on the local machine will - be opened. SD_JOURNAL_RUNTIME_ONLY + be opened. SD_JOURNAL_RUNTIME_ONLY makes sure only volatile journal files will be opened, excluding those which are stored on persistent - storage. SD_JOURNAL_SYSTEM + storage. SD_JOURNAL_SYSTEM will cause journal files of system services and the kernel (in opposition to user session processes) to - be opened. SD_JOURNAL_CURRENT_USER + be opened. SD_JOURNAL_CURRENT_USER will cause journal files of the current user to be - opened. If neither SD_JOURNAL_SYSTEM - nor SD_JOURNAL_CURRENT_USER are + opened. If neither SD_JOURNAL_SYSTEM + nor SD_JOURNAL_CURRENT_USER are specified, all journal file types will be opened. sd_journal_open_directory() @@ -121,7 +121,7 @@ sd_journal_open_files() is similar to sd_journal_open() - but takes a NULL-terminated list + but takes a NULL-terminated list of file paths to open. All files will be opened and interleaved automatically. This call also takes a flags argument, but it must be passed as 0 as no flags @@ -191,7 +191,7 @@ sd_journal_close() interfaces are available as a shared library, which can be compiled and linked to with the - libsystemd-journal + libsystemd-journal pkg-config1 file. @@ -201,19 +201,19 @@ sd_journal_open(), sd_journal_close(), - SD_JOURNAL_LOCAL_ONLY, - SD_JOURNAL_RUNTIME_ONLY, - SD_JOURNAL_SYSTEM_ONLY were added + SD_JOURNAL_LOCAL_ONLY, + SD_JOURNAL_RUNTIME_ONLY, + SD_JOURNAL_SYSTEM_ONLY were added in systemd-38. sd_journal_open_directory() was added in systemd-187. - SD_JOURNAL_SYSTEM, - SD_JOURNAL_CURRENT_USER, + SD_JOURNAL_SYSTEM, + SD_JOURNAL_CURRENT_USER, and sd_journal_open_files() were added in systemd-205. - SD_JOURNAL_SYSTEM_ONLY + SD_JOURNAL_SYSTEM_ONLY was deprecated. diff --git a/man/sd_journal_print.xml b/man/sd_journal_print.xml index cdaea8c2ef..7292d33456 100644 --- a/man/sd_journal_print.xml +++ b/man/sd_journal_print.xml @@ -102,14 +102,14 @@ or syslog3. The priority value is one of - LOG_EMERG, - LOG_ALERT, - LOG_CRIT, - LOG_ERR, - LOG_WARNING, - LOG_NOTICE, - LOG_INFO, - LOG_DEBUG, as defined in + LOG_EMERG, + LOG_ALERT, + LOG_CRIT, + LOG_ERR, + LOG_WARNING, + LOG_NOTICE, + LOG_INFO, + LOG_DEBUG, as defined in syslog.h, see syslog3 for details. It is recommended to use this call to @@ -120,7 +120,7 @@ sd_journal_printv() is similar to sd_journal_print() but takes a variable argument list encapsulated in an - object of type va_list (see + object of type va_list (see stdarg3 for more information) instead of the format string. It is otherwise equivalent in behavior. @@ -129,7 +129,7 @@ used to submit structured log entries to the system journal. It takes a series of format strings, each immediately followed by their associated parameters, - terminated by NULL. The strings passed should be of + terminated by NULL. The strings passed should be of the format VARIABLE=value. The variable name must be in uppercase and consist only of characters, numbers and underscores, and may not begin @@ -147,7 +147,7 @@ sd_journal_sendv() is similar to sd_journal_send() but - takes an array of struct iovec (as + takes an array of struct iovec (as defined in uio.h, see readv3 for details) instead of the format string. Each @@ -166,12 +166,12 @@ readable representation of the current error code stored in errno3. If - the message string is passed as NULL or empty string + the message string is passed as NULL or empty string only the error string representation will be written, prefixed with nothing. An additional journal field ERRNO= is included in the entry containing the numeric error code formatted as decimal string. The log - priority used is LOG_ERR (3). + priority used is LOG_ERR (3). Note that sd_journal_send() is a wrapper around @@ -229,7 +229,7 @@ sd_journal_send("MESSAGE=Hello World, this is PID %lu!", (unsigned long) getpid( sd_journal_sendv() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-journal + libsystemd-journal pkg-config1 file. diff --git a/man/sd_journal_query_unique.xml b/man/sd_journal_query_unique.xml index 502a7e08c2..dde52cf5fb 100644 --- a/man/sd_journal_query_unique.xml +++ b/man/sd_journal_query_unique.xml @@ -158,7 +158,7 @@ sd_journal_restart_unique() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-journal + libsystemd-journal pkg-config1 file. diff --git a/man/sd_journal_seek_head.xml b/man/sd_journal_seek_head.xml index d24b2f30ee..9cf9dd07a8 100644 --- a/man/sd_journal_seek_head.xml +++ b/man/sd_journal_seek_head.xml @@ -101,13 +101,15 @@ sd_journal_seek_monotonic_usec() seeks to the entry with the specified monotonic - timestamp, i.e. CLOCK_MONOTONIC. Since monotonic time - restarts on every reboot a boot ID needs to be - specified as well. + timestamp, + i.e. CLOCK_MONOTONIC. Since + monotonic time restarts on every reboot a boot ID + needs to be specified as well. sd_journal_seek_realtime_usec() seeks to the entry with the specified realtime - (wallclock) timestamp, i.e. CLOCK_REALTIME. Note that + (wallclock) timestamp, + i.e. CLOCK_REALTIME. Note that the realtime clock is not necessarily monotonic. If a realtime timestamp is ambiguous it is not defined which position is sought to. @@ -156,7 +158,7 @@ and sd_journal_seek_cursor() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-journal + libsystemd-journal pkg-config1 file. diff --git a/man/sd_journal_stream_fd.xml b/man/sd_journal_stream_fd.xml index 4407296b40..ec42e8cb1b 100644 --- a/man/sd_journal_stream_fd.xml +++ b/man/sd_journal_stream_fd.xml @@ -79,19 +79,19 @@ systemd.journal-fields7 for more information). The second argument shall be the default priority level for all messages. The - priority level is one of LOG_EMERG, - LOG_ALERT, - LOG_CRIT, - LOG_ERR, - LOG_WARNING, - LOG_NOTICE, - LOG_INFO, - LOG_DEBUG, as defined in + priority level is one of LOG_EMERG, + LOG_ALERT, + LOG_CRIT, + LOG_ERR, + LOG_WARNING, + LOG_NOTICE, + LOG_INFO, + LOG_DEBUG, as defined in syslog.h, see syslog3 for details. The third argument is a boolean: if true kernel-style log priority level prefixes (such as - SD_WARNING) are interpreted, see + SD_WARNING) are interpreted, see sd-daemon3 for more information. @@ -114,7 +114,7 @@ The sd_journal_stream_fd() interface is available as shared library, which can be compiled and linked to with the - libsystemd-journal + libsystemd-journal pkg-config1 file. diff --git a/man/sd_listen_fds.xml b/man/sd_listen_fds.xml index 9c8fdbccaf..9d9f4d0d76 100644 --- a/man/sd_listen_fds.xml +++ b/man/sd_listen_fds.xml @@ -151,7 +151,7 @@ sd-daemon.h files. These interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-daemon + libsystemd-daemon pkg-config1 file. Alternatively, applications consuming these APIs may copy the implementation into their source diff --git a/man/sd_login_monitor_new.xml b/man/sd_login_monitor_new.xml index 261ef1d9d3..c7650e6ba3 100644 --- a/man/sd_login_monitor_new.xml +++ b/man/sd_login_monitor_new.xml @@ -112,7 +112,7 @@ logins) or machine (to get only notifications when a virtual machine or container is started or stopped). If notifications shall be - generated in all these conditions, NULL may be + generated in all these conditions, NULL may be passed. Note that in the future additional categories may be defined. The second parameter returns a monitor object and needs to be freed with the @@ -154,22 +154,22 @@ sd_login_monitor_get_events() will return the poll() mask to wait for. This function will return a combination of - POLLIN, POLLOUT + POLLIN, POLLOUT and similar to fill into the - .events field of struct - pollfd. + .events field of struct + pollfd. sd_login_monitor_get_timeout() will return a timeout value for usage in poll(). This returns a value in - microseconds since the epoch of CLOCK_MONOTONIC for - timing out poll() in - timeout_usec. See + microseconds since the epoch of CLOCK_MONOTONIC + for timing out poll() in + timeout_usec. See clock_gettime2 for details about - CLOCK_MONOTONIC. If there's no + CLOCK_MONOTONIC. If there's no timeout to wait for this will fill in - (uint64_t) -1 instead. Note that + (uint64_t) -1 instead. Note that poll() takes a relative timeout in milliseconds rather than an absolute timeout in microseconds. To convert the absolute 'us' timeout into @@ -189,7 +189,7 @@ else { } The code above does not do any error checking - for brevity's sake. The calculated msec + for brevity's sake. The calculated msec integer can be passed directly as poll()'s timeout parameter. @@ -206,13 +206,13 @@ else { sd_login_monitor_get_fd() returns a Unix file descriptor. On success sd_login_monitor_get_events() - returns a combination of POLLIN, - POLLOUT and suchlike. On failure, + returns a combination of POLLIN, + POLLOUT and suchlike. On failure, these calls return a negative errno-style error code. sd_login_monitor_unref() - always returns NULL. + always returns NULL. @@ -226,7 +226,7 @@ else { sd_login_monitor_get_timeout() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-login + libsystemd-login pkg-config1 file. diff --git a/man/sd_notify.xml b/man/sd_notify.xml index 81f74aa843..52614a2071 100644 --- a/man/sd_notify.xml +++ b/man/sd_notify.xml @@ -217,7 +217,7 @@ Internally, these functions send a single datagram with the state string as payload to the - AF_UNIX socket referenced in the + AF_UNIX socket referenced in the $NOTIFY_SOCKET environment variable. If the first character of $NOTIFY_SOCKET is @ the string is @@ -238,7 +238,7 @@ sd-daemon.h files. These interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-daemon + libsystemd-daemon pkg-config1 file. Alternatively, applications consuming these APIs may copy the implementation into their source tree. For diff --git a/man/sd_pid_get_session.xml b/man/sd_pid_get_session.xml index 543a5c0c72..b45c9a5526 100644 --- a/man/sd_pid_get_session.xml +++ b/man/sd_pid_get_session.xml @@ -146,7 +146,7 @@ free3 call after use. - If the pid parameter of any + If the pid parameter of any of these functions is passed as 0 the operation is executed for the calling process. @@ -169,7 +169,7 @@ sd_pid_get_machine_name() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-login + libsystemd-login pkg-config1 file. diff --git a/man/sd_seat_get_active.xml b/man/sd_seat_get_active.xml index 07e018de13..3060ec7d52 100644 --- a/man/sd_seat_get_active.xml +++ b/man/sd_seat_get_active.xml @@ -101,18 +101,18 @@ sd_seat_get_sessions() may be used to determine all sessions on the specified - seat. Returns two arrays, one (NULL terminated) with + seat. Returns two arrays, one (NULL terminated) with the session identifiers of the sessions and one with the user identifiers of the Unix users the sessions belong to. An additional parameter may be used to return the number of entries in the latter array. The two arrays and the latter parameter may be passed as - NULL in case these values need not to be + NULL in case these values need not to be determined. The arrays and the strings referenced by them need to be freed with the libc free3 call after use. Note that instead of an empty array - NULL may be returned and should be considered + NULL may be returned and should be considered equivalent to an empty array. sd_seat_can_multi_session() @@ -130,10 +130,11 @@ graphics functionality, i.e. is useful as a graphics display. - If the seat parameter of any - of these functions is passed as NULL the operation is - executed for the seat of the session of the calling - process, if there is any. + If the seat parameter of any + of these functions is passed as + NULL the operation is executed + for the seat of the session of the calling process, if + there is any. @@ -162,7 +163,7 @@ sd_seat_can_grapical() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-login + libsystemd-login pkg-config1 file. diff --git a/man/sd_session_is_active.xml b/man/sd_session_is_active.xml index 6fa803bfa2..0146fb427b 100644 --- a/man/sd_session_is_active.xml +++ b/man/sd_session_is_active.xml @@ -202,10 +202,11 @@ free3 call after use. - If the session parameter of - any of these functions is passed as NULL the operation - is executed for the session the calling process is a - member of, if there is any. + If the session parameter of + any of these functions is passed as + NULL the operation is executed + for the session the calling process is a member of, if + there is any. @@ -240,7 +241,7 @@ sd_session_get_tty() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-login + libsystemd-login pkg-config1 file. diff --git a/man/sd_uid_get_state.xml b/man/sd_uid_get_state.xml index cc8fc0f5b6..9a20b5453c 100644 --- a/man/sd_uid_get_state.xml +++ b/man/sd_uid_get_state.xml @@ -127,15 +127,15 @@ currently active (> 0), where the user is currently online but possibly inactive (= 0), or logged in at all but possibly closing the session (< 0). The call returns a - NULL terminated string array of session identifiers in + NULL terminated string array of session identifiers in sessions which needs to be freed by the caller with the libc free3 call after use, including all the strings referenced. If the string array parameter is passed as - NULL the array will not be filled in, but the return + NULL the array will not be filled in, but the return code still indicates the number of current - sessions. Note that instead of an empty array NULL may + sessions. Note that instead of an empty array NULL may be returned and should be considered equivalent to an empty array. @@ -172,7 +172,7 @@ sd_uid_get_sessions(), and sd_uid_get_seats() interfaces are available as shared library, which can be compiled and - linked to with the libsystemd-login + linked to with the libsystemd-login pkg-config1 file. diff --git a/man/systemd-journald.service.xml b/man/systemd-journald.service.xml index 822f3c28f0..2860ae9769 100644 --- a/man/systemd-journald.service.xml +++ b/man/systemd-journald.service.xml @@ -87,8 +87,8 @@ the data. systemd-journald will - forward all received log messages to the AF_UNIX - SOCK_DGRAM socket + forward all received log messages to the AF_UNIX + SOCK_DGRAM socket /run/systemd/journal/syslog (if it exists) which may be used by UNIX syslog daemons to process the data further. diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 8d5948ab07..2ccc470e26 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -721,9 +721,9 @@ separated list of capability names as read by cap_from_name3, - e.g. CAP_SYS_ADMIN - CAP_DAC_OVERRIDE - CAP_SYS_PTRACE. + e.g. CAP_SYS_ADMIN, + CAP_DAC_OVERRIDE, + CAP_SYS_PTRACE. Capabilities listed will be included in the bounding set, all others are removed. If the list of capabilities @@ -1217,7 +1217,8 @@ system calls executed by the unit process except for the listed ones will result in immediate process - termination with the SIGSYS signal + termination with the + SIGSYS signal (whitelisting). If the first character of the list is ~ the effect is inverted: only the diff --git a/man/systemd.journal-fields.xml b/man/systemd.journal-fields.xml index de01dc236b..fe65078f76 100644 --- a/man/systemd.journal-fields.xml +++ b/man/systemd.journal-fields.xml @@ -100,9 +100,9 @@ enforced, and formatted differently. Developers can generate a new ID for this - purpose with - journalctl - --new-id. + purpose with journalctl + . + @@ -474,8 +474,8 @@ describes the position of an entry in the journal and is portable across machines, - platforms and journal - files. + platforms and journal files. + @@ -483,16 +483,17 @@ __REALTIME_TIMESTAMP= The wallclock time - (CLOCK_REALTIME) at the point - in time the entry was received - by the journal, in usec since - the epoch UTC formatted as - decimal string. This has - different properties from + (CLOCK_REALTIME) + at the point in time the entry + was received by the journal, + in usec since the epoch UTC + formatted as decimal + string. This has different + properties from _SOURCE_REALTIME_TIMESTAMP= as it is usually a bit later - but more likely to be - monotonic. + but more likely to be monotonic. + @@ -500,15 +501,15 @@ __MONOTONIC_TIMESTAMP= The monotonic time - (CLOCK_MONOTONIC) at the point - in time the entry was received - by the journal in usec - formatted as decimal + (CLOCK_MONOTONIC) + at the point in time the entry + was received by the journal in + usec formatted as decimal string. To be useful as an address for the entry this should be combined with with - boot ID in - _BOOT_ID=. + boot ID in _BOOT_ID=. + diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml index 040305c632..0d5652b834 100644 --- a/man/systemd.socket.xml +++ b/man/systemd.socket.xml @@ -150,19 +150,19 @@ ListenSequentialPacket= Specifies an address to listen on for a stream - (SOCK_STREAM), datagram (SOCK_DGRAM), + (SOCK_STREAM), datagram (SOCK_DGRAM), or sequential packet - (SOCK_SEQPACKET) socket, respectively. The address + (SOCK_SEQPACKET) socket, respectively. The address can be written in various formats: If the address starts with a slash (/), it is read as file system - socket in the AF_UNIX socket + socket in the AF_UNIX socket family. If the address starts with an at symbol (@) it is read as abstract - namespace socket in the AF_UNIX + namespace socket in the AF_UNIX family. The @ is replaced with a NUL character before binding. For details see @@ -193,13 +193,13 @@ setting (see below). - Note that SOCK_SEQPACKET + Note that SOCK_SEQPACKET (i.e. ListenSequentialPacket=) - is only available for AF_UNIX - sockets. SOCK_STREAM + is only available for AF_UNIX + sockets. SOCK_STREAM (i.e. ListenStream=) when used for IP sockets refers to TCP - sockets, SOCK_DGRAM + sockets, SOCK_DGRAM (i.e. ListenDatagram=) to UDP. @@ -258,7 +258,7 @@ Specifies a Netlink family to create a socket for to listen on. This expects a short string - referring to the AF_NETLINK family + referring to the AF_NETLINK family name (such as audit or kobject-uevent) as argument, optionally suffixed by a @@ -382,7 +382,7 @@ to write new daemons only in a way that is suitable for . A - daemon listening on an AF_UNIX socket + daemon listening on an AF_UNIX socket may, but does not need to, call close2 on the received socket before @@ -584,7 +584,7 @@ PassCredentials= Takes a boolean value. This controls the SO_PASSCRED - socket option, which allows AF_UNIX sockets to + socket option, which allows AF_UNIX sockets to receive the credentials of the sending process in an ancillary message. Defaults to @@ -595,7 +595,7 @@ PassSecurity= Takes a boolean value. This controls the SO_PASSSEC - socket option, which allows AF_UNIX + socket option, which allows AF_UNIX sockets to receive the security context of the sending process in an ancillary message. Defaults to diff --git a/man/systemd.xml b/man/systemd.xml index 497dd2bfee..ef95641387 100644 --- a/man/systemd.xml +++ b/man/systemd.xml @@ -611,7 +611,7 @@ - SIGTERM + SIGTERM Upon receiving this signal the systemd system manager @@ -631,7 +631,7 @@ - SIGINT + SIGINT Upon receiving this signal the systemd system manager will @@ -647,7 +647,7 @@ - SIGWINCH + SIGWINCH When this signal is received the systemd system manager @@ -663,7 +663,7 @@ - SIGPWR + SIGPWR When this signal is received the systemd manager @@ -675,7 +675,7 @@ - SIGUSR1 + SIGUSR1 When this signal is received the systemd manager will try @@ -684,7 +684,7 @@ - SIGUSR2 + SIGUSR2 When this signal is received the systemd manager will log @@ -695,7 +695,7 @@ - SIGHUP + SIGHUP Reloads the complete daemon configuration. This is mostly @@ -704,7 +704,7 @@ - SIGRTMIN+0 + SIGRTMIN+0 Enters default mode, starts the default.target @@ -714,7 +714,7 @@ - SIGRTMIN+1 + SIGRTMIN+1 Enters rescue mode, starts the @@ -725,7 +725,7 @@ - SIGRTMIN+2 + SIGRTMIN+2 Enters emergency mode, starts the @@ -736,7 +736,7 @@ - SIGRTMIN+3 + SIGRTMIN+3 Halts the machine, starts the @@ -747,7 +747,7 @@ - SIGRTMIN+4 + SIGRTMIN+4 Powers off the machine, starts the @@ -758,7 +758,7 @@ - SIGRTMIN+5 + SIGRTMIN+5 Reboots the machine, starts the @@ -769,7 +769,7 @@ - SIGRTMIN+6 + SIGRTMIN+6 Reboots the machine via kexec, starts the @@ -780,31 +780,31 @@ - SIGRTMIN+13 + SIGRTMIN+13 Immediately halts the machine. - SIGRTMIN+14 + SIGRTMIN+14 Immediately powers off the machine. - SIGRTMIN+15 + SIGRTMIN+15 Immediately reboots the machine. - SIGRTMIN+16 + SIGRTMIN+16 Immediately reboots the machine with kexec. - SIGRTMIN+20 + SIGRTMIN+20 Enables display of status messages on the console, as @@ -815,7 +815,7 @@ - SIGRTMIN+21 + SIGRTMIN+21 Disables display of status messages on the console, as @@ -826,23 +826,23 @@ - SIGRTMIN+22 - SIGRTMIN+23 + SIGRTMIN+22 + SIGRTMIN+23 Sets the log level to debug (or info on - SIGRTMIN+23), as + SIGRTMIN+23), as controlled via systemd.log_level=debug (or systemd.log_level=info - on SIGRTMIN+23) on + on SIGRTMIN+23) on the kernel command line. - SIGRTMIN+24 + SIGRTMIN+24 Immediately exits the manager (only available for --user @@ -850,28 +850,28 @@ - SIGRTMIN+26 - SIGRTMIN+27 - SIGRTMIN+28 - SIGRTMIN+29 + SIGRTMIN+26 + SIGRTMIN+27 + SIGRTMIN+28 + SIGRTMIN+29 Sets the log level to journal-or-kmsg (or console on - SIGRTMIN+27, + SIGRTMIN+27, kmsg on - SIGRTMIN+28, + SIGRTMIN+28, or syslog-or-kmsg - on SIGRTMIN+29), as + on SIGRTMIN+29), as controlled via systemd.log_target=journal-or-kmsg (or systemd.log_target=console - on SIGRTMIN+27, + on SIGRTMIN+27, systemd.log_target=kmsg - on SIGRTMIN+28, + on SIGRTMIN+28, or systemd.log_target=syslog-or-kmsg - on SIGRTMIN+29) on + on SIGRTMIN+29) on the kernel command line. @@ -1044,7 +1044,7 @@ argument. If positive systemd activates the specified virtual terminal when it crashes. Defaults to - -1. + -1. @@ -1223,7 +1223,7 @@ Daemon status notification socket. This is an - AF_UNIX datagram socket and is used to + AF_UNIX datagram socket and is used to implement the daemon notification logic as implemented by sd_notify3. @@ -1236,7 +1236,7 @@ Used internally by the shutdown8 tool to implement delayed - shutdowns. This is an AF_UNIX datagram + shutdowns. This is an AF_UNIX datagram socket. @@ -1247,7 +1247,7 @@ communication channel between systemctl1 and the systemd process. This is an - AF_UNIX stream socket. This interface + AF_UNIX stream socket. This interface is private to systemd and should not be used in external projects. -- cgit v1.2.1 From 785a51eb682136b2c7ee33fabe64c72d20fa37db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 26 Jun 2013 19:48:19 -0400 Subject: man: add CONSTANTS section to systemd.directives(7) --- make-directive-index.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/make-directive-index.py b/make-directive-index.py index 468d14da75..b43fea0b99 100755 --- a/make-directive-index.py +++ b/make-directive-index.py @@ -138,6 +138,14 @@ TEMPLATE = '''\ + + Constants + + Various constant used and/or defined by systemd. + + + + Miscellaneous options and directives @@ -222,6 +230,16 @@ def _extract_directives(directive_groups, formatting, page): storfile[text].append((pagename, section)) formatting[text] = name + storfile = directive_groups['constants'] + for name in t.iterfind('.//constant'): + if name.attrib.get('noindex'): + continue + name.tail = '' + if name.text.startswith('('): # a cast, strip it + name.text = name.text.partition(' ')[2] + storfile[name.text].append((pagename, section)) + formatting[name.text] = name + def _make_section(template, name, directives, formatting): varlist = template.find(".//*[@id='{}']".format(name)) for varname, manpages in sorted(directives.items()): -- cgit v1.2.1 From 7ac4fa7e92c782f2978260023cff64aa683e6011 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 26 Jun 2013 19:48:24 -0400 Subject: journalctl: highlight MESSAGE= in verbose output When looking at verbose output, additional "work" is required to pick out the interesting MESSAGE= lines from all the fields. Also, show long fields in full in verbose output mode when OUTPUT_FULL_WIDTH is specified. --- src/shared/logs-show.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index 91b2bec159..8dc11bb7fd 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -357,6 +357,8 @@ static int output_verbose( JOURNAL_FOREACH_DATA_RETVAL(j, data, length, r) { const char *c; int fieldlen; + const char *on = "", *off = ""; + c = memchr(data, '=', length); if (!c) { log_error("Invalid field."); @@ -364,16 +366,25 @@ static int output_verbose( } fieldlen = c - (const char*) data; - if ((flags & OUTPUT_SHOW_ALL) || (length < PRINT_THRESHOLD && utf8_is_printable(data, length))) { - fprintf(f, " %.*s=", fieldlen, (const char*)data); + if (flags & OUTPUT_COLOR && startswith(data, "MESSAGE=")) { + on = ANSI_HIGHLIGHT_ON; + off = ANSI_HIGHLIGHT_OFF; + } + + if (flags & OUTPUT_SHOW_ALL || + (((length < PRINT_THRESHOLD) || flags & OUTPUT_FULL_WIDTH) && utf8_is_printable(data, length))) { + fprintf(f, " %s%.*s=", on, fieldlen, (const char*)data); print_multiline(f, 4 + fieldlen + 1, 0, OUTPUT_FULL_WIDTH, 0, c + 1, length - fieldlen - 1); + fputs(off, f); } else { char bytes[FORMAT_BYTES_MAX]; - fprintf(f, " %.*s=[%s blob data]\n", + fprintf(f, " %s%.*s=[%s blob data]%s\n", + on, (int) (c - (const char*) data), (const char*) data, - format_bytes(bytes, sizeof(bytes), length - (c - (const char *) data) - 1)); + format_bytes(bytes, sizeof(bytes), length - (c - (const char *) data) - 1), + off); } } -- cgit v1.2.1 From 5841bd803f1b651c0d70c6ae114630723a76d1da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 26 Jun 2013 19:48:32 -0400 Subject: killall: do not use alloca() in argument list It is not allowed. --- src/core/killall.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/killall.c b/src/core/killall.c index a0f57455fb..e395050107 100644 --- a/src/core/killall.c +++ b/src/core/killall.c @@ -33,7 +33,7 @@ static bool ignore_proc(pid_t pid) { _cleanup_fclose_ FILE *f = NULL; - char c; + char c, *p; size_t count; uid_t uid; int r; @@ -50,7 +50,8 @@ static bool ignore_proc(pid_t pid) { if (uid != 0) return false; - f = fopen(procfs_file_alloca(pid, "cmdline"), "re"); + p = procfs_file_alloca(pid, "cmdline"); + f = fopen(p, "re"); if (!f) return true; /* not really, but has the desired effect */ -- cgit v1.2.1 From abb26902e424c4142b68ead35676028b12249b77 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 27 Jun 2013 02:28:12 +0200 Subject: core: don't do runaway fork()s if we hit a segfault from our segfault handler --- src/core/main.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index 470fecf15d..c123de91ce 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -106,7 +106,10 @@ static void nop_handler(int sig) { _noreturn_ static void crash(int sig) { - if (!arg_dump_core) + if (getpid() != 1) + /* Pass this on immediately, if this is not PID 1 */ + raise(sig); + else if (!arg_dump_core) log_error("Caught <%s>, not dumping core.", signal_to_string(sig)); else { struct sigaction sa = { @@ -116,7 +119,7 @@ _noreturn_ static void crash(int sig) { pid_t pid; /* We want to wait for the core process, hence let's enable SIGCHLD */ - assert_se(sigaction(SIGCHLD, &sa, NULL) == 0); + sigaction(SIGCHLD, &sa, NULL); pid = fork(); if (pid < 0) @@ -128,7 +131,7 @@ _noreturn_ static void crash(int sig) { /* Enable default signal handler for core dump */ zero(sa); sa.sa_handler = SIG_DFL; - assert_se(sigaction(sig, &sa, NULL) == 0); + sigaction(sig, &sa, NULL); /* Don't limit the core dump size */ rl.rlim_cur = RLIM_INFINITY; @@ -136,7 +139,7 @@ _noreturn_ static void crash(int sig) { setrlimit(RLIMIT_CORE, &rl); /* Just to be sure... */ - assert_se(chdir("/") == 0); + chdir("/"); /* Raise the signal again */ raise(sig); -- cgit v1.2.1 From 4ad490007b70e6ac18d3cb04fa2ed92eba1451fa Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 27 Jun 2013 04:14:27 +0200 Subject: core: general cgroup rework Replace the very generic cgroup hookup with a much simpler one. With this change only the high-level cgroup settings remain, the ability to set arbitrary cgroup attributes is removed, so is support for adding units to arbitrary cgroup controllers or setting arbitrary paths for them (especially paths that are different for the various controllers). This also introduces a new -.slice root slice, that is the parent of system.slice and friends. This enables easy admin configuration of root-level cgrouo properties. This replaces DeviceDeny= by DevicePolicy=, and implicitly adds in /dev/null, /dev/zero and friends if DeviceAllow= is used (unless this is turned off by DevicePolicy=). --- Makefile.am | 19 +- TODO | 18 +- src/core/cgroup-attr.c | 132 ------ src/core/cgroup-attr.h | 50 -- src/core/cgroup-semantics.c | 333 -------------- src/core/cgroup-semantics.h | 43 -- src/core/cgroup.c | 831 +++++++++++++++++++--------------- src/core/cgroup.h | 116 +++-- src/core/dbus-cgroup.c | 139 ++++++ src/core/dbus-cgroup.h | 44 ++ src/core/dbus-execute.c | 32 +- src/core/dbus-execute.h | 16 - src/core/dbus-manager.c | 148 +----- src/core/dbus-mount.c | 16 +- src/core/dbus-service.c | 6 +- src/core/dbus-slice.c | 10 +- src/core/dbus-socket.c | 14 +- src/core/dbus-swap.c | 14 +- src/core/dbus-unit.c | 530 +--------------------- src/core/dbus-unit.h | 28 +- src/core/dbus.c | 5 +- src/core/execute.c | 70 +-- src/core/execute.h | 17 +- src/core/load-fragment-gperf.gperf.m4 | 25 +- src/core/load-fragment.c | 435 +++++++++++------- src/core/load-fragment.h | 9 +- src/core/main.c | 6 - src/core/manager.c | 38 +- src/core/manager.h | 10 +- src/core/mount.c | 44 +- src/core/mount.h | 4 + src/core/service.c | 61 ++- src/core/service.h | 1 + src/core/slice.c | 79 ++-- src/core/slice.h | 2 + src/core/socket.c | 17 +- src/core/socket.h | 1 + src/core/special.h | 1 + src/core/swap.c | 17 +- src/core/swap.h | 1 + src/core/unit.c | 404 ++--------------- src/core/unit.h | 29 +- src/login/logind-machine.c | 2 +- src/login/logind-session.c | 4 +- src/login/logind-user.c | 4 +- src/shared/cgroup-label.c | 11 +- src/shared/cgroup-show.c | 1 - src/shared/cgroup-util.c | 269 ++++++----- src/shared/cgroup-util.h | 24 +- src/shared/fileio.c | 1 - src/shared/mkdir.c | 74 +-- src/shared/mkdir.h | 8 + src/systemctl/systemctl.c | 209 ++------- src/test/test-cgroup.c | 8 +- units/-.slice | 12 + units/slices.target | 4 +- units/system.slice | 2 + 57 files changed, 1644 insertions(+), 2804 deletions(-) delete mode 100644 src/core/cgroup-attr.c delete mode 100644 src/core/cgroup-attr.h delete mode 100644 src/core/cgroup-semantics.c delete mode 100644 src/core/cgroup-semantics.h create mode 100644 src/core/dbus-cgroup.c create mode 100644 src/core/dbus-cgroup.h create mode 100644 units/-.slice diff --git a/Makefile.am b/Makefile.am index 016d7dad32..12254e39a8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -379,6 +379,7 @@ dist_systemunit_DATA = \ units/swap.target \ units/slices.target \ units/system.slice \ + units/-.slice \ units/systemd-initctl.socket \ units/systemd-shutdownd.socket \ units/syslog.socket \ @@ -880,14 +881,16 @@ libsystemd_core_la_SOURCES = \ src/core/dbus-snapshot.h \ src/core/dbus-device.c \ src/core/dbus-device.h \ - src/core/dbus-execute.c \ - src/core/dbus-execute.h \ - src/core/dbus-kill.c \ - src/core/dbus-kill.h \ src/core/dbus-path.c \ src/core/dbus-path.h \ src/core/dbus-slice.c \ src/core/dbus-slice.h \ + src/core/dbus-execute.c \ + src/core/dbus-execute.h \ + src/core/dbus-kill.c \ + src/core/dbus-kill.h \ + src/core/dbus-cgroup.c \ + src/core/dbus-cgroup.h \ src/core/cgroup.c \ src/core/cgroup.h \ src/core/selinux-access.c \ @@ -914,10 +917,6 @@ libsystemd_core_la_SOURCES = \ src/core/namespace.h \ src/core/tcpwrap.c \ src/core/tcpwrap.h \ - src/core/cgroup-attr.c \ - src/core/cgroup-attr.h \ - src/core/cgroup-semantics.c \ - src/core/cgroup-semantics.h \ src/core/securebits.h \ src/core/initreq.h \ src/core/special.h \ @@ -1137,6 +1136,10 @@ test_ns_SOURCES = \ test_ns_LDADD = \ libsystemd-core.la +test_ns_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + test_loopback_SOURCES = \ src/test/test-loopback.c diff --git a/TODO b/TODO index caba4e39eb..a61fa92b68 100644 --- a/TODO +++ b/TODO @@ -28,11 +28,17 @@ Fedora 19: Features: -* journald: make sure ratelimit is actually really per-service with the new cgroup changes +* split out CreateMachine into systemd-machined + +* "transient" units, i.e units that are not sourced from disk but + created only transiently via bus calls -* when creating a session or machine, automatically move the process into the root cgroup for all other hierarchies +* introduce new Scope unit type then make logind's session and machine + registration use this to set up cgroups -* maybe reintroduce nspawn -C? +* should Slice= be part of [Unit] or of [Service]? + +* journald: make sure ratelimit is actually really per-service with the new cgroup changes * move systemctl dump to systemd-analyze @@ -49,12 +55,6 @@ Features: * when a service changes state make reflect that in the RUNNING/LISTENING states of its socket -* slices: - - add option to pam_systemd to move login session into a slice (?) - - remove ControlGroup= setting - - in sd_pid_get_owner_uid() fallback to query session file - - add api to determine slice of unit - * when recursively showing the cgroup hierarchy, optionally also show the hierarchies of child processes diff --git a/src/core/cgroup-attr.c b/src/core/cgroup-attr.c deleted file mode 100644 index 7e3e08eabb..0000000000 --- a/src/core/cgroup-attr.c +++ /dev/null @@ -1,132 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2011 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see . -***/ - -#include "cgroup-attr.h" -#include "cgroup-util.h" -#include "list.h" -#include "fileio.h" - -int cgroup_attribute_apply(CGroupAttribute *a, CGroupBonding *b) { - _cleanup_free_ char *path = NULL, *v = NULL; - int r; - - assert(a); - - b = cgroup_bonding_find_list(b, a->controller); - if (!b) - return 0; - - if (a->semantics && a->semantics->map_write) { - r = a->semantics->map_write(a->semantics, a->value, &v); - if (r < 0) - return r; - } - - r = cg_get_path(a->controller, b->path, a->name, &path); - if (r < 0) - return r; - - r = write_string_file(path, v ? v : a->value); - if (r < 0) - log_warning("Failed to write '%s' to %s: %s", v ? v : a->value, path, strerror(-r)); - - return r; -} - -int cgroup_attribute_apply_list(CGroupAttribute *first, CGroupBonding *b) { - CGroupAttribute *a; - int r = 0; - - LIST_FOREACH(by_unit, a, first) { - int k; - - k = cgroup_attribute_apply(a, b); - if (r == 0) - r = k; - } - - return r; -} - -bool cgroup_attribute_matches(CGroupAttribute *a, const char *controller, const char *name) { - assert(a); - - if (controller) { - if (streq(a->controller, controller) && (!name || streq(a->name, name))) - return true; - - } else if (!name) - return true; - else if (streq(a->name, name)) { - size_t x, y; - x = strlen(a->controller); - y = strlen(name); - - if (y > x && - memcmp(a->controller, name, x) == 0 && - name[x] == '.') - return true; - } - - return false; -} - -CGroupAttribute *cgroup_attribute_find_list( - CGroupAttribute *first, - const char *controller, - const char *name) { - CGroupAttribute *a; - - assert(name); - - LIST_FOREACH(by_unit, a, first) - if (cgroup_attribute_matches(a, controller, name)) - return a; - - return NULL; -} - -void cgroup_attribute_free(CGroupAttribute *a) { - assert(a); - - if (a->unit) - LIST_REMOVE(CGroupAttribute, by_unit, a->unit->cgroup_attributes, a); - - free(a->controller); - free(a->name); - free(a->value); - free(a); -} - -void cgroup_attribute_free_list(CGroupAttribute *first) { - CGroupAttribute *a, *n; - - LIST_FOREACH_SAFE(by_unit, a, n, first) - cgroup_attribute_free(a); -} - -void cgroup_attribute_free_some(CGroupAttribute *first, const char *controller, const char *name) { - CGroupAttribute *a, *n; - - LIST_FOREACH_SAFE(by_unit, a, n, first) - if (cgroup_attribute_matches(a, controller, name)) - cgroup_attribute_free(a); -} diff --git a/src/core/cgroup-attr.h b/src/core/cgroup-attr.h deleted file mode 100644 index 3a13b7c92d..0000000000 --- a/src/core/cgroup-attr.h +++ /dev/null @@ -1,50 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -#pragma once - -/*** - This file is part of systemd. - - Copyright 2011 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see . -***/ - -typedef struct CGroupAttribute CGroupAttribute; - -#include "unit.h" -#include "cgroup.h" -#include "cgroup-semantics.h" - -struct CGroupAttribute { - char *controller; - char *name; - char *value; - - Unit *unit; - - const CGroupSemantics *semantics; - - LIST_FIELDS(CGroupAttribute, by_unit); -}; - -int cgroup_attribute_apply(CGroupAttribute *a, CGroupBonding *b); -int cgroup_attribute_apply_list(CGroupAttribute *first, CGroupBonding *b); - -bool cgroup_attribute_matches(CGroupAttribute *a, const char *controller, const char *name) _pure_; -CGroupAttribute *cgroup_attribute_find_list(CGroupAttribute *first, const char *controller, const char *name) _pure_; - -void cgroup_attribute_free(CGroupAttribute *a); -void cgroup_attribute_free_list(CGroupAttribute *first); -void cgroup_attribute_free_some(CGroupAttribute *first, const char *controller, const char *name); diff --git a/src/core/cgroup-semantics.c b/src/core/cgroup-semantics.c deleted file mode 100644 index 7df9d014e9..0000000000 --- a/src/core/cgroup-semantics.c +++ /dev/null @@ -1,333 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see . -***/ - -#include "util.h" -#include "strv.h" -#include "path-util.h" -#include "cgroup-util.h" - -#include "cgroup-semantics.h" - -static int parse_cpu_shares(const CGroupSemantics *s, const char *value, char **ret) { - unsigned long ul; - - assert(s); - assert(value); - assert(ret); - - if (safe_atolu(value, &ul) < 0 || ul < 1) - return -EINVAL; - - if (asprintf(ret, "%lu", ul) < 0) - return -ENOMEM; - - return 1; -} - -static int parse_memory_limit(const CGroupSemantics *s, const char *value, char **ret) { - off_t sz; - - assert(s); - assert(value); - assert(ret); - - if (parse_bytes(value, &sz) < 0 || sz <= 0) - return -EINVAL; - - if (asprintf(ret, "%llu", (unsigned long long) sz) < 0) - return -ENOMEM; - - return 1; -} - -static int parse_device(const CGroupSemantics *s, const char *value, char **ret) { - _cleanup_strv_free_ char **l = NULL; - char *x; - unsigned k; - - assert(s); - assert(value); - assert(ret); - - l = strv_split_quoted(value); - if (!l) - return -ENOMEM; - - k = strv_length(l); - if (k < 1 || k > 2) - return -EINVAL; - - if (!streq(l[0], "*") && !path_startswith(l[0], "/dev")) - return -EINVAL; - - if (!isempty(l[1]) && !in_charset(l[1], "rwm")) - return -EINVAL; - - x = strdup(value); - if (!x) - return -ENOMEM; - - *ret = x; - return 1; -} - -static int parse_blkio_weight(const CGroupSemantics *s, const char *value, char **ret) { - _cleanup_strv_free_ char **l = NULL; - unsigned long ul; - - assert(s); - assert(value); - assert(ret); - - l = strv_split_quoted(value); - if (!l) - return -ENOMEM; - - if (strv_length(l) != 1) - return 0; /* Returning 0 will cause parse_blkio_weight_device() be tried instead */ - - if (safe_atolu(l[0], &ul) < 0 || ul < 10 || ul > 1000) - return -EINVAL; - - if (asprintf(ret, "%lu", ul) < 0) - return -ENOMEM; - - return 1; -} - -static int parse_blkio_weight_device(const CGroupSemantics *s, const char *value, char **ret) { - _cleanup_strv_free_ char **l = NULL; - unsigned long ul; - - assert(s); - assert(value); - assert(ret); - - l = strv_split_quoted(value); - if (!l) - return -ENOMEM; - - if (strv_length(l) != 2) - return -EINVAL; - - if (!path_startswith(l[0], "/dev")) - return -EINVAL; - - if (safe_atolu(l[1], &ul) < 0 || ul < 10 || ul > 1000) - return -EINVAL; - - if (asprintf(ret, "%s %lu", l[0], ul) < 0) - return -ENOMEM; - - return 1; -} - -static int parse_blkio_bandwidth(const CGroupSemantics *s, const char *value, char **ret) { - _cleanup_strv_free_ char **l = NULL; - off_t bytes; - - assert(s); - assert(value); - assert(ret); - - l = strv_split_quoted(value); - if (!l) - return -ENOMEM; - - if (strv_length(l) != 2) - return -EINVAL; - - if (!path_startswith(l[0], "/dev")) { - return -EINVAL; - } - - if (parse_bytes(l[1], &bytes) < 0 || bytes <= 0) - return -EINVAL; - - if (asprintf(ret, "%s %llu", l[0], (unsigned long long) bytes) < 0) - return -ENOMEM; - - return 0; -} - -static int map_device(const CGroupSemantics *s, const char *value, char **ret) { - _cleanup_strv_free_ char **l = NULL; - unsigned k; - - assert(s); - assert(value); - assert(ret); - - l = strv_split_quoted(value); - if (!l) - return -ENOMEM; - - k = strv_length(l); - if (k < 1 || k > 2) - return -EINVAL; - - if (streq(l[0], "*")) { - - if (asprintf(ret, "a *:*%s%s", - isempty(l[1]) ? "" : " ", strempty(l[1])) < 0) - return -ENOMEM; - } else { - struct stat st; - - if (stat(l[0], &st) < 0) { - log_warning("Couldn't stat device %s", l[0]); - return -errno; - } - - if (!S_ISCHR(st.st_mode) && !S_ISBLK(st.st_mode)) { - log_warning("%s is not a device.", l[0]); - return -ENODEV; - } - - if (asprintf(ret, "%c %u:%u%s%s", - S_ISCHR(st.st_mode) ? 'c' : 'b', - major(st.st_rdev), minor(st.st_rdev), - isempty(l[1]) ? "" : " ", strempty(l[1])) < 0) - return -ENOMEM; - } - - return 0; -} - -static int map_blkio(const CGroupSemantics *s, const char *value, char **ret) { - _cleanup_strv_free_ char **l = NULL; - struct stat st; - dev_t d; - - assert(s); - assert(value); - assert(ret); - - l = strv_split_quoted(value); - if (!l) - return log_oom(); - - if (strv_length(l) != 2) - return -EINVAL; - - if (stat(l[0], &st) < 0) { - log_warning("Couldn't stat device %s", l[0]); - return -errno; - } - - if (S_ISBLK(st.st_mode)) - d = st.st_rdev; - else if (major(st.st_dev) != 0) { - /* If this is not a device node then find the block - * device this file is stored on */ - d = st.st_dev; - - /* If this is a partition, try to get the originating - * block device */ - block_get_whole_disk(d, &d); - } else { - log_warning("%s is not a block device and file system block device cannot be determined or is not local.", l[0]); - return -ENODEV; - } - - if (asprintf(ret, "%u:%u %s", major(d), minor(d), l[1]) < 0) - return -ENOMEM; - - return 0; -} - -static const CGroupSemantics semantics[] = { - { "cpu", "cpu.shares", "CPUShares", false, parse_cpu_shares, NULL, NULL }, - { "memory", "memory.soft_limit_in_bytes", "MemorySoftLimit", false, parse_memory_limit, NULL, NULL }, - { "memory", "memory.limit_in_bytes", "MemoryLimit", false, parse_memory_limit, NULL, NULL }, - { "devices", "devices.allow", "DeviceAllow", true, parse_device, map_device, NULL }, - { "devices", "devices.deny", "DeviceDeny", true, parse_device, map_device, NULL }, - { "blkio", "blkio.weight", "BlockIOWeight", false, parse_blkio_weight, NULL, NULL }, - { "blkio", "blkio.weight_device", "BlockIOWeight", true, parse_blkio_weight_device, map_blkio, NULL }, - { "blkio", "blkio.read_bps_device", "BlockIOReadBandwidth", true, parse_blkio_bandwidth, map_blkio, NULL }, - { "blkio", "blkio.write_bps_device", "BlockIOWriteBandwidth", true, parse_blkio_bandwidth, map_blkio, NULL } -}; - -int cgroup_semantics_find( - const char *controller, - const char *name, - const char *value, - char **ret, - const CGroupSemantics **_s) { - - _cleanup_free_ char *c = NULL; - unsigned i; - int r; - - assert(name); - assert(_s); - assert(!value == !ret); - - if (!controller) { - r = cg_controller_from_attr(name, &c); - if (r < 0) - return r; - - controller = c; - } - - for (i = 0; i < ELEMENTSOF(semantics); i++) { - const CGroupSemantics *s = semantics + i; - bool matches_name, matches_pretty; - - if (controller && s->controller && !streq(s->controller, controller)) - continue; - - matches_name = s->name && streq(s->name, name); - matches_pretty = s->pretty && streq(s->pretty, name); - - if (!matches_name && !matches_pretty) - continue; - - if (value) { - if (matches_pretty && s->map_pretty) { - - r = s->map_pretty(s, value, ret); - if (r < 0) - return r; - - if (r == 0) - continue; - - } else { - char *x; - - x = strdup(value); - if (!x) - return -ENOMEM; - - *ret = x; - } - } - - *_s = s; - return 1; - } - - *ret = NULL; - *_s = NULL; - return 0; -} diff --git a/src/core/cgroup-semantics.h b/src/core/cgroup-semantics.h deleted file mode 100644 index 4f848f4bb7..0000000000 --- a/src/core/cgroup-semantics.h +++ /dev/null @@ -1,43 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -#pragma once - -/*** - This file is part of systemd. - - Copyright 2011 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see . -***/ - -typedef struct CGroupSemantics CGroupSemantics; - -struct CGroupSemantics { - const char *controller; - const char *name; - const char *pretty; - - bool multiple; - - /* This call is used for parsing the pretty value to the actual attribute value */ - int (*map_pretty)(const CGroupSemantics *semantics, const char *value, char **ret); - - /* Right before writing this attribute the attribute value is converted to a low-level value */ - int (*map_write)(const CGroupSemantics *semantics, const char *value, char **ret); - - /* If this attribute takes a list, this call can be used to reset the list to empty */ - int (*reset)(const CGroupSemantics *semantics, const char *group); -}; - -int cgroup_semantics_find(const char *controller, const char *name, const char *value, char **ret, const CGroupSemantics **semantics); diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 5065329739..79467a82ce 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -3,7 +3,7 @@ /*** This file is part of systemd. - Copyright 2010 Lennart Poettering + Copyright 2013 Lennart Poettering systemd is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -19,305 +19,554 @@ along with systemd; If not, see . ***/ -#include -#include -#include -#include -#include -#include #include -#include "cgroup.h" -#include "cgroup-util.h" -#include "log.h" -#include "strv.h" #include "path-util.h" #include "special.h" +#include "cgroup-util.h" +#include "cgroup.h" -int cgroup_bonding_realize(CGroupBonding *b) { - int r; +void cgroup_context_init(CGroupContext *c) { + assert(c); + + /* Initialize everything to the kernel defaults, assuming the + * structure is preinitialized to 0 */ + + c->cpu_shares = 1024; + c->memory_limit = c->memory_soft_limit = (uint64_t) -1; + c->blockio_weight = 1000; +} +void cgroup_context_free_device_allow(CGroupContext *c, CGroupDeviceAllow *a) { + assert(c); + assert(a); + + LIST_REMOVE(CGroupDeviceAllow, device_allow, c->device_allow, a); + free(a->path); + free(a); +} + +void cgroup_context_free_blockio_device_weight(CGroupContext *c, CGroupBlockIODeviceWeight *w) { + assert(c); + assert(w); + + LIST_REMOVE(CGroupBlockIODeviceWeight, device_weights, c->blockio_device_weights, w); + free(w->path); + free(w); +} + +void cgroup_context_free_blockio_device_bandwidth(CGroupContext *c, CGroupBlockIODeviceBandwidth *b) { + assert(c); assert(b); - assert(b->path); - assert(b->controller); - r = cg_create(b->controller, b->path, NULL); + LIST_REMOVE(CGroupBlockIODeviceBandwidth, device_bandwidths, c->blockio_device_bandwidths, b); + free(b->path); + free(b); +} + +void cgroup_context_done(CGroupContext *c) { + assert(c); + + while (c->blockio_device_weights) + cgroup_context_free_blockio_device_weight(c, c->blockio_device_weights); + + while (c->blockio_device_bandwidths) + cgroup_context_free_blockio_device_bandwidth(c, c->blockio_device_bandwidths); + + while (c->device_allow) + cgroup_context_free_device_allow(c, c->device_allow); +} + +void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) { + CGroupBlockIODeviceBandwidth *b; + CGroupBlockIODeviceWeight *w; + CGroupDeviceAllow *a; + + assert(c); + assert(f); + + prefix = strempty(prefix); + + fprintf(f, + "%sCPUAccounting=%s\n" + "%sBlockIOAccounting=%s\n" + "%sMemoryAccounting=%s\n" + "%sCPUShares=%lu\n" + "%sBlockIOWeight%lu\n" + "%sMemoryLimit=%" PRIu64 "\n" + "%sMemorySoftLimit=%" PRIu64 "\n" + "%sDevicePolicy=%s\n", + prefix, yes_no(c->cpu_accounting), + prefix, yes_no(c->blockio_accounting), + prefix, yes_no(c->memory_accounting), + prefix, c->cpu_shares, + prefix, c->blockio_weight, + prefix, c->memory_limit, + prefix, c->memory_soft_limit, + prefix, cgroup_device_policy_to_string(c->device_policy)); + + LIST_FOREACH(device_allow, a, c->device_allow) + fprintf(f, + "%sDeviceAllow=%s %s%s%s\n", + prefix, + a->path, + a->r ? "r" : "", a->w ? "w" : "", a->m ? "m" : ""); + + LIST_FOREACH(device_weights, w, c->blockio_device_weights) + fprintf(f, + "%sBlockIOWeight=%s %lu", + prefix, + w->path, + w->weight); + + LIST_FOREACH(device_bandwidths, b, c->blockio_device_bandwidths) { + char buf[FORMAT_BYTES_MAX]; + + fprintf(f, + "%s%s=%s %s\n", + prefix, + b->read ? "BlockIOReadBandwidth" : "BlockIOWriteBandwidth", + b->path, + format_bytes(buf, sizeof(buf), b->bandwidth)); + } +} + +static int lookup_blkio_device(const char *p, dev_t *dev) { + struct stat st; + int r; + + assert(p); + assert(dev); + + r = stat(p, &st); if (r < 0) { - log_warning("Failed to create cgroup %s:%s: %s", b->controller, b->path, strerror(-r)); - return r; + log_warning("Couldn't stat device %s: %m", p); + return -errno; } - b->realized = true; + if (S_ISBLK(st.st_mode)) + *dev = st.st_rdev; + else if (major(st.st_dev) != 0) { + /* If this is not a device node then find the block + * device this file is stored on */ + *dev = st.st_dev; + + /* If this is a partition, try to get the originating + * block device */ + block_get_whole_disk(*dev, dev); + } else { + log_warning("%s is not a block device and file system block device cannot be determined or is not local.", p); + return -ENODEV; + } return 0; } -int cgroup_bonding_realize_list(CGroupBonding *first) { - CGroupBonding *b; +static int whitelist_device(const char *path, const char *node, const char *acc) { + char buf[2+DECIMAL_STR_MAX(dev_t)*2+2+4]; + struct stat st; int r; - LIST_FOREACH(by_unit, b, first) - if ((r = cgroup_bonding_realize(b)) < 0 && b->essential) - return r; + assert(path); + assert(acc); - return 0; + if (stat(node, &st) < 0) { + log_warning("Couldn't stat device %s", node); + return -errno; + } + + if (!S_ISCHR(st.st_mode) && !S_ISBLK(st.st_mode)) { + log_warning("%s is not a device.", node); + return -ENODEV; + } + + sprintf(buf, + "%c %u:%u %s", + S_ISCHR(st.st_mode) ? 'c' : 'b', + major(st.st_rdev), minor(st.st_rdev), + acc); + + r = cg_set_attribute("devices", path, "devices.allow", buf); + if (r < 0) + log_warning("Failed to set devices.allow on %s: %s", path, strerror(-r)); + + return r; } -void cgroup_bonding_free(CGroupBonding *b, bool trim) { - assert(b); +void cgroup_context_apply(CGroupContext *c, CGroupControllerMask mask, const char *path) { + int r; + + assert(c); + assert(path); - if (b->unit) { - CGroupBonding *f; + if (mask == 0) + return; - LIST_REMOVE(CGroupBonding, by_unit, b->unit->cgroup_bondings, b); + if (mask & CGROUP_CPU) { + char buf[DECIMAL_STR_MAX(unsigned long) + 1]; - if (streq(b->controller, SYSTEMD_CGROUP_CONTROLLER)) { - assert_se(f = hashmap_get(b->unit->manager->cgroup_bondings, b->path)); - LIST_REMOVE(CGroupBonding, by_path, f, b); + sprintf(buf, "%lu\n", c->cpu_shares); + r = cg_set_attribute("cpu", path, "cpu.shares", buf); + if (r < 0) + log_warning("Failed to set cpu.shares on %s: %s", path, strerror(-r)); + } + + if (mask & CGROUP_BLKIO) { + char buf[MAX3(DECIMAL_STR_MAX(unsigned long)+1, + DECIMAL_STR_MAX(dev_t)*2+2+DECIMAL_STR_MAX(unsigned long)*1, + DECIMAL_STR_MAX(dev_t)*2+2+DECIMAL_STR_MAX(uint64_t)+1)]; + CGroupBlockIODeviceWeight *w; + CGroupBlockIODeviceBandwidth *b; + + sprintf(buf, "%lu\n", c->blockio_weight); + r = cg_set_attribute("blkio", path, "blkio.weight", buf); + if (r < 0) + log_warning("Failed to set blkio.weight on %s: %s", path, strerror(-r)); + + /* FIXME: no way to reset this list */ + LIST_FOREACH(device_weights, w, c->blockio_device_weights) { + dev_t dev; + + r = lookup_blkio_device(w->path, &dev); + if (r < 0) + continue; - if (f) - hashmap_replace(b->unit->manager->cgroup_bondings, b->path, f); - else - hashmap_remove(b->unit->manager->cgroup_bondings, b->path); + sprintf(buf, "%u:%u %lu", major(dev), minor(dev), w->weight); + r = cg_set_attribute("blkio", path, "blkio.weight_device", buf); + if (r < 0) + log_error("Failed to set blkio.weight_device on %s: %s", path, strerror(-r)); + } + + /* FIXME: no way to reset this list */ + LIST_FOREACH(device_bandwidths, b, c->blockio_device_bandwidths) { + const char *a; + dev_t dev; + + r = lookup_blkio_device(b->path, &dev); + if (r < 0) + continue; + + a = b->read ? "blkio.throttle.read_bps_device" : "blkio.throttle.write_bps_device"; + + sprintf(buf, "%u:%u %" PRIu64 "\n", major(dev), minor(dev), b->bandwidth); + r = cg_set_attribute("blkio", path, a, buf); + if (r < 0) + log_error("Failed to set %s on %s: %s", a, path, strerror(-r)); } } - if (b->realized && b->ours && trim) - cg_trim(b->controller, b->path, false); + if (mask & CGROUP_MEMORY) { + char buf[DECIMAL_STR_MAX(uint64_t) + 1]; - free(b->controller); - free(b->path); - free(b); -} + sprintf(buf, "%" PRIu64 "\n", c->memory_limit); + r = cg_set_attribute("memory", path, "memory.limit_in_bytes", buf); + if (r < 0) + log_error("Failed to set memory.limit_in_bytes on %s: %s", path, strerror(-r)); -void cgroup_bonding_free_list(CGroupBonding *first, bool remove_or_trim) { - CGroupBonding *b, *n; + sprintf(buf, "%" PRIu64 "\n", c->memory_soft_limit); + cg_set_attribute("memory", path, "memory.soft_limit_in_bytes", buf); + if (r < 0) + log_error("Failed to set memory.limit_in_bytes on %s: %s", path, strerror(-r)); + } - LIST_FOREACH_SAFE(by_unit, b, n, first) - cgroup_bonding_free(b, remove_or_trim); -} + if (mask & CGROUP_DEVICE) { + CGroupDeviceAllow *a; -void cgroup_bonding_trim(CGroupBonding *b, bool delete_root) { - assert(b); + if (c->device_allow || c->device_policy != CGROUP_AUTO) + r = cg_set_attribute("devices", path, "devices.deny", "a"); + else + r = cg_set_attribute("devices", path, "devices.allow", "a"); + if (r < 0) + log_error("Failed to reset devices.list on %s: %s", path, strerror(-r)); - if (b->realized && b->ours) - cg_trim(b->controller, b->path, delete_root); -} + if (c->device_policy == CGROUP_CLOSED || + (c->device_policy == CGROUP_AUTO && c->device_allow)) { + static const char auto_devices[] = + "/dev/null\0" "rw\0" + "/dev/zero\0" "rw\0" + "/dev/full\0" "rw\0" + "/dev/random\0" "rw\0" + "/dev/urandom\0" "rw\0"; + + const char *x, *y; + + NULSTR_FOREACH_PAIR(x, y, auto_devices) + whitelist_device(path, x, y); + } + + LIST_FOREACH(device_allow, a, c->device_allow) { + char acc[4]; + unsigned k = 0; + + if (a->r) + acc[k++] = 'r'; + if (a->w) + acc[k++] = 'w'; + if (a->m) + acc[k++] = 'm'; -void cgroup_bonding_trim_list(CGroupBonding *first, bool delete_root) { - CGroupBonding *b; + if (k == 0) + continue; - LIST_FOREACH(by_unit, b, first) - cgroup_bonding_trim(b, delete_root); + acc[k++] = 0; + whitelist_device(path, a->path, acc); + } + } } -int cgroup_bonding_install(CGroupBonding *b, pid_t pid, const char *cgroup_suffix) { - _cleanup_free_ char *p = NULL; - const char *path; - int r; +CGroupControllerMask cgroup_context_get_mask(CGroupContext *c) { + CGroupControllerMask mask = 0; - assert(b); - assert(pid >= 0); + /* Figure out which controllers we need */ - if (cgroup_suffix) { - p = strjoin(b->path, "/", cgroup_suffix, NULL); - if (!p) - return -ENOMEM; + if (c->cpu_accounting || c->cpu_shares != 1024) + mask |= CGROUP_CPUACCT | CGROUP_CPU; - path = p; - } else - path = b->path; + if (c->blockio_accounting || + c->blockio_weight != 1000 || + c->blockio_device_weights || + c->blockio_device_bandwidths) + mask |= CGROUP_BLKIO; - r = cg_create_and_attach(b->controller, path, pid); - if (r < 0) - return r; + if (c->memory_accounting || + c->memory_limit != (uint64_t) -1 || + c->memory_soft_limit != (uint64_t) -1) + mask |= CGROUP_MEMORY; - b->realized = true; - return 0; + if (c->device_allow || c->device_policy != CGROUP_AUTO) + mask |= CGROUP_DEVICE; + + return mask; } -int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid, const char *cgroup_suffix) { - CGroupBonding *b; - int r; +static CGroupControllerMask unit_get_cgroup_mask(Unit *u) { + CGroupContext *c; - LIST_FOREACH(by_unit, b, first) { - r = cgroup_bonding_install(b, pid, cgroup_suffix); - if (r < 0 && b->essential) - return r; - } + c = unit_get_cgroup_context(u); + if (!c) + return 0; - return 0; + return cgroup_context_get_mask(c); } -int cgroup_bonding_migrate(CGroupBonding *b, CGroupBonding *list) { - CGroupBonding *q; - int ret = 0; +static CGroupControllerMask unit_get_members_mask(Unit *u) { + CGroupControllerMask mask = 0; + Unit *m; + Iterator i; - LIST_FOREACH(by_unit, q, list) { - int r; + assert(u); - if (q == b) - continue; + SET_FOREACH(m, u->dependencies[UNIT_BEFORE], i) { - if (!q->ours) + if (UNIT_DEREF(m->slice) != u) continue; - r = cg_migrate_recursive(q->controller, q->path, b->controller, b->path, true, false); - if (r < 0 && ret == 0) - ret = r; + mask |= unit_get_cgroup_mask(m) | unit_get_members_mask(m); } - return ret; + return mask; } -int cgroup_bonding_migrate_to(CGroupBonding *b, const char *target, bool rem) { - assert(b); - assert(target); +static CGroupControllerMask unit_get_siblings_mask(Unit *u) { + assert(u); - return cg_migrate_recursive(b->controller, b->path, b->controller, target, true, rem); + if (!UNIT_ISSET(u->slice)) + return 0; + + /* Sibling propagation is only relevant for weight-based + * controllers, so let's mask out everything else */ + return unit_get_members_mask(UNIT_DEREF(u->slice)) & + (CGROUP_CPU|CGROUP_BLKIO|CGROUP_CPUACCT); } -int cgroup_bonding_set_group_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid) { - assert(b); +static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) { + char *path = NULL; + int r; - if (!b->realized) - return -EINVAL; + assert(u); - return cg_set_group_access(b->controller, b->path, mode, uid, gid); -} + path = unit_default_cgroup_path(u); + if (!path) + return -ENOMEM; -int cgroup_bonding_set_group_access_list(CGroupBonding *first, mode_t mode, uid_t uid, gid_t gid) { - CGroupBonding *b; - int r; + /* First, create our own group */ + r = cg_create_with_mask(mask, path); + if (r < 0) + log_error("Failed to create cgroup %s: %s", path, strerror(-r)); - LIST_FOREACH(by_unit, b, first) { - r = cgroup_bonding_set_group_access(b, mode, uid, gid); + /* Then, possibly move things over */ + if (u->cgroup_path && !streq(path, u->cgroup_path)) { + r = cg_migrate_with_mask(mask, u->cgroup_path, path); if (r < 0) - return r; + log_error("Failed to migrate cgroup %s: %s", path, strerror(-r)); } + /* And remember the new data */ + free(u->cgroup_path); + u->cgroup_path = path; + u->cgroup_realized = true; + u->cgroup_mask = mask; + return 0; } -int cgroup_bonding_set_task_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid, int sticky) { - assert(b); +static void unit_realize_cgroup_now(Unit *u) { + CGroupControllerMask mask; - if (!b->realized) - return -EINVAL; + assert(u); - return cg_set_task_access(b->controller, b->path, mode, uid, gid, sticky); -} + if (u->in_cgroup_queue) { + LIST_REMOVE(Unit, cgroup_queue, u->manager->cgroup_queue, u); + u->in_cgroup_queue = false; + } -int cgroup_bonding_set_task_access_list(CGroupBonding *first, mode_t mode, uid_t uid, gid_t gid, int sticky) { - CGroupBonding *b; - int r; + mask = unit_get_cgroup_mask(u) | unit_get_members_mask(u) | unit_get_siblings_mask(u); + mask &= u->manager->cgroup_supported; - LIST_FOREACH(by_unit, b, first) { - r = cgroup_bonding_set_task_access(b, mode, uid, gid, sticky); - if (r < 0) - return r; - } + if (u->cgroup_realized && + u->cgroup_mask == mask) + return; - return 0; + /* First, realize parents */ + if (UNIT_ISSET(u->slice)) + unit_realize_cgroup_now(UNIT_DEREF(u->slice)); + + /* And then do the real work */ + unit_create_cgroups(u, mask); } -int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, bool rem, Set *s, const char *cgroup_suffix) { - char *p = NULL; - const char *path; - int r; +static void unit_add_to_cgroup_queue(Unit *u) { - assert(b); - assert(sig >= 0); + if (u->in_cgroup_queue) + return; - /* Don't kill cgroups that aren't ours */ - if (!b->ours) - return 0; + LIST_PREPEND(Unit, cgroup_queue, u->manager->cgroup_queue, u); + u->in_cgroup_queue = true; +} - if (cgroup_suffix) { - p = strjoin(b->path, "/", cgroup_suffix, NULL); - if (!p) - return -ENOMEM; +unsigned manager_dispatch_cgroup_queue(Manager *m) { + Unit *i; + unsigned n = 0; - path = p; - } else - path = b->path; + while ((i = m->cgroup_queue)) { + assert(i->in_cgroup_queue); - r = cg_kill_recursive(b->controller, path, sig, sigcont, true, rem, s); - free(p); + unit_realize_cgroup_now(i); + cgroup_context_apply(unit_get_cgroup_context(i), i->cgroup_mask, i->cgroup_path); + n++; + } - return r; + return n; } -int cgroup_bonding_kill_list(CGroupBonding *first, int sig, bool sigcont, bool rem, Set *s, const char *cgroup_suffix) { - CGroupBonding *b; - Set *allocated_set = NULL; - int ret = -EAGAIN, r; +static void unit_queue_siblings(Unit *u) { + Unit *slice; - if (!first) - return 0; + /* This adds the siblings of the specified unit and the + * siblings of all parent units to the cgroup queue. (But + * neither the specified unit itself nor the parents.) */ + + while ((slice = UNIT_DEREF(u->slice))) { + Iterator i; + Unit *m; - if (!s) - if (!(s = allocated_set = set_new(trivial_hash_func, trivial_compare_func))) - return -ENOMEM; + SET_FOREACH(m, slice->dependencies[UNIT_BEFORE], i) { + if (m == u) + continue; - LIST_FOREACH(by_unit, b, first) { - r = cgroup_bonding_kill(b, sig, sigcont, rem, s, cgroup_suffix); - if (r < 0) { - if (r == -EAGAIN || r == -ESRCH) + if (UNIT_DEREF(m->slice) != slice) continue; - ret = r; - goto finish; + unit_add_to_cgroup_queue(m); } - if (ret < 0 || r > 0) - ret = r; + u = slice; } +} + +void unit_realize_cgroup(Unit *u) { + CGroupContext *c; + + assert(u); + + c = unit_get_cgroup_context(u); + if (!c) + return; -finish: - if (allocated_set) - set_free(allocated_set); + /* So, here's the deal: when realizing the cgroups for this + * unit, we need to first create all parents, but there's more + * actually: for the weight-based controllers we also need to + * make sure that all our siblings (i.e. units that are in the + * same slice as we are) have cgroup too. Otherwise things + * would become very uneven as each of their processes would + * get as much resources as all our group together. This call + * will synchronously create the parent cgroups, but will + * defer work on the siblings to the next event loop + * iteration. */ - return ret; + /* Add all sibling slices to the cgroup queue. */ + unit_queue_siblings(u); + + /* And realize this one now */ + unit_realize_cgroup_now(u); + + /* And apply the values */ + cgroup_context_apply(c, u->cgroup_mask, u->cgroup_path); } -/* Returns 1 if the group is empty, 0 if it is not, -EAGAIN if we - * cannot know */ -int cgroup_bonding_is_empty(CGroupBonding *b) { +void unit_destroy_cgroup(Unit *u) { int r; - assert(b); + assert(u); - if ((r = cg_is_empty_recursive(b->controller, b->path, true)) < 0) - return r; + if (!u->cgroup_path) + return; - /* If it is empty it is empty */ - if (r > 0) - return 1; + r = cg_trim_with_mask(u->cgroup_mask, u->cgroup_path, true); + if (r < 0) + log_error("Failed to destroy cgroup %s: %s", u->cgroup_path, strerror(-r)); - /* It's not only us using this cgroup, so we just don't know */ - return b->ours ? 0 : -EAGAIN; + free(u->cgroup_path); + u->cgroup_path = NULL; + u->cgroup_realized = false; + u->cgroup_mask = 0; } -int cgroup_bonding_is_empty_list(CGroupBonding *first) { - CGroupBonding *b; +pid_t unit_search_main_pid(Unit *u) { + _cleanup_fclose_ FILE *f = NULL; + pid_t pid = 0, npid, mypid; + + assert(u); + + if (!u->cgroup_path) + return 0; + + if (cg_enumerate_processes(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, &f) < 0) + return 0; + + mypid = getpid(); + while (cg_read_pid(f, &npid) > 0) { + pid_t ppid; + + if (npid == pid) + continue; - LIST_FOREACH(by_unit, b, first) { - int r; + /* Ignore processes that aren't our kids */ + if (get_parent_of_pid(npid, &ppid) >= 0 && ppid != mypid) + continue; - r = cgroup_bonding_is_empty(b); - if (r < 0) { - /* If this returned -EAGAIN, then we don't know if the - * group is empty, so let's see if another group can - * tell us */ + if (pid != 0) { + /* Dang, there's more than one daemonized PID + in this group, so we don't know what process + is the main process. */ + pid = 0; + break; + } - if (r != -EAGAIN) - return r; - } else - return r; + pid = npid; } - return -EAGAIN; + return pid; } int manager_setup_cgroup(Manager *m) { @@ -394,8 +643,8 @@ int manager_setup_cgroup(Manager *m) { return -errno; } - /* 6. Remove non-existing controllers from the default controllers list */ - cg_shorten_controllers(m->default_controllers); + /* 6. Figure out which controllers are supported */ + m->cgroup_supported = cg_mask_supported(); return 0; } @@ -417,201 +666,71 @@ void manager_shutdown_cgroup(Manager *m, bool delete) { m->cgroup_root = NULL; } -int cgroup_bonding_get(Manager *m, const char *cgroup, CGroupBonding **bonding) { - CGroupBonding *b; +Unit* manager_get_unit_by_cgroup(Manager *m, const char *cgroup) { char *p; + Unit *u; assert(m); assert(cgroup); - assert(bonding); - b = hashmap_get(m->cgroup_bondings, cgroup); - if (b) { - *bonding = b; - return 1; - } + u = hashmap_get(m->cgroup_unit, cgroup); + if (u) + return u; p = strdupa(cgroup); - if (!p) - return -ENOMEM; - for (;;) { char *e; e = strrchr(p, '/'); - if (e == p || !e) { - *bonding = NULL; - return 0; - } + if (e == p || !e) + return NULL; *e = 0; - b = hashmap_get(m->cgroup_bondings, p); - if (b) { - *bonding = b; - return 1; - } + u = hashmap_get(m->cgroup_unit, p); + if (u) + return u; } } -int cgroup_notify_empty(Manager *m, const char *group) { - CGroupBonding *l, *b; +Unit *manager_get_unit_by_pid(Manager *m, pid_t pid) { + _cleanup_free_ char *cgroup = NULL; int r; - assert(m); - assert(group); - - r = cgroup_bonding_get(m, group, &l); - if (r <= 0) - return r; - - LIST_FOREACH(by_path, b, l) { - int t; - - if (!b->unit) - continue; - - t = cgroup_bonding_is_empty_list(b); - if (t < 0) { - - /* If we don't know, we don't know */ - if (t != -EAGAIN) - log_warning("Failed to check whether cgroup is empty: %s", strerror(errno)); - - continue; - } - - if (t > 0) { - /* If it is empty, let's delete it */ - cgroup_bonding_trim_list(b->unit->cgroup_bondings, true); - - if (UNIT_VTABLE(b->unit)->cgroup_notify_empty) - UNIT_VTABLE(b->unit)->cgroup_notify_empty(b->unit); - } - } - - return 0; -} - -Unit* cgroup_unit_by_pid(Manager *m, pid_t pid) { - CGroupBonding *l, *b; - char *group = NULL; - assert(m); if (pid <= 1) return NULL; - if (cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &group) < 0) - return NULL; - - l = hashmap_get(m->cgroup_bondings, group); - - if (!l) { - char *slash; - - while ((slash = strrchr(group, '/'))) { - if (slash == group) - break; - - *slash = 0; - - if ((l = hashmap_get(m->cgroup_bondings, group))) - break; - } - } - - free(group); - - LIST_FOREACH(by_path, b, l) { - - if (!b->unit) - continue; - - if (b->ours) - return b->unit; - } - - return NULL; -} - -CGroupBonding *cgroup_bonding_find_list(CGroupBonding *first, const char *controller) { - CGroupBonding *b; - - if (!controller) - controller = SYSTEMD_CGROUP_CONTROLLER; - - LIST_FOREACH(by_unit, b, first) - if (streq(b->controller, controller)) - return b; - - return NULL; -} - -char *cgroup_bonding_to_string(CGroupBonding *b) { - char *r; - - assert(b); - - if (asprintf(&r, "%s:%s", b->controller, b->path) < 0) + r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &cgroup); + if (r < 0) return NULL; - return r; + return manager_get_unit_by_cgroup(m, cgroup); } -pid_t cgroup_bonding_search_main_pid(CGroupBonding *b) { - FILE *f; - pid_t pid = 0, npid, mypid; - - assert(b); +int manager_notify_cgroup_empty(Manager *m, const char *cgroup) { + Unit *u; + int r; - if (!b->ours) - return 0; + assert(m); + assert(cgroup); - if (cg_enumerate_processes(b->controller, b->path, &f) < 0) + r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, cgroup, true); + if (r == 0) return 0; - mypid = getpid(); + u = manager_get_unit_by_cgroup(m, cgroup); + if (u && UNIT_VTABLE(u)->notify_cgroup_empty) + UNIT_VTABLE(u)->notify_cgroup_empty(u); - while (cg_read_pid(f, &npid) > 0) { - pid_t ppid; - - if (npid == pid) - continue; - - /* Ignore processes that aren't our kids */ - if (get_parent_of_pid(npid, &ppid) >= 0 && ppid != mypid) - continue; - - if (pid != 0) { - /* Dang, there's more than one daemonized PID - in this group, so we don't know what process - is the main process. */ - pid = 0; - break; - } - - pid = npid; - } - - fclose(f); - - return pid; + return 0; } -pid_t cgroup_bonding_search_main_pid_list(CGroupBonding *first) { - CGroupBonding *b; - pid_t pid; - - /* Try to find a main pid from this cgroup, but checking if - * there's only one PID in the cgroup and returning it. Later - * on we might want to add additional, smarter heuristics - * here. */ - - LIST_FOREACH(by_unit, b, first) - if ((pid = cgroup_bonding_search_main_pid(b)) != 0) - return pid; +static const char* const cgroup_device_policy_table[_CGROUP_DEVICE_POLICY_MAX] = { + [CGROUP_AUTO] = "auto", + [CGROUP_CLOSED] = "closed", + [CGROUP_STRICT] = "strict", +}; - return 0; - -} +DEFINE_STRING_TABLE_LOOKUP(cgroup_device_policy, CGroupDevicePolicy); diff --git a/src/core/cgroup.h b/src/core/cgroup.h index 6555d89e37..96f1d9f7b6 100644 --- a/src/core/cgroup.h +++ b/src/core/cgroup.h @@ -5,7 +5,7 @@ /*** This file is part of systemd. - Copyright 2010 Lennart Poettering + Copyright 2013 Lennart Poettering systemd is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -21,74 +21,96 @@ along with systemd; If not, see . ***/ -typedef struct CGroupBonding CGroupBonding; +#include "list.h" -#include "unit.h" +typedef struct CGroupContext CGroupContext; +typedef struct CGroupDeviceAllow CGroupDeviceAllow; +typedef struct CGroupBlockIODeviceWeight CGroupBlockIODeviceWeight; +typedef struct CGroupBlockIODeviceBandwidth CGroupBlockIODeviceBandwidth; -/* Binds a cgroup to a name */ -struct CGroupBonding { - char *controller; - char *path; +typedef enum CGroupDevicePolicy { - Unit *unit; + /* When devices listed, will allow those, plus built-in ones, + if none are listed will allow everything. */ + CGROUP_AUTO, - /* For the Unit::cgroup_bondings list */ - LIST_FIELDS(CGroupBonding, by_unit); + /* Everything forbidden, except built-in ones and listed ones. */ + CGROUP_CLOSED, - /* For the Manager::cgroup_bondings hashmap */ - LIST_FIELDS(CGroupBonding, by_path); + /* Everythings forbidden, except for the listed devices */ + CGROUP_STRICT, - /* When shutting down, remove cgroup? Are our own tasks the - * only ones in this group?*/ - bool ours:1; + _CGROUP_DEVICE_POLICY_MAX, + _CGROUP_DEVICE_POLICY_INVALID = -1 +} CGroupDevicePolicy; - /* If we cannot create this group, or add a process to it, is this fatal? */ - bool essential:1; +struct CGroupDeviceAllow { + LIST_FIELDS(CGroupDeviceAllow, device_allow); + char *path; + bool r:1; + bool w:1; + bool m:1; +}; - /* This cgroup is realized */ - bool realized:1; +struct CGroupBlockIODeviceWeight { + LIST_FIELDS(CGroupBlockIODeviceWeight, device_weights); + char *path; + unsigned long weight; }; -int cgroup_bonding_realize(CGroupBonding *b); -int cgroup_bonding_realize_list(CGroupBonding *first); +struct CGroupBlockIODeviceBandwidth { + LIST_FIELDS(CGroupBlockIODeviceBandwidth, device_bandwidths); + char *path; + uint64_t bandwidth; + bool read; +}; -void cgroup_bonding_free(CGroupBonding *b, bool trim); -void cgroup_bonding_free_list(CGroupBonding *first, bool trim); +struct CGroupContext { + bool cpu_accounting; + bool blockio_accounting; + bool memory_accounting; -int cgroup_bonding_install(CGroupBonding *b, pid_t pid, const char *suffix); -int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid, const char *suffix); + unsigned long cpu_shares; -int cgroup_bonding_migrate(CGroupBonding *b, CGroupBonding *list); -int cgroup_bonding_migrate_to(CGroupBonding *b, const char *target, bool rem); + unsigned long blockio_weight; + LIST_HEAD(CGroupBlockIODeviceWeight, blockio_device_weights); + LIST_HEAD(CGroupBlockIODeviceBandwidth, blockio_device_bandwidths); -int cgroup_bonding_set_group_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid); -int cgroup_bonding_set_group_access_list(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid); + uint64_t memory_limit; + uint64_t memory_soft_limit; -int cgroup_bonding_set_task_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid, int sticky); -int cgroup_bonding_set_task_access_list(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid, int sticky); + CGroupDevicePolicy device_policy; + LIST_HEAD(CGroupDeviceAllow, device_allow); +}; -int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, bool rem, Set *s, const char *suffix); -int cgroup_bonding_kill_list(CGroupBonding *first, int sig, bool sigcont, bool rem, Set *s, const char *suffix); +#include "unit.h" +#include "manager.h" +#include "cgroup-util.h" -void cgroup_bonding_trim(CGroupBonding *first, bool delete_root); -void cgroup_bonding_trim_list(CGroupBonding *first, bool delete_root); +void cgroup_context_init(CGroupContext *c); +void cgroup_context_done(CGroupContext *c); +void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix); +void cgroup_context_apply(CGroupContext *c, CGroupControllerMask mask, const char *path); +CGroupControllerMask cgroup_context_get_mask(CGroupContext *c); -int cgroup_bonding_is_empty(CGroupBonding *b); -int cgroup_bonding_is_empty_list(CGroupBonding *first); +void cgroup_context_free_device_allow(CGroupContext *c, CGroupDeviceAllow *a); +void cgroup_context_free_blockio_device_weight(CGroupContext *c, CGroupBlockIODeviceWeight *w); +void cgroup_context_free_blockio_device_bandwidth(CGroupContext *c, CGroupBlockIODeviceBandwidth *b); -CGroupBonding *cgroup_bonding_find_list(CGroupBonding *first, const char *controller) _pure_; +void unit_realize_cgroup(Unit *u); +void unit_destroy_cgroup(Unit *u); -char *cgroup_bonding_to_string(CGroupBonding *b); +int manager_setup_cgroup(Manager *m); +void manager_shutdown_cgroup(Manager *m, bool delete); -pid_t cgroup_bonding_search_main_pid(CGroupBonding *b); -pid_t cgroup_bonding_search_main_pid_list(CGroupBonding *b); +unsigned manager_dispatch_cgroup_queue(Manager *m); -#include "manager.h" +Unit *manager_get_unit_by_cgroup(Manager *m, const char *cgroup); +Unit* manager_get_unit_by_pid(Manager *m, pid_t pid); -int manager_setup_cgroup(Manager *m); -void manager_shutdown_cgroup(Manager *m, bool delete); +pid_t unit_search_main_pid(Unit *u); -int cgroup_bonding_get(Manager *m, const char *cgroup, CGroupBonding **bonding); -int cgroup_notify_empty(Manager *m, const char *group); +int manager_notify_cgroup_empty(Manager *m, const char *group); -Unit* cgroup_unit_by_pid(Manager *m, pid_t pid); +const char* cgroup_device_policy_to_string(CGroupDevicePolicy i) _const_; +CGroupDevicePolicy cgroup_device_policy_from_string(const char *s) _pure_; diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c new file mode 100644 index 0000000000..08ee9c8db4 --- /dev/null +++ b/src/core/dbus-cgroup.c @@ -0,0 +1,139 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include + +#include "dbus-cgroup.h" + +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_cgroup_append_device_policy, cgroup_device_policy, CGroupDevicePolicy); + +static int bus_cgroup_append_device_weights(DBusMessageIter *i, const char *property, void *data) { + DBusMessageIter sub, sub2; + CGroupContext *c = data; + CGroupBlockIODeviceWeight *w; + + assert(i); + assert(property); + assert(c); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(st)", &sub)) + return -ENOMEM; + + LIST_FOREACH(device_weights, w, c->blockio_device_weights) { + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &w->path) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &w->weight) || + !dbus_message_iter_close_container(&sub, &sub2)) + return -ENOMEM; + } + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_cgroup_append_device_bandwidths(DBusMessageIter *i, const char *property, void *data) { + DBusMessageIter sub, sub2; + CGroupContext *c = data; + CGroupBlockIODeviceBandwidth *b; + + assert(i); + assert(property); + assert(c); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(st)", &sub)) + return -ENOMEM; + + LIST_FOREACH(device_bandwidths, b, c->blockio_device_bandwidths) { + + if (streq(property, "BlockIOReadBandwidth") != b->read) + continue; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &b->path) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &b->bandwidth) || + !dbus_message_iter_close_container(&sub, &sub2)) + return -ENOMEM; + } + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_cgroup_append_device_allow(DBusMessageIter *i, const char *property, void *data) { + DBusMessageIter sub, sub2; + CGroupContext *c = data; + CGroupDeviceAllow *a; + + assert(i); + assert(property); + assert(c); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(ss)", &sub)) + return -ENOMEM; + + LIST_FOREACH(device_allow, a, c->device_allow) { + const char *rwm; + char buf[4]; + unsigned k = 0; + + if (a->r) + buf[k++] = 'r'; + if (a->w) + buf[k++] = 'w'; + if (a->m) + buf[k++] = 'm'; + + buf[k] = 0; + rwm = buf; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &a->path) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &rwm) || + !dbus_message_iter_close_container(&sub, &sub2)) + return -ENOMEM; + } + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +const BusProperty bus_cgroup_context_properties[] = { + { "CPUAccounting", bus_property_append_bool, "b", offsetof(CGroupContext, cpu_accounting) }, + { "CPUShares", bus_property_append_ul, "t", offsetof(CGroupContext, cpu_shares) }, + { "BlockIOAccounting", bus_property_append_bool, "b", offsetof(CGroupContext, blockio_accounting) }, + { "BlockIOWeight", bus_property_append_ul, "t", offsetof(CGroupContext, blockio_weight) }, + { "BlockIODeviceWeight", bus_cgroup_append_device_weights, "a(st)", 0 }, + { "BlockIOReadBandwidth", bus_cgroup_append_device_bandwidths, "a(st)", 0 }, + { "BlockIOWriteBandwidth", bus_cgroup_append_device_bandwidths, "a(st)", 0 }, + { "MemoryAccounting", bus_property_append_bool, "b", offsetof(CGroupContext, memory_accounting) }, + { "MemoryLimit", bus_property_append_uint64, "t", offsetof(CGroupContext, memory_limit) }, + { "MemorySoftLimit", bus_property_append_uint64, "t", offsetof(CGroupContext, memory_soft_limit) }, + { "DevicePolicy", bus_cgroup_append_device_policy, "s", offsetof(CGroupContext, device_policy) }, + { "DeviceAllow", bus_cgroup_append_device_allow, "a(ss)", 0 }, + {} +}; diff --git a/src/core/dbus-cgroup.h b/src/core/dbus-cgroup.h new file mode 100644 index 0000000000..a0a7a7771e --- /dev/null +++ b/src/core/dbus-cgroup.h @@ -0,0 +1,44 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include + +#include "manager.h" +#include "dbus-common.h" +#include "cgroup.h" + +#define BUS_CGROUP_CONTEXT_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +extern const BusProperty bus_cgroup_context_properties[]; diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index 2a8a0e1ac5..73590c82be 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -31,10 +31,10 @@ #include "syscall-list.h" #include "fileio.h" -DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_input, exec_input, ExecInput); -DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_output, exec_output, ExecOutput); +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_input, exec_input, ExecInput); +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_output, exec_output, ExecOutput); -int bus_execute_append_env_files(DBusMessageIter *i, const char *property, void *data) { +static int bus_execute_append_env_files(DBusMessageIter *i, const char *property, void *data) { char **env_files = data, **j; DBusMessageIter sub, sub2; @@ -66,7 +66,7 @@ int bus_execute_append_env_files(DBusMessageIter *i, const char *property, void return 0; } -int bus_execute_append_oom_score_adjust(DBusMessageIter *i, const char *property, void *data) { +static int bus_execute_append_oom_score_adjust(DBusMessageIter *i, const char *property, void *data) { ExecContext *c = data; int32_t n; @@ -92,7 +92,7 @@ int bus_execute_append_oom_score_adjust(DBusMessageIter *i, const char *property return 0; } -int bus_execute_append_nice(DBusMessageIter *i, const char *property, void *data) { +static int bus_execute_append_nice(DBusMessageIter *i, const char *property, void *data) { ExecContext *c = data; int32_t n; @@ -111,7 +111,7 @@ int bus_execute_append_nice(DBusMessageIter *i, const char *property, void *data return 0; } -int bus_execute_append_ioprio(DBusMessageIter *i, const char *property, void *data) { +static int bus_execute_append_ioprio(DBusMessageIter *i, const char *property, void *data) { ExecContext *c = data; int32_t n; @@ -130,7 +130,7 @@ int bus_execute_append_ioprio(DBusMessageIter *i, const char *property, void *da return 0; } -int bus_execute_append_cpu_sched_policy(DBusMessageIter *i, const char *property, void *data) { +static int bus_execute_append_cpu_sched_policy(DBusMessageIter *i, const char *property, void *data) { ExecContext *c = data; int32_t n; @@ -149,7 +149,7 @@ int bus_execute_append_cpu_sched_policy(DBusMessageIter *i, const char *property return 0; } -int bus_execute_append_cpu_sched_priority(DBusMessageIter *i, const char *property, void *data) { +static int bus_execute_append_cpu_sched_priority(DBusMessageIter *i, const char *property, void *data) { ExecContext *c = data; int32_t n; @@ -174,7 +174,7 @@ int bus_execute_append_cpu_sched_priority(DBusMessageIter *i, const char *proper return 0; } -int bus_execute_append_affinity(DBusMessageIter *i, const char *property, void *data) { +static int bus_execute_append_affinity(DBusMessageIter *i, const char *property, void *data) { ExecContext *c = data; dbus_bool_t b; DBusMessageIter sub; @@ -200,7 +200,7 @@ int bus_execute_append_affinity(DBusMessageIter *i, const char *property, void * return 0; } -int bus_execute_append_timer_slack_nsec(DBusMessageIter *i, const char *property, void *data) { +static int bus_execute_append_timer_slack_nsec(DBusMessageIter *i, const char *property, void *data) { ExecContext *c = data; uint64_t u; @@ -219,7 +219,7 @@ int bus_execute_append_timer_slack_nsec(DBusMessageIter *i, const char *property return 0; } -int bus_execute_append_capability_bs(DBusMessageIter *i, const char *property, void *data) { +static int bus_execute_append_capability_bs(DBusMessageIter *i, const char *property, void *data) { ExecContext *c = data; uint64_t normal, inverted; @@ -236,7 +236,7 @@ int bus_execute_append_capability_bs(DBusMessageIter *i, const char *property, v return bus_property_append_uint64(i, property, &inverted); } -int bus_execute_append_capabilities(DBusMessageIter *i, const char *property, void *data) { +static int bus_execute_append_capabilities(DBusMessageIter *i, const char *property, void *data) { ExecContext *c = data; char *t = NULL; const char *s; @@ -265,7 +265,7 @@ int bus_execute_append_capabilities(DBusMessageIter *i, const char *property, vo return 0; } -int bus_execute_append_rlimits(DBusMessageIter *i, const char *property, void *data) { +static int bus_execute_append_rlimits(DBusMessageIter *i, const char *property, void *data) { ExecContext *c = data; int r; uint64_t u; @@ -347,7 +347,7 @@ int bus_execute_append_command(DBusMessageIter *i, const char *property, void *d return 0; } -int bus_execute_append_syscall_filter(DBusMessageIter *i, const char *property, void *data) { +static int bus_execute_append_syscall_filter(DBusMessageIter *i, const char *property, void *data) { ExecContext *c = data; dbus_bool_t b; DBusMessageIter sub; @@ -430,10 +430,8 @@ const BusProperty bus_exec_context_properties[] = { { "PrivateNetwork", bus_property_append_bool, "b", offsetof(ExecContext, private_network) }, { "SameProcessGroup", bus_property_append_bool, "b", offsetof(ExecContext, same_pgrp) }, { "UtmpIdentifier", bus_property_append_string, "s", offsetof(ExecContext, utmp_id), true }, - { "ControlGroupModify", bus_property_append_bool, "b", offsetof(ExecContext, control_group_modify) }, - { "ControlGroupPersistent", bus_property_append_tristate_false, "b", offsetof(ExecContext, control_group_persistent) }, { "IgnoreSIGPIPE", bus_property_append_bool, "b", offsetof(ExecContext, ignore_sigpipe) }, { "NoNewPrivileges", bus_property_append_bool, "b", offsetof(ExecContext, no_new_privileges) }, { "SystemCallFilter", bus_execute_append_syscall_filter, "au", 0 }, - { NULL, } + {} }; diff --git a/src/core/dbus-execute.h b/src/core/dbus-execute.h index 91d70e535f..5a6a559c99 100644 --- a/src/core/dbus-execute.h +++ b/src/core/dbus-execute.h @@ -92,8 +92,6 @@ " \n" \ " \n" \ " \n" \ - " \n" \ - " \n" \ " \n" \ " \n" \ " \n" @@ -106,18 +104,4 @@ extern const BusProperty bus_exec_context_properties[]; #define BUS_EXEC_COMMAND_PROPERTY(name, command, indirect) \ { name, bus_execute_append_command, "a(sasbttttuii)", (command), (indirect), NULL } -int bus_execute_append_output(DBusMessageIter *i, const char *property, void *data); -int bus_execute_append_input(DBusMessageIter *i, const char *property, void *data); -int bus_execute_append_oom_score_adjust(DBusMessageIter *i, const char *property, void *data); -int bus_execute_append_nice(DBusMessageIter *i, const char *property, void *data); -int bus_execute_append_ioprio(DBusMessageIter *i, const char *property, void *data); -int bus_execute_append_cpu_sched_policy(DBusMessageIter *i, const char *property, void *data); -int bus_execute_append_cpu_sched_priority(DBusMessageIter *i, const char *property, void *data); -int bus_execute_append_affinity(DBusMessageIter *i, const char *property, void *data); -int bus_execute_append_timer_slack_nsec(DBusMessageIter *i, const char *property, void *data); -int bus_execute_append_capabilities(DBusMessageIter *i, const char *property, void *data); -int bus_execute_append_capability_bs(DBusMessageIter *i, const char *property, void *data); -int bus_execute_append_rlimits(DBusMessageIter *i, const char *property, void *data); int bus_execute_append_command(DBusMessageIter *u, const char *property, void *data); -int bus_execute_append_env_files(DBusMessageIter *i, const char *property, void *data); -int bus_execute_append_syscall_filter(DBusMessageIter *i, const char *property, void *data); diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index d41b6ae15f..c081ff5d16 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -613,7 +613,6 @@ static const BusProperty bus_manager_properties[] = { { "ConfirmSpawn", bus_property_append_bool, "b", offsetof(Manager, confirm_spawn) }, { "ShowStatus", bus_property_append_bool, "b", offsetof(Manager, show_status) }, { "UnitPath", bus_property_append_strv, "as", offsetof(Manager, lookup_paths.unit_path), true }, - { "DefaultControllers", bus_property_append_strv, "as", offsetof(Manager, default_controllers), true }, { "DefaultStandardOutput", bus_manager_append_exec_output, "s", offsetof(Manager, default_std_output) }, { "DefaultStandardError", bus_manager_append_exec_output, "s", offsetof(Manager, default_std_error) }, { "RuntimeWatchdogUSec", bus_property_append_usec, "t", offsetof(Manager, runtime_watchdog), false, bus_manager_set_runtime_watchdog_usec }, @@ -683,7 +682,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, DBUS_TYPE_INVALID)) return bus_send_error_reply(connection, message, &error, -EINVAL); - u = cgroup_unit_by_pid(m, (pid_t) pid); + u = manager_get_unit_by_pid(m, (pid_t) pid); if (!u) { dbus_set_error(&error, BUS_ERROR_NO_SUCH_UNIT, "No unit for PID %lu is loaded.", (unsigned long) pid); return bus_send_error_reply(connection, message, &error, -ENOENT); @@ -896,151 +895,6 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, if (!reply) goto oom; - } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "SetUnitControlGroup")) { - const char *name; - Unit *u; - DBusMessageIter iter; - - if (!dbus_message_iter_init(message, &iter)) - goto oom; - - r = bus_iter_get_basic_and_next(&iter, DBUS_TYPE_STRING, &name, true); - if (r < 0) - return bus_send_error_reply(connection, message, NULL, r); - - u = manager_get_unit(m, name); - if (!u) { - dbus_set_error(&error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name); - return bus_send_error_reply(connection, message, &error, -ENOENT); - } - - SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "start"); - - r = bus_unit_cgroup_set(u, &iter); - if (r < 0) - return bus_send_error_reply(connection, message, NULL, r); - - reply = dbus_message_new_method_return(message); - if (!reply) - goto oom; - - } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "UnsetUnitControlGroup")) { - const char *name; - Unit *u; - DBusMessageIter iter; - - if (!dbus_message_iter_init(message, &iter)) - goto oom; - - r = bus_iter_get_basic_and_next(&iter, DBUS_TYPE_STRING, &name, true); - if (r < 0) - return bus_send_error_reply(connection, message, NULL, r); - - u = manager_get_unit(m, name); - if (!u) { - dbus_set_error(&error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name); - return bus_send_error_reply(connection, message, &error, -ENOENT); - } - - SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "stop"); - - r = bus_unit_cgroup_unset(u, &iter); - if (r < 0) - return bus_send_error_reply(connection, message, NULL, r); - - reply = dbus_message_new_method_return(message); - if (!reply) - goto oom; - - } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "SetUnitControlGroupAttribute")) { - const char *name; - Unit *u; - DBusMessageIter iter; - - if (!dbus_message_iter_init(message, &iter)) - goto oom; - - r = bus_iter_get_basic_and_next(&iter, DBUS_TYPE_STRING, &name, true); - if (r < 0) - return bus_send_error_reply(connection, message, NULL, r); - - u = manager_get_unit(m, name); - if (!u) { - dbus_set_error(&error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name); - return bus_send_error_reply(connection, message, &error, -ENOENT); - } - - SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "start"); - - r = bus_unit_cgroup_attribute_set(u, &iter); - if (r < 0) - return bus_send_error_reply(connection, message, NULL, r); - - reply = dbus_message_new_method_return(message); - if (!reply) - goto oom; - - } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "UnsetUnitControlGroupAttribute")) { - const char *name; - Unit *u; - DBusMessageIter iter; - - if (!dbus_message_iter_init(message, &iter)) - goto oom; - - r = bus_iter_get_basic_and_next(&iter, DBUS_TYPE_STRING, &name, true); - if (r < 0) - return bus_send_error_reply(connection, message, NULL, r); - - u = manager_get_unit(m, name); - if (!u) { - dbus_set_error(&error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name); - return bus_send_error_reply(connection, message, &error, -ENOENT); - } - - SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "stop"); - - r = bus_unit_cgroup_attribute_unset(u, &iter); - if (r < 0) - return bus_send_error_reply(connection, message, NULL, r); - - reply = dbus_message_new_method_return(message); - if (!reply) - goto oom; - - } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetUnitControlGroupAttribute")) { - const char *name; - Unit *u; - DBusMessageIter iter; - _cleanup_strv_free_ char **list = NULL; - - if (!dbus_message_iter_init(message, &iter)) - goto oom; - - r = bus_iter_get_basic_and_next(&iter, DBUS_TYPE_STRING, &name, true); - if (r < 0) - return bus_send_error_reply(connection, message, NULL, r); - - u = manager_get_unit(m, name); - if (!u) { - dbus_set_error(&error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name); - return bus_send_error_reply(connection, message, &error, -ENOENT); - } - - SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "status"); - - r = bus_unit_cgroup_attribute_get(u, &iter, &list); - if (r < 0) - return bus_send_error_reply(connection, message, NULL, r); - - reply = dbus_message_new_method_return(message); - if (!reply) - goto oom; - - dbus_message_iter_init_append(reply, &iter); - if (bus_append_strv_iter(&iter, list) < 0) - goto oom; - } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ListUnits")) { DBusMessageIter iter, sub; Iterator i; diff --git a/src/core/dbus-mount.c b/src/core/dbus-mount.c index 0fcceb500d..16b7afe8b7 100644 --- a/src/core/dbus-mount.c +++ b/src/core/dbus-mount.c @@ -22,11 +22,12 @@ #include #include "dbus-unit.h" -#include "dbus-mount.h" -#include "dbus-kill.h" #include "dbus-execute.h" +#include "dbus-kill.h" +#include "dbus-cgroup.h" #include "dbus-common.h" #include "selinux-access.h" +#include "dbus-mount.h" #define BUS_MOUNT_INTERFACE \ " \n" \ @@ -40,7 +41,6 @@ BUS_EXEC_COMMAND_INTERFACE("ExecRemount") \ BUS_EXEC_CONTEXT_INTERFACE \ BUS_KILL_CONTEXT_INTERFACE \ - BUS_UNIT_CGROUP_INTERFACE \ " \n" \ " \n" \ " \n" \ @@ -156,11 +156,11 @@ DBusHandlerResult bus_mount_message_handler(Unit *u, DBusConnection *c, DBusMess Mount *m = MOUNT(u); const BusBoundProperties bps[] = { - { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, - { "org.freedesktop.systemd1.Mount", bus_mount_properties, m }, - { "org.freedesktop.systemd1.Mount", bus_exec_context_properties, &m->exec_context }, - { "org.freedesktop.systemd1.Mount", bus_kill_context_properties, &m->kill_context }, - { "org.freedesktop.systemd1.Mount", bus_unit_cgroup_properties, u }, + { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Mount", bus_mount_properties, m }, + { "org.freedesktop.systemd1.Mount", bus_exec_context_properties, &m->exec_context }, + { "org.freedesktop.systemd1.Mount", bus_kill_context_properties, &m->kill_context }, + { "org.freedesktop.systemd1.Mount", bus_cgroup_context_properties, &m->cgroup_context }, { NULL, } }; diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c index 98bcdcb402..bbac1b8167 100644 --- a/src/core/dbus-service.c +++ b/src/core/dbus-service.c @@ -24,9 +24,10 @@ #include "dbus-unit.h" #include "dbus-execute.h" #include "dbus-kill.h" -#include "dbus-service.h" +#include "dbus-cgroup.h" #include "dbus-common.h" #include "selinux-access.h" +#include "dbus-service.h" #define BUS_SERVICE_INTERFACE \ " \n" \ @@ -50,7 +51,6 @@ BUS_EXEC_COMMAND_INTERFACE("ExecStopPost") \ BUS_EXEC_CONTEXT_INTERFACE \ BUS_KILL_CONTEXT_INTERFACE \ - BUS_UNIT_CGROUP_INTERFACE \ " \n" \ " \n" \ " \n" \ @@ -152,8 +152,8 @@ DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *connectio { "org.freedesktop.systemd1.Service", bus_service_properties, s }, { "org.freedesktop.systemd1.Service", bus_exec_context_properties, &s->exec_context }, { "org.freedesktop.systemd1.Service", bus_kill_context_properties, &s->kill_context }, + { "org.freedesktop.systemd1.Service", bus_cgroup_context_properties, &s->cgroup_context }, { "org.freedesktop.systemd1.Service", bus_exec_main_status_properties, &s->main_exec_status }, - { "org.freedesktop.systemd1.Service", bus_unit_cgroup_properties, u }, { NULL, } }; diff --git a/src/core/dbus-slice.c b/src/core/dbus-slice.c index 8a318faa55..8243305848 100644 --- a/src/core/dbus-slice.c +++ b/src/core/dbus-slice.c @@ -22,13 +22,13 @@ #include #include "dbus-unit.h" -#include "dbus-slice.h" #include "dbus-common.h" +#include "dbus-cgroup.h" #include "selinux-access.h" +#include "dbus-slice.h" #define BUS_SLICE_INTERFACE \ " \n" \ - BUS_UNIT_CGROUP_INTERFACE \ " \n" #define INTROSPECTION \ @@ -48,9 +48,11 @@ const char bus_slice_interface[] _introspect_("Slice") = BUS_SLICE_INTERFACE; DBusHandlerResult bus_slice_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { + Slice *s = SLICE(u); + const BusBoundProperties bps[] = { - { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, - { "org.freedesktop.systemd1.Slice", bus_unit_cgroup_properties, u }, + { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Slice", bus_cgroup_context_properties, &s->cgroup_context }, { NULL, } }; diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c index 973f905149..7ec4f33924 100644 --- a/src/core/dbus-socket.c +++ b/src/core/dbus-socket.c @@ -22,11 +22,12 @@ #include #include "dbus-unit.h" -#include "dbus-socket.h" #include "dbus-execute.h" #include "dbus-kill.h" +#include "dbus-cgroup.h" #include "dbus-common.h" #include "selinux-access.h" +#include "dbus-socket.h" #define BUS_SOCKET_INTERFACE \ " \n" \ @@ -39,7 +40,6 @@ BUS_EXEC_COMMAND_INTERFACE("ExecStopPost") \ BUS_EXEC_CONTEXT_INTERFACE \ BUS_KILL_CONTEXT_INTERFACE \ - BUS_UNIT_CGROUP_INTERFACE \ " \n" \ " \n" \ " \n" \ @@ -201,11 +201,11 @@ static const BusProperty bus_socket_properties[] = { DBusHandlerResult bus_socket_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { Socket *s = SOCKET(u); const BusBoundProperties bps[] = { - { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, - { "org.freedesktop.systemd1.Socket", bus_socket_properties, s }, - { "org.freedesktop.systemd1.Socket", bus_exec_context_properties, &s->exec_context }, - { "org.freedesktop.systemd1.Socket", bus_kill_context_properties, &s->kill_context }, - { "org.freedesktop.systemd1.Socket", bus_unit_cgroup_properties, u }, + { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Socket", bus_socket_properties, s }, + { "org.freedesktop.systemd1.Socket", bus_exec_context_properties, &s->exec_context }, + { "org.freedesktop.systemd1.Socket", bus_kill_context_properties, &s->kill_context }, + { "org.freedesktop.systemd1.Socket", bus_cgroup_context_properties, &s->cgroup_context }, { NULL, } }; diff --git a/src/core/dbus-swap.c b/src/core/dbus-swap.c index 2e99fba7db..4ae1cd08e0 100644 --- a/src/core/dbus-swap.c +++ b/src/core/dbus-swap.c @@ -23,11 +23,12 @@ #include #include "dbus-unit.h" -#include "dbus-swap.h" #include "dbus-execute.h" #include "dbus-kill.h" +#include "dbus-cgroup.h" #include "dbus-common.h" #include "selinux-access.h" +#include "dbus-swap.h" #define BUS_SWAP_INTERFACE \ " \n" \ @@ -38,7 +39,6 @@ BUS_EXEC_COMMAND_INTERFACE("ExecDeactivate") \ BUS_EXEC_CONTEXT_INTERFACE \ BUS_KILL_CONTEXT_INTERFACE \ - BUS_UNIT_CGROUP_INTERFACE \ " \n" \ " \n" \ " \n" @@ -103,11 +103,11 @@ static const BusProperty bus_swap_properties[] = { DBusHandlerResult bus_swap_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { Swap *s = SWAP(u); const BusBoundProperties bps[] = { - { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, - { "org.freedesktop.systemd1.Swap", bus_swap_properties, s }, - { "org.freedesktop.systemd1.Swap", bus_exec_context_properties, &s->exec_context }, - { "org.freedesktop.systemd1.Swap", bus_kill_context_properties, &s->kill_context }, - { "org.freedesktop.systemd1.Swap", bus_unit_cgroup_properties, u }, + { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Swap", bus_swap_properties, s }, + { "org.freedesktop.systemd1.Swap", bus_exec_context_properties, &s->exec_context }, + { "org.freedesktop.systemd1.Swap", bus_kill_context_properties, &s->kill_context }, + { "org.freedesktop.systemd1.Swap", bus_cgroup_context_properties, &s->cgroup_context }, { NULL, } }; diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index 8a7ab349d1..cbd41342f4 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -295,90 +295,6 @@ static int bus_unit_append_job(DBusMessageIter *i, const char *property, void *d return 0; } -static int bus_unit_append_default_cgroup(DBusMessageIter *i, const char *property, void *data) { - Unit *u = data; - char *t; - CGroupBonding *cgb; - bool success; - - assert(i); - assert(property); - assert(u); - - cgb = unit_get_default_cgroup(u); - if (cgb) { - t = cgroup_bonding_to_string(cgb); - if (!t) - return -ENOMEM; - } else - t = (char*) ""; - - success = dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t); - - if (cgb) - free(t); - - return success ? 0 : -ENOMEM; -} - -static int bus_unit_append_cgroups(DBusMessageIter *i, const char *property, void *data) { - Unit *u = data; - CGroupBonding *cgb; - DBusMessageIter sub; - - if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "s", &sub)) - return -ENOMEM; - - LIST_FOREACH(by_unit, cgb, u->cgroup_bondings) { - _cleanup_free_ char *t = NULL; - bool success; - - t = cgroup_bonding_to_string(cgb); - if (!t) - return -ENOMEM; - - success = dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &t); - if (!success) - return -ENOMEM; - } - - if (!dbus_message_iter_close_container(i, &sub)) - return -ENOMEM; - - return 0; -} - -static int bus_unit_append_cgroup_attrs(DBusMessageIter *i, const char *property, void *data) { - Unit *u = data; - CGroupAttribute *a; - DBusMessageIter sub, sub2; - - if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(sss)", &sub)) - return -ENOMEM; - - LIST_FOREACH(by_unit, a, u->cgroup_attributes) { - _cleanup_free_ char *v = NULL; - bool success; - - if (a->semantics && a->semantics->map_write) - a->semantics->map_write(a->semantics, a->value, &v); - - success = - dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) && - dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &a->controller) && - dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &a->name) && - dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, v ? &v : &a->value) && - dbus_message_iter_close_container(&sub, &sub2); - if (!success) - return -ENOMEM; - } - - if (!dbus_message_iter_close_container(i, &sub)) - return -ENOMEM; - - return 0; -} - static int bus_unit_append_need_daemon_reload(DBusMessageIter *i, const char *property, void *data) { Unit *u = data; dbus_bool_t b; @@ -488,90 +404,6 @@ static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusConnection *conn if (!reply) goto oom; - } else if (streq_ptr(dbus_message_get_member(message), "SetControlGroup")) { - DBusMessageIter iter; - - SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "start"); - - if (!dbus_message_iter_init(message, &iter)) - goto oom; - - r = bus_unit_cgroup_set(u, &iter); - if (r < 0) - return bus_send_error_reply(connection, message, NULL, r); - - reply = dbus_message_new_method_return(message); - if (!reply) - goto oom; - - } else if (streq_ptr(dbus_message_get_member(message), "UnsetControlGroup")) { - DBusMessageIter iter; - - SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "stop"); - - if (!dbus_message_iter_init(message, &iter)) - goto oom; - - r = bus_unit_cgroup_unset(u, &iter); - if (r < 0) - return bus_send_error_reply(connection, message, NULL, r); - - reply = dbus_message_new_method_return(message); - if (!reply) - goto oom; - } else if (streq_ptr(dbus_message_get_member(message), "GetControlGroupAttribute")) { - DBusMessageIter iter; - _cleanup_strv_free_ char **list = NULL; - - SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "status"); - - if (!dbus_message_iter_init(message, &iter)) - goto oom; - - r = bus_unit_cgroup_attribute_get(u, &iter, &list); - if (r < 0) - return bus_send_error_reply(connection, message, NULL, r); - - reply = dbus_message_new_method_return(message); - if (!reply) - goto oom; - - dbus_message_iter_init_append(reply, &iter); - if (bus_append_strv_iter(&iter, list) < 0) - goto oom; - - } else if (streq_ptr(dbus_message_get_member(message), "SetControlGroupAttribute")) { - DBusMessageIter iter; - - SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "start"); - - if (!dbus_message_iter_init(message, &iter)) - goto oom; - - r = bus_unit_cgroup_attribute_set(u, &iter); - if (r < 0) - return bus_send_error_reply(connection, message, NULL, r); - - reply = dbus_message_new_method_return(message); - if (!reply) - goto oom; - - } else if (streq_ptr(dbus_message_get_member(message), "UnsetControlGroupAttribute")) { - DBusMessageIter iter; - - SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "stop"); - - if (!dbus_message_iter_init(message, &iter)) - goto oom; - - r = bus_unit_cgroup_attribute_unset(u, &iter); - if (r < 0) - return bus_send_error_reply(connection, message, NULL, r); - - reply = dbus_message_new_method_return(message); - if (!reply) - goto oom; - } else if (UNIT_VTABLE(u)->bus_message_handler) return UNIT_VTABLE(u)->bus_message_handler(u, connection, message); else @@ -913,360 +745,6 @@ oom: return DBUS_HANDLER_RESULT_NEED_MEMORY; } -static int parse_mode(DBusMessageIter *iter, bool *runtime, bool next) { - const char *mode; - int r; - - assert(iter); - assert(runtime); - - r = bus_iter_get_basic_and_next(iter, DBUS_TYPE_STRING, &mode, next); - if (r < 0) - return r; - - if (streq(mode, "runtime")) - *runtime = true; - else if (streq(mode, "persistent")) - *runtime = false; - else - return -EINVAL; - - return 0; -} - -int bus_unit_cgroup_set(Unit *u, DBusMessageIter *iter) { - _cleanup_free_ char *controller = NULL, *old_path = NULL, *new_path = NULL, *contents = NULL; - const char *name; - CGroupBonding *b; - bool runtime; - int r; - - assert(u); - assert(iter); - - if (!unit_get_exec_context(u)) - return -EINVAL; - - r = bus_iter_get_basic_and_next(iter, DBUS_TYPE_STRING, &name, true); - if (r < 0) - return r; - - r = parse_mode(iter, &runtime, false); - if (r < 0) - return r; - - r = cg_split_spec(name, &controller, &new_path); - if (r < 0) - return r; - - if (!new_path) { - new_path = unit_default_cgroup_path(u); - if (!new_path) - return -ENOMEM; - } - - if (!controller || streq(controller, SYSTEMD_CGROUP_CONTROLLER)) - return -EINVAL; - - b = cgroup_bonding_find_list(u->cgroup_bondings, controller); - if (b) { - if (streq(b->path, new_path)) - return 0; - - if (b->essential) - return -EINVAL; - - old_path = strdup(b->path); - if (!old_path) - return -ENOMEM; - } - - r = unit_add_cgroup_from_text(u, name, true, &b); - if (r < 0) - return r; - if (r > 0) { - CGroupAttribute *a; - - /* Try to move things to the new place, and clean up the old place */ - cgroup_bonding_realize(b); - cgroup_bonding_migrate(b, u->cgroup_bondings); - - if (old_path) - cg_trim(controller, old_path, true); - - /* Apply the attributes to the new group */ - LIST_FOREACH(by_unit, a, u->cgroup_attributes) - if (streq(a->controller, controller)) - cgroup_attribute_apply(a, b); - } - - contents = strjoin("[", UNIT_VTABLE(u)->exec_section, "]\n" - "ControlGroup=", name, "\n", NULL); - if (!contents) - return -ENOMEM; - - return unit_write_drop_in(u, runtime, controller, contents); -} - -int bus_unit_cgroup_unset(Unit *u, DBusMessageIter *iter) { - _cleanup_free_ char *controller = NULL, *path = NULL, *target = NULL; - const char *name; - CGroupAttribute *a, *n; - CGroupBonding *b; - bool runtime; - int r; - - assert(u); - assert(iter); - - if (!unit_get_exec_context(u)) - return -EINVAL; - - r = bus_iter_get_basic_and_next(iter, DBUS_TYPE_STRING, &name, true); - if (r < 0) - return r; - - r = parse_mode(iter, &runtime, false); - if (r < 0) - return r; - - r = cg_split_spec(name, &controller, &path); - if (r < 0) - return r; - - if (!controller || streq(controller, SYSTEMD_CGROUP_CONTROLLER)) - return -EINVAL; - - b = cgroup_bonding_find_list(u->cgroup_bondings, controller); - if (!b) - return -ENOENT; - - if (path && !path_equal(path, b->path)) - return -ENOENT; - - if (b->essential) - return -EINVAL; - - unit_remove_drop_in(u, runtime, controller); - - /* Try to migrate the old group away */ - if (cg_pid_get_path(controller, 0, &target) >= 0) - cgroup_bonding_migrate_to(u->cgroup_bondings, target, false); - - cgroup_bonding_free(b, true); - - /* Drop all attributes of this controller */ - LIST_FOREACH_SAFE(by_unit, a, n, u->cgroup_attributes) { - if (!streq(a->controller, controller)) - continue; - - unit_remove_drop_in(u, runtime, a->name); - cgroup_attribute_free(a); - } - - return 0; -} - -int bus_unit_cgroup_attribute_get(Unit *u, DBusMessageIter *iter, char ***_result) { - _cleanup_free_ char *controller = NULL; - CGroupAttribute *a; - CGroupBonding *b; - const char *name; - char **l = NULL; - int r; - - assert(u); - assert(iter); - assert(_result); - - if (!unit_get_exec_context(u)) - return -EINVAL; - - r = bus_iter_get_basic_and_next(iter, DBUS_TYPE_STRING, &name, false); - if (r < 0) - return r; - - r = cg_controller_from_attr(name, &controller); - if (r < 0) - return r; - - /* First attempt, read the value from the kernel */ - b = cgroup_bonding_find_list(u->cgroup_bondings, controller); - if (b) { - _cleanup_free_ char *p = NULL, *v = NULL; - - r = cg_get_path(b->controller, b->path, name, &p); - if (r < 0) - return r; - - r = read_full_file(p, &v, NULL); - if (r >= 0) { - /* Split on new lines */ - l = strv_split_newlines(v); - if (!l) - return -ENOMEM; - - *_result = l; - return 0; - - } - } - - /* If that didn't work, read our cached value */ - LIST_FOREACH(by_unit, a, u->cgroup_attributes) { - - if (!cgroup_attribute_matches(a, controller, name)) - continue; - - r = strv_extend(&l, a->value); - if (r < 0) { - strv_free(l); - return r; - } - } - - if (!l) - return -ENOENT; - - *_result = l; - return 0; -} - -static int update_attribute_drop_in(Unit *u, bool runtime, const char *name) { - _cleanup_free_ char *buf = NULL; - CGroupAttribute *a; - - assert(u); - assert(name); - - LIST_FOREACH(by_unit, a, u->cgroup_attributes) { - if (!cgroup_attribute_matches(a, NULL, name)) - continue; - - if (!buf) { - buf = strjoin("[", UNIT_VTABLE(u)->exec_section, "]\n" - "ControlGroupAttribute=", a->name, " ", a->value, "\n", NULL); - - if (!buf) - return -ENOMEM; - } else { - char *b; - - b = strjoin(buf, - "ControlGroupAttribute=", a->name, " ", a->value, "\n", NULL); - - if (!b) - return -ENOMEM; - - free(buf); - buf = b; - } - } - - if (buf) - return unit_write_drop_in(u, runtime, name, buf); - else - return unit_remove_drop_in(u, runtime, name); -} - -int bus_unit_cgroup_attribute_set(Unit *u, DBusMessageIter *iter) { - _cleanup_strv_free_ char **l = NULL; - int r; - bool runtime = false; - char **value; - const char *name; - - assert(u); - assert(iter); - - if (!unit_get_exec_context(u)) - return -EINVAL; - - r = bus_iter_get_basic_and_next(iter, DBUS_TYPE_STRING, &name, true); - if (r < 0) - return r; - - r = bus_parse_strv_iter(iter, &l); - if (r < 0) - return r; - - if (!dbus_message_iter_next(iter)) - return -EINVAL; - - r = parse_mode(iter, &runtime, false); - if (r < 0) - return r; - - STRV_FOREACH(value, l) { - _cleanup_free_ char *v = NULL; - CGroupAttribute *a; - const CGroupSemantics *s; - - r = cgroup_semantics_find(NULL, name, *value, &v, &s); - if (r < 0) - return r; - - if (s && !s->multiple && l[1]) - return -EINVAL; - - r = unit_add_cgroup_attribute(u, s, NULL, name, v ? v : *value, &a); - if (r < 0) - return r; - - if (r > 0) { - CGroupBonding *b; - - b = cgroup_bonding_find_list(u->cgroup_bondings, a->controller); - if (!b) { - /* Doesn't exist yet? Then let's add it */ - r = unit_add_cgroup_from_text(u, a->controller, false, &b); - if (r < 0) - return r; - - if (r > 0) { - cgroup_bonding_realize(b); - cgroup_bonding_migrate(b, u->cgroup_bondings); - } - } - - /* Make it count */ - cgroup_attribute_apply(a, u->cgroup_bondings); - } - - } - - r = update_attribute_drop_in(u, runtime, name); - if (r < 0) - return r; - - return 0; -} - -int bus_unit_cgroup_attribute_unset(Unit *u, DBusMessageIter *iter) { - const char *name; - bool runtime; - int r; - - assert(u); - assert(iter); - - if (!unit_get_exec_context(u)) - return -EINVAL; - - r = bus_iter_get_basic_and_next(iter, DBUS_TYPE_STRING, &name, true); - if (r < 0) - return r; - - r = parse_mode(iter, &runtime, false); - if (r < 0) - return r; - - cgroup_attribute_free_some(u->cgroup_attributes, NULL, name); - update_attribute_drop_in(u, runtime, name); - - return 0; -} - const BusProperty bus_unit_properties[] = { { "Id", bus_property_append_string, "s", offsetof(Unit, id), true }, { "Names", bus_unit_append_names, "as", 0 }, @@ -1330,12 +808,6 @@ const BusProperty bus_unit_properties[] = { { "ConditionTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, condition_timestamp.monotonic) }, { "ConditionResult", bus_property_append_bool, "b", offsetof(Unit, condition_result) }, { "LoadError", bus_unit_append_load_error, "(ss)", 0 }, - { NULL, } -}; - -const BusProperty bus_unit_cgroup_properties[] = { - { "DefaultControlGroup", bus_unit_append_default_cgroup, "s", 0 }, - { "ControlGroups", bus_unit_append_cgroups, "as", 0 }, - { "ControlGroupAttributes", bus_unit_append_cgroup_attrs, "a(sss)", 0 }, + { "ControlGroup", bus_property_append_string, "s", offsetof(Unit, cgroup_path), true }, { NULL, } }; diff --git a/src/core/dbus-unit.h b/src/core/dbus-unit.h index 83932c5a6c..1e226ef451 100644 --- a/src/core/dbus-unit.h +++ b/src/core/dbus-unit.h @@ -123,40 +123,14 @@ " \n" \ " \n" \ " \n" \ + " \n" \ " \n" -#define BUS_UNIT_CGROUP_INTERFACE \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" - #define BUS_UNIT_INTERFACES_LIST \ BUS_GENERIC_INTERFACES_LIST \ "org.freedesktop.systemd1.Unit\0" extern const BusProperty bus_unit_properties[]; -extern const BusProperty bus_unit_cgroup_properties[]; void bus_unit_send_change_signal(Unit *u); void bus_unit_send_removed_signal(Unit *u); diff --git a/src/core/dbus.c b/src/core/dbus.c index 1272c938cf..c2097a4dbf 100644 --- a/src/core/dbus.c +++ b/src/core/dbus.c @@ -28,7 +28,6 @@ #include "dbus.h" #include "log.h" #include "strv.h" -#include "cgroup.h" #include "mkdir.h" #include "missing.h" #include "dbus-unit.h" @@ -453,7 +452,7 @@ static DBusHandlerResult system_bus_message_filter(DBusConnection *connection, D DBUS_TYPE_INVALID)) log_error("Failed to parse Released message: %s", bus_error_message(&error)); else - cgroup_notify_empty(m, cgroup); + manager_notify_cgroup_empty(m, cgroup); } dbus_error_free(&error); @@ -489,7 +488,7 @@ static DBusHandlerResult private_bus_message_filter(DBusConnection *connection, DBUS_TYPE_INVALID)) log_error("Failed to parse Released message: %s", bus_error_message(&error)); else - cgroup_notify_empty(m, cgroup); + manager_notify_cgroup_empty(m, cgroup); /* Forward the message to the system bus, so that user * instances are notified as well */ diff --git a/src/core/execute.c b/src/core/execute.c index 9148d06df4..5e342f8d47 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -55,7 +55,6 @@ #include "sd-messages.h" #include "ioprio.h" #include "securebits.h" -#include "cgroup.h" #include "namespace.h" #include "tcpwrap.h" #include "exit-status.h" @@ -67,6 +66,7 @@ #include "syscall-list.h" #include "env-util.h" #include "fileio.h" +#include "unit.h" #define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC) @@ -986,18 +986,17 @@ int exec_spawn(ExecCommand *command, bool apply_chroot, bool apply_tty_stdin, bool confirm_spawn, - CGroupBonding *cgroup_bondings, - CGroupAttribute *cgroup_attributes, - const char *cgroup_suffix, + CGroupControllerMask cgroup_mask, + const char *cgroup_path, const char *unit_id, int idle_pipe[2], pid_t *ret) { + _cleanup_strv_free_ char **files_env = NULL; + int socket_fd; + char *line; pid_t pid; int r; - char *line; - int socket_fd; - _cleanup_strv_free_ char **files_env = NULL; assert(command); assert(context); @@ -1042,17 +1041,6 @@ int exec_spawn(ExecCommand *command, NULL); free(line); - r = cgroup_bonding_realize_list(cgroup_bondings); - if (r < 0) - return r; - - /* We must initialize the attributes in the parent, before we - fork, because we really need them initialized before making - the process a member of the group (which we do in both the - child and the parent), and we cannot really apply them twice - (due to 'append' style attributes) */ - cgroup_attribute_apply_list(cgroup_attributes, cgroup_bondings); - if (context->private_tmp && !context->tmp_dir && !context->var_tmp_dir) { r = setup_tmpdirs(&context->tmp_dir, &context->var_tmp_dir); if (r < 0) @@ -1072,7 +1060,6 @@ int exec_spawn(ExecCommand *command, _cleanup_strv_free_ char **our_env = NULL, **pam_env = NULL, **final_env = NULL, **final_argv = NULL; unsigned n_env = 0; - bool set_access = false; /* child */ @@ -1185,8 +1172,8 @@ int exec_spawn(ExecCommand *command, goto fail_child; } - if (cgroup_bondings) { - err = cgroup_bonding_install_list(cgroup_bondings, 0, cgroup_suffix); + if (cgroup_path) { + err = cg_attach_with_mask(cgroup_mask, cgroup_path, 0); if (err < 0) { r = EXIT_CGROUP; goto fail_child; @@ -1269,36 +1256,6 @@ int exec_spawn(ExecCommand *command, goto fail_child; } } - - if (cgroup_bondings && context->control_group_modify) { - err = cgroup_bonding_set_group_access_list(cgroup_bondings, 0755, uid, gid); - if (err >= 0) - err = cgroup_bonding_set_task_access_list( - cgroup_bondings, - 0644, - uid, - gid, - context->control_group_persistent); - if (err < 0) { - r = EXIT_CGROUP; - goto fail_child; - } - - set_access = true; - } - } - - if (cgroup_bondings && !set_access && context->control_group_persistent >= 0) { - err = cgroup_bonding_set_task_access_list( - cgroup_bondings, - (mode_t) -1, - (uid_t) -1, - (uid_t) -1, - context->control_group_persistent); - if (err < 0) { - r = EXIT_CGROUP; - goto fail_child; - } } if (apply_permissions) { @@ -1562,7 +1519,8 @@ int exec_spawn(ExecCommand *command, * outside of the cgroup) and in the parent (so that we can be * sure that when we kill the cgroup the process will be * killed too). */ - cgroup_bonding_install_list(cgroup_bondings, pid, cgroup_suffix); + if (cgroup_path) + cg_attach(SYSTEMD_CGROUP_CONTROLLER, cgroup_path, pid); exec_status_start(&command->exec_status, pid); @@ -1578,7 +1536,6 @@ void exec_context_init(ExecContext *c) { c->cpu_sched_policy = SCHED_OTHER; c->syslog_priority = LOG_DAEMON|LOG_INFO; c->syslog_level_prefix = true; - c->control_group_persistent = -1; c->ignore_sigpipe = true; c->timer_slack_nsec = (nsec_t) -1; } @@ -1843,8 +1800,7 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { assert(c); assert(f); - if (!prefix) - prefix = ""; + prefix = strempty(prefix); fprintf(f, "%sUMask: %04o\n" @@ -1852,8 +1808,6 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { "%sRootDirectory: %s\n" "%sNonBlocking: %s\n" "%sPrivateTmp: %s\n" - "%sControlGroupModify: %s\n" - "%sControlGroupPersistent: %s\n" "%sPrivateNetwork: %s\n" "%sIgnoreSIGPIPE: %s\n", prefix, c->umask, @@ -1861,8 +1815,6 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { prefix, c->root_directory ? c->root_directory : "/", prefix, yes_no(c->non_blocking), prefix, yes_no(c->private_tmp), - prefix, yes_no(c->control_group_modify), - prefix, yes_no(c->control_group_persistent), prefix, yes_no(c->private_network), prefix, yes_no(c->ignore_sigpipe)); diff --git a/src/core/execute.h b/src/core/execute.h index 15574dc97e..c1e9717dc8 100644 --- a/src/core/execute.h +++ b/src/core/execute.h @@ -33,14 +33,11 @@ typedef struct ExecContext ExecContext; #include #include -struct CGroupBonding; -struct CGroupAttribute; - -typedef struct Unit Unit; - #include "list.h" #include "util.h" +typedef struct Unit Unit; + typedef enum ExecInput { EXEC_INPUT_NULL, EXEC_INPUT_TTY, @@ -148,9 +145,6 @@ struct ExecContext { bool no_new_privileges; - bool control_group_modify; - int control_group_persistent; - /* This is not exposed to the user but available * internally. We need it to make sure that whenever we spawn * /bin/mount it is run in the same process group as us so @@ -166,6 +160,8 @@ struct ExecContext { bool cpu_sched_set:1; }; +#include "cgroup.h" + int exec_spawn(ExecCommand *command, char **argv, ExecContext *context, @@ -175,9 +171,8 @@ int exec_spawn(ExecCommand *command, bool apply_chroot, bool apply_tty_stdin, bool confirm_spawn, - struct CGroupBonding *cgroup_bondings, - struct CGroupAttribute *cgroup_attributes, - const char *cgroup_suffix, + CGroupControllerMask cgroup_mask, + const char *cgroup_path, const char *unit_id, int pipe_fd[2], pid_t *ret); diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index 9e5a408a30..aa07de0517 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -75,9 +75,7 @@ $1.MountFlags, config_parse_exec_mount_flags, 0, $1.TCPWrapName, config_parse_unit_string_printf, 0, offsetof($1, exec_context.tcpwrap_name) $1.PAMName, config_parse_unit_string_printf, 0, offsetof($1, exec_context.pam_name) $1.IgnoreSIGPIPE, config_parse_bool, 0, offsetof($1, exec_context.ignore_sigpipe) -$1.UtmpIdentifier, config_parse_unit_string_printf, 0, offsetof($1, exec_context.utmp_id) -$1.ControlGroupModify, config_parse_bool, 0, offsetof($1, exec_context.control_group_modify) -$1.ControlGroupPersistent, config_parse_tristate, 0, offsetof($1, exec_context.control_group_persistent)' +$1.UtmpIdentifier, config_parse_unit_string_printf, 0, offsetof($1, exec_context.utmp_id)' )m4_dnl m4_define(`KILL_CONTEXT_CONFIG_ITEMS', `$1.SendSIGKILL, config_parse_bool, 0, offsetof($1, kill_context.send_sigkill) @@ -85,16 +83,17 @@ $1.KillMode, config_parse_kill_mode, 0, $1.KillSignal, config_parse_kill_signal, 0, offsetof($1, kill_context.kill_signal)' )m4_dnl m4_define(`CGROUP_CONTEXT_CONFIG_ITEMS', -`$1.ControlGroup, config_parse_unit_cgroup, 0, 0 -$1.ControlGroupAttribute, config_parse_unit_cgroup_attr, 0, 0 -$1.CPUShares, config_parse_unit_cgroup_attr_pretty, 0, 0 -$1.MemoryLimit, config_parse_unit_cgroup_attr_pretty, 0, 0 -$1.MemorySoftLimit, config_parse_unit_cgroup_attr_pretty, 0, 0 -$1.DeviceAllow, config_parse_unit_cgroup_attr_pretty, 0, 0 -$1.DeviceDeny, config_parse_unit_cgroup_attr_pretty, 0, 0 -$1.BlockIOWeight, config_parse_unit_cgroup_attr_pretty, 0, 0 -$1.BlockIOReadBandwidth, config_parse_unit_cgroup_attr_pretty, 0, 0 -$1.BlockIOWriteBandwidth, config_parse_unit_cgroup_attr_pretty, 0, 0' +`$1.CPUAccounting, config_parse_bool, 0, offsetof($1, cgroup_context.cpu_accounting) +$1.CPUShares, config_parse_cpu_shares, 0, offsetof($1, cgroup_context) +$1.MemoryAccounting, config_parse_bool, 0, offsetof($1, cgroup_context.memory_accounting) +$1.MemoryLimit, config_parse_memory_limit, 0, offsetof($1, cgroup_context) +$1.MemorySoftLimit, config_parse_memory_limit, 0, offsetof($1, cgroup_context) +$1.DeviceAllow, config_parse_device_allow, 0, offsetof($1, cgroup_context) +$1.DevicePolicy, config_parse_device_policy, 0, offsetof($1, cgroup_context.device_policy) +$1.BlockIOAccounting, config_parse_bool, 0, offsetof($1, cgroup_context.blockio_accounting) +$1.BlockIOWeight, config_parse_blockio_weight, 0, offsetof($1, cgroup_context) +$1.BlockIOReadBandwidth, config_parse_blockio_bandwidth, 0, offsetof($1, cgroup_context) +$1.BlockIOWriteBandwidth, config_parse_blockio_bandwidth, 0, offsetof($1, cgroup_context)' )m4_dnl Unit.Description, config_parse_unit_string_printf, 0, offsetof(Unit, description) Unit.Documentation, config_parse_documentation, 0, offsetof(Unit, documentation) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 15fabe860e..57c8156fdd 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -51,6 +51,7 @@ #include "path-util.h" #include "syscall-list.h" #include "env-util.h" +#include "cgroup.h" #ifndef HAVE_SYSV_COMPAT int config_parse_warn_compat(const char *unit, @@ -996,58 +997,6 @@ int config_parse_limit(const char *unit, return 0; } -int config_parse_unit_cgroup(const char *unit, - const char *filename, - unsigned line, - const char *section, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - Unit *u = userdata; - char *w; - size_t l; - char *state; - - if (isempty(rvalue)) { - /* An empty assignment resets the list */ - cgroup_bonding_free_list(u->cgroup_bondings, false); - u->cgroup_bondings = NULL; - return 0; - } - - FOREACH_WORD_QUOTED(w, l, rvalue, state) { - _cleanup_free_ char *t = NULL, *k = NULL, *ku = NULL; - int r; - - t = strndup(w, l); - if (!t) - return log_oom(); - - k = unit_full_printf(u, t); - if (!k) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Failed to resolve unit specifiers on %s. Ignoring.", - t); - - ku = cunescape(k ? k : t); - if (!ku) - return log_oom(); - - r = unit_add_cgroup_from_text(u, ku, true, NULL); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to parse cgroup value %s, ignoring: %s", - k, rvalue); - return 0; - } - } - - return 0; -} - #ifdef HAVE_SYSV_COMPAT int config_parse_sysv_priority(const char *unit, const char *filename, @@ -1793,108 +1742,6 @@ int config_parse_unit_condition_null(const char *unit, DEFINE_CONFIG_PARSE_ENUM(config_parse_notify_access, notify_access, NotifyAccess, "Failed to parse notify access specifier"); DEFINE_CONFIG_PARSE_ENUM(config_parse_start_limit_action, start_limit_action, StartLimitAction, "Failed to parse start limit action specifier"); -int config_parse_unit_cgroup_attr(const char *unit, - const char *filename, - unsigned line, - const char *section, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - Unit *u = data; - size_t a, b; - _cleanup_free_ char *n = NULL, *v = NULL; - const CGroupSemantics *s; - int r; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(data); - - if (isempty(rvalue)) { - /* Empty assignment clears the list */ - cgroup_attribute_free_list(u->cgroup_attributes); - u->cgroup_attributes = NULL; - return 0; - } - - a = strcspn(rvalue, WHITESPACE); - b = strspn(rvalue + a, WHITESPACE); - if (a <= 0 || b <= 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Failed to parse cgroup attribute value, ignoring: %s", - rvalue); - return 0; - } - - n = strndup(rvalue, a); - if (!n) - return log_oom(); - - r = cgroup_semantics_find(NULL, n, rvalue + a + b, &v, &s); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to parse cgroup attribute value, ignoring: %s", - rvalue); - return 0; - } - - r = unit_add_cgroup_attribute(u, s, NULL, n, v ? v : rvalue + a + b, NULL); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to add cgroup attribute value, ignoring: %s", rvalue); - return 0; - } - - return 0; -} - -int config_parse_unit_cgroup_attr_pretty(const char *unit, - const char *filename, - unsigned line, - const char *section, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - Unit *u = data; - _cleanup_free_ char *v = NULL; - const CGroupSemantics *s; - int r; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(data); - - r = cgroup_semantics_find(NULL, lvalue, rvalue, &v, &s); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to parse cgroup attribute value, ignoring: %s", - rvalue); - return 0; - } else if (r == 0) { - log_syntax(unit, LOG_ERR, filename, line, ENOTSUP, - "Unknown or unsupported cgroup attribute %s, ignoring: %s", - lvalue, rvalue); - return 0; - } - - r = unit_add_cgroup_attribute(u, s, NULL, NULL, v, NULL); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to add cgroup attribute value, ignoring: %s", rvalue); - return 0; - } - - return 0; -} - int config_parse_unit_requires_mounts_for(const char *unit, const char *filename, unsigned line, @@ -2104,6 +1951,285 @@ int config_parse_unit_slice( return 0; } +DEFINE_CONFIG_PARSE_ENUM(config_parse_device_policy, cgroup_device_policy, CGroupDevicePolicy, "Failed to parse device policy"); + +int config_parse_cpu_shares( + const char *unit, + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + CGroupContext *c = data; + unsigned long lu; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + + if (isempty(rvalue)) { + c->cpu_shares = 1024; + return 0; + } + + r = safe_atolu(rvalue, &lu); + if (r < 0 || lu <= 0) { + log_syntax(unit, LOG_ERR, filename, line, EINVAL, + "CPU shares '%s' invalid. Ignoring.", rvalue); + return 0; + } + + c->cpu_shares = lu; + return 0; +} + +int config_parse_memory_limit( + const char *unit, + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + CGroupContext *c = data; + uint64_t *limit; + off_t bytes; + int r; + + limit = streq(lvalue, "MemoryLimit") ? &c->memory_limit : &c->memory_soft_limit; + + if (isempty(rvalue)) { + *limit = (uint64_t) -1; + return 0; + } + + assert_cc(sizeof(uint64_t) == sizeof(off_t)); + + r = parse_bytes(rvalue, &bytes); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, EINVAL, + "Memory limit '%s' invalid. Ignoring.", rvalue); + return 0; + } + + *limit = (uint64_t) bytes; + return 0; +} + +int config_parse_device_allow( + const char *unit, + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + _cleanup_free_ char *path = NULL; + CGroupContext *c = data; + CGroupDeviceAllow *a; + const char *m; + size_t n; + + if (isempty(rvalue)) { + while (c->device_allow) + cgroup_context_free_device_allow(c, c->device_allow); + + return 0; + } + + n = strcspn(rvalue, WHITESPACE); + path = strndup(rvalue, n); + if (!path) + return log_oom(); + + if (!path_startswith(path, "/dev")) { + log_syntax(unit, LOG_ERR, filename, line, EINVAL, + "Invalid device node path '%s'. Ignoring.", path); + return 0; + } + + m = rvalue + n + strspn(rvalue + n, WHITESPACE); + if (isempty(m)) + m = "rwm"; + + if (!in_charset(m, "rwm")) { + log_syntax(unit, LOG_ERR, filename, line, EINVAL, + "Invalid device rights '%s'. Ignoring.", m); + return 0; + } + + a = new0(CGroupDeviceAllow, 1); + if (!a) + return log_oom(); + + a->path = path; + path = NULL; + a->r = !!strchr(m, 'r'); + a->w = !!strchr(m, 'w'); + a->m = !!strchr(m, 'm'); + + LIST_PREPEND(CGroupDeviceAllow, device_allow, c->device_allow, a); + return 0; +} + +int config_parse_blockio_weight( + const char *unit, + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + _cleanup_free_ char *path = NULL; + CGroupContext *c = data; + unsigned long lu; + const char *weight; + size_t n; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + + if (isempty(rvalue)) { + c->blockio_weight = 1000; + + while (c->blockio_device_weights) + cgroup_context_free_blockio_device_weight(c, c->blockio_device_weights); + + return 0; + } + + n = strcspn(rvalue, WHITESPACE); + weight = rvalue + n; + if (*weight) { + /* Two params, first device name, then weight */ + path = strndup(rvalue, n); + if (!path) + return log_oom(); + + if (!path_startswith(path, "/dev")) { + log_syntax(unit, LOG_ERR, filename, line, EINVAL, + "Invalid device node path '%s'. Ignoring.", path); + return 0; + } + + weight += strspn(weight, WHITESPACE); + } else + /* One param, only weight */ + weight = rvalue; + + r = safe_atolu(weight, &lu); + if (r < 0 || lu < 10 || lu > 1000) { + log_syntax(unit, LOG_ERR, filename, line, EINVAL, + "Block IO weight '%s' invalid. Ignoring.", rvalue); + return 0; + } + + if (!path) + c->blockio_weight = lu; + else { + CGroupBlockIODeviceWeight *w; + + w = new0(CGroupBlockIODeviceWeight, 1); + if (!w) + return log_oom(); + + w->path = path; + path = NULL; + + w->weight = lu; + + LIST_PREPEND(CGroupBlockIODeviceWeight, device_weights, c->blockio_device_weights, w); + } + + return 0; +} + +int config_parse_blockio_bandwidth( + const char *unit, + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + _cleanup_free_ char *path = NULL; + CGroupBlockIODeviceBandwidth *b; + CGroupContext *c = data; + const char *bandwidth; + off_t bytes; + size_t n; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + + if (isempty(rvalue)) { + while (c->blockio_device_bandwidths) + cgroup_context_free_blockio_device_bandwidth(c, c->blockio_device_bandwidths); + + return 0; + } + + n = strcspn(rvalue, WHITESPACE); + bandwidth = rvalue + n; + bandwidth += strspn(bandwidth, WHITESPACE); + + if (!*bandwidth) { + log_syntax(unit, LOG_ERR, filename, line, EINVAL, + "Expected space separated pair of device node and bandwidth. Ignoring."); + return 0; + } + + path = strndup(rvalue, n); + if (!path) + return log_oom(); + + if (!path_startswith(path, "/dev")) { + log_syntax(unit, LOG_ERR, filename, line, EINVAL, + "Invalid device node path '%s'. Ignoring.", path); + return 0; + } + + r = parse_bytes(bandwidth, &bytes); + if (r < 0 || bytes <= 0) { + log_syntax(unit, LOG_ERR, filename, line, EINVAL, + "Block IO Bandwidth '%s' invalid. Ignoring.", rvalue); + return 0; + } + + b = new0(CGroupBlockIODeviceBandwidth, 1); + if (!b) + return log_oom(); + + b->path = path; + path = NULL; + b->bandwidth = (uint64_t) bytes; + + LIST_PREPEND(CGroupBlockIODeviceBandwidth, device_bandwidths, c->blockio_device_bandwidths, b); + + return 0; +} + #define FOLLOW_MAX 8 static int open_follow(char **filename, FILE **_f, Set *names, char **_final) { @@ -2463,7 +2589,6 @@ void unit_dump_config_items(FILE *f) { { config_parse_exec_secure_bits, "SECUREBITS" }, { config_parse_bounding_set, "BOUNDINGSET" }, { config_parse_limit, "LIMIT" }, - { config_parse_unit_cgroup, "CGROUP [...]" }, { config_parse_unit_deps, "UNIT [...]" }, { config_parse_exec, "PATH [ARGUMENT [...]]" }, { config_parse_service_type, "SERVICETYPE" }, diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h index f9677baa0f..5e36f3538a 100644 --- a/src/core/load-fragment.h +++ b/src/core/load-fragment.h @@ -55,7 +55,6 @@ int config_parse_exec_capabilities(const char *unit, const char *filename, unsig int config_parse_exec_secure_bits(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_bounding_set(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_limit(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); -int config_parse_unit_cgroup(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_sysv_priority(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_fsck_passno(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_kill_signal(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); @@ -73,12 +72,16 @@ int config_parse_unit_condition_null(const char *unit, const char *filename, uns int config_parse_kill_mode(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_notify_access(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_start_limit_action(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); -int config_parse_unit_cgroup_attr(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); -int config_parse_unit_cgroup_attr_pretty(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_unit_requires_mounts_for(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_syscall_filter(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_environ(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_unit_slice(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_cpu_shares(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_memory_limit(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_device_policy(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_device_allow(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_blockio_weight(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_blockio_bandwidth(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); /* gperf prototypes */ const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, unsigned length); diff --git a/src/core/main.c b/src/core/main.c index c123de91ce..3c6fccf527 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -88,7 +88,6 @@ static int arg_crash_chvt = -1; static bool arg_confirm_spawn = false; static bool arg_show_status = true; static bool arg_switched_root = false; -static char **arg_default_controllers = NULL; static char ***arg_join_controllers = NULL; static ExecOutput arg_default_std_output = EXEC_OUTPUT_JOURNAL; static ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT; @@ -642,7 +641,6 @@ static int parse_config_file(void) { { "Manager", "ShowStatus", config_parse_bool, 0, &arg_show_status }, { "Manager", "CrashChVT", config_parse_int, 0, &arg_crash_chvt }, { "Manager", "CPUAffinity", config_parse_cpu_affinity2, 0, NULL }, - { "Manager", "DefaultControllers", config_parse_strv, 0, &arg_default_controllers }, { "Manager", "DefaultStandardOutput", config_parse_output, 0, &arg_default_std_output }, { "Manager", "DefaultStandardError", config_parse_output, 0, &arg_default_std_error }, { "Manager", "JoinControllers", config_parse_join_controllers, 0, &arg_join_controllers }, @@ -1632,9 +1630,6 @@ int main(int argc, char *argv[]) { manager_set_default_rlimits(m, arg_default_rlimit); - if (arg_default_controllers) - manager_set_default_controllers(m, arg_default_controllers); - if (arg_default_environment) manager_set_default_environment(m, arg_default_environment); @@ -1807,7 +1802,6 @@ finish: free(arg_default_rlimit[j]); free(arg_default_unit); - strv_free(arg_default_controllers); free_join_controllers(); dbus_shutdown(); diff --git a/src/core/manager.c b/src/core/manager.c index 2416dd0f1e..6ba51a4116 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -55,7 +55,6 @@ #include "util.h" #include "mkdir.h" #include "ratelimit.h" -#include "cgroup.h" #include "mount-setup.h" #include "unit-name.h" #include "dbus-unit.h" @@ -467,12 +466,6 @@ int manager_new(SystemdRunningAs running_as, Manager **_m) { manager_strip_environment(m); - if (running_as == SYSTEMD_SYSTEM) { - m->default_controllers = strv_new("cpu", NULL); - if (!m->default_controllers) - goto fail; - } - if (!(m->units = hashmap_new(string_hash_func, string_compare_func))) goto fail; @@ -482,7 +475,8 @@ int manager_new(SystemdRunningAs running_as, Manager **_m) { if (!(m->watch_pids = hashmap_new(trivial_hash_func, trivial_compare_func))) goto fail; - if (!(m->cgroup_bondings = hashmap_new(string_hash_func, string_compare_func))) + m->cgroup_unit = hashmap_new(string_hash_func, string_compare_func); + if (!m->cgroup_unit) goto fail; if (!(m->watch_bus = hashmap_new(string_hash_func, string_compare_func))) @@ -712,9 +706,7 @@ void manager_free(Manager *m) { lookup_paths_free(&m->lookup_paths); strv_free(m->environment); - strv_free(m->default_controllers); - - hashmap_free(m->cgroup_bondings); + hashmap_free(m->cgroup_unit); set_free_free(m->unit_path_cache); close_pipe(m->idle_pipe); @@ -1220,7 +1212,7 @@ static int manager_process_notify_fd(Manager *m) { u = hashmap_get(m->watch_pids, LONG_TO_PTR(ucred->pid)); if (!u) { - u = cgroup_unit_by_pid(m, ucred->pid); + u = manager_get_unit_by_pid(m, ucred->pid); if (!u) { log_warning("Cannot find unit for notify message of PID %lu.", (unsigned long) ucred->pid); continue; @@ -1285,7 +1277,7 @@ static int manager_dispatch_sigchld(Manager *m) { /* And now figure out the unit this belongs to */ u = hashmap_get(m->watch_pids, LONG_TO_PTR(si.si_pid)); if (!u) - u = cgroup_unit_by_pid(m, si.si_pid); + u = manager_get_unit_by_pid(m, si.si_pid); /* And now, we actually reap the zombie. */ if (waitid(P_PID, si.si_pid, &si, WEXITED) < 0) { @@ -1741,6 +1733,9 @@ int manager_loop(Manager *m) { if (manager_dispatch_gc_queue(m) > 0) continue; + if (manager_dispatch_cgroup_queue(m) > 0) + continue; + if (manager_dispatch_dbus_queue(m) > 0) continue; @@ -2586,23 +2581,6 @@ int manager_set_default_environment(Manager *m, char **environment) { return 0; } -int manager_set_default_controllers(Manager *m, char **controllers) { - char **l; - - assert(m); - - l = strv_copy(controllers); - if (!l) - return -ENOMEM; - - strv_free(m->default_controllers); - m->default_controllers = l; - - cg_shorten_controllers(m->default_controllers); - - return 0; -} - int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit) { int i; diff --git a/src/core/manager.h b/src/core/manager.h index f0bb2eb035..68cb2e4a3d 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -27,6 +27,7 @@ #include #include "fdset.h" +#include "cgroup-util.h" /* Enforce upper limit how many names we allow */ #define MANAGER_MAX_NAMES 131072 /* 128K */ @@ -86,6 +87,7 @@ struct Watch { #include "dbus.h" #include "path-lookup.h" #include "execute.h" +#include "unit-name.h" struct Manager { /* Note that the set of units we know of is allowed to be @@ -122,6 +124,9 @@ struct Manager { /* Units to check when doing GC */ LIST_HEAD(Unit, gc_queue); + /* Units that should be realized */ + LIST_HEAD(Unit, cgroup_queue); + Hashmap *watch_pids; /* pid => Unit object n:1 */ char *notify_socket; @@ -139,7 +144,6 @@ struct Manager { Set *unit_path_cache; char **environment; - char **default_controllers; usec_t runtime_watchdog; usec_t shutdown_watchdog; @@ -198,7 +202,8 @@ struct Manager { int dev_autofs_fd; /* Data specific to the cgroup subsystem */ - Hashmap *cgroup_bondings; /* path string => CGroupBonding object 1:n */ + Hashmap *cgroup_unit; + CGroupControllerMask cgroup_supported; char *cgroup_root; usec_t gc_queue_timestamp; @@ -273,7 +278,6 @@ unsigned manager_dispatch_run_queue(Manager *m); unsigned manager_dispatch_dbus_queue(Manager *m); int manager_set_default_environment(Manager *m, char **environment); -int manager_set_default_controllers(Manager *m, char **controllers); int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit); int manager_loop(Manager *m); diff --git a/src/core/mount.c b/src/core/mount.c index e21e774d4d..c71d51bfa4 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -82,6 +82,7 @@ static void mount_init(Unit *u) { } kill_context_init(&m->kill_context); + cgroup_context_init(&m->cgroup_context); /* We need to make sure that /bin/mount is always called in * the same process group as us, so that the autofs kernel @@ -127,6 +128,7 @@ static void mount_done(Unit *u) { mount_parameters_done(&m->parameters_proc_self_mountinfo); mount_parameters_done(&m->parameters_fragment); + cgroup_context_done(&m->cgroup_context); exec_context_done(&m->exec_context, manager_is_reloading_or_reexecuting(u->manager)); exec_command_done_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX); m->control_command = NULL; @@ -651,10 +653,6 @@ static int mount_add_extras(Mount *m) { if (r < 0) return r; - r = unit_add_default_cgroups(u); - if (r < 0) - return r; - r = mount_fix_timeouts(m); if (r < 0) return r; @@ -848,28 +846,31 @@ static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) { assert(c); assert(_pid); + unit_realize_cgroup(UNIT(m)); + r = unit_watch_timer(UNIT(m), CLOCK_MONOTONIC, true, m->timeout_usec, &m->timer_watch); if (r < 0) goto fail; - if ((r = exec_spawn(c, - NULL, - &m->exec_context, - NULL, 0, - UNIT(m)->manager->environment, - true, - true, - true, - UNIT(m)->manager->confirm_spawn, - UNIT(m)->cgroup_bondings, - UNIT(m)->cgroup_attributes, - NULL, - UNIT(m)->id, - NULL, - &pid)) < 0) + r = exec_spawn(c, + NULL, + &m->exec_context, + NULL, 0, + UNIT(m)->manager->environment, + true, + true, + true, + UNIT(m)->manager->confirm_spawn, + UNIT(m)->cgroup_mask, + UNIT(m)->cgroup_path, + UNIT(m)->id, + NULL, + &pid); + if (r < 0) goto fail; - if ((r = unit_watch_pid(UNIT(m), pid)) < 0) + r = unit_watch_pid(UNIT(m), pid); + if (r < 0) /* FIXME: we need to do something here */ goto fail; @@ -1878,8 +1879,9 @@ const UnitVTable mount_vtable = { "Mount\0" "Install\0", + .private_section = "Mount", .exec_context_offset = offsetof(Mount, exec_context), - .exec_section = "Mount", + .cgroup_context_offset = offsetof(Mount, cgroup_context), .no_alias = true, .no_instances = true, diff --git a/src/core/mount.h b/src/core/mount.h index bcc10ee0d4..7cd4320d94 100644 --- a/src/core/mount.h +++ b/src/core/mount.h @@ -25,6 +25,8 @@ typedef struct Mount Mount; #include "unit.h" #include "kill.h" +#include "execute.h" +#include "cgroup.h" typedef enum MountState { MOUNT_DEAD, @@ -95,8 +97,10 @@ struct Mount { usec_t timeout_usec; ExecCommand exec_command[_MOUNT_EXEC_COMMAND_MAX]; + ExecContext exec_context; KillContext kill_context; + CGroupContext cgroup_context; MountState state, deserialized_state; diff --git a/src/core/service.c b/src/core/service.c index a0c648a85b..5fdbdb13a3 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -141,6 +141,7 @@ static void service_init(Unit *u) { exec_context_init(&s->exec_context); kill_context_init(&s->kill_context); + cgroup_context_init(&s->cgroup_context); RATELIMIT_INIT(s->start_limit, 10*USEC_PER_SEC, 5); @@ -283,6 +284,7 @@ static void service_done(Unit *u) { free(s->status_text); s->status_text = NULL; + cgroup_context_done(&s->cgroup_context); exec_context_done(&s->exec_context, manager_is_reloading_or_reexecuting(u->manager)); exec_command_free_array(s->exec_command, _SERVICE_EXEC_COMMAND_MAX); s->control_command = NULL; @@ -1229,10 +1231,6 @@ static int service_load(Unit *u) { if (r < 0) return r; - r = unit_add_default_cgroups(u); - if (r < 0) - return r; - #ifdef HAVE_SYSV_COMPAT r = sysv_fix_order(s); if (r < 0) @@ -1457,7 +1455,7 @@ static int service_search_main_pid(Service *s) { assert(s->main_pid <= 0); - pid = cgroup_bonding_search_main_pid_list(UNIT(s)->cgroup_bondings); + pid = unit_search_main_pid(UNIT(s)); if (pid <= 0) return -ENOENT; @@ -1582,7 +1580,7 @@ static void service_set_state(Service *s, ServiceState state) { /* For the inactive states unit_notify() will trim the cgroup, * but for exit we have to do that ourselves... */ if (state == SERVICE_EXITED && UNIT(s)->manager->n_reloading <= 0) - cgroup_bonding_trim_list(UNIT(s)->cgroup_bondings, true); + unit_destroy_cgroup(UNIT(s)); if (old_state != state) log_debug_unit(UNIT(s)->id, @@ -1751,11 +1749,14 @@ static int service_spawn( unsigned n_fds = 0, n_env = 0; _cleanup_strv_free_ char **argv = NULL, **final_env = NULL, **our_env = NULL; + const char *path; assert(s); assert(c); assert(_pid); + unit_realize_cgroup(UNIT(s)); + if (pass_fds || s->exec_context.std_input == EXEC_INPUT_SOCKET || s->exec_context.std_output == EXEC_OUTPUT_SOCKET || @@ -1811,7 +1812,7 @@ static int service_spawn( goto fail; } - if (s->meta.manager->running_as != SYSTEMD_SYSTEM) + if (UNIT(s)->manager->running_as != SYSTEMD_SYSTEM) if (asprintf(our_env + n_env++, "MANAGERPID=%lu", (unsigned long) getpid()) < 0) { r = -ENOMEM; goto fail; @@ -1823,6 +1824,12 @@ static int service_spawn( goto fail; } + if (is_control && UNIT(s)->cgroup_path) { + path = strappenda(UNIT(s)->cgroup_path, "/control"); + cg_create(SYSTEMD_CGROUP_CONTROLLER, path); + } else + path = UNIT(s)->cgroup_path; + r = exec_spawn(c, argv, &s->exec_context, @@ -1832,9 +1839,8 @@ static int service_spawn( apply_chroot, apply_tty_stdin, UNIT(s)->manager->confirm_spawn, - UNIT(s)->cgroup_bondings, - UNIT(s)->cgroup_attributes, - is_control ? "control" : NULL, + UNIT(s)->cgroup_mask, + path, UNIT(s)->id, s->type == SERVICE_IDLE ? UNIT(s)->manager->idle_pipe : NULL, &pid); @@ -1893,7 +1899,10 @@ static int cgroup_good(Service *s) { assert(s); - r = cgroup_bonding_is_empty_list(UNIT(s)->cgroup_bondings); + if (!UNIT(s)->cgroup_path) + return 0; + + r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, UNIT(s)->cgroup_path, true); if (r < 0) return r; @@ -2123,10 +2132,21 @@ fail: service_enter_stop(s, SERVICE_FAILURE_RESOURCES); } +static void service_kill_control_processes(Service *s) { + char *p; + + if (!UNIT(s)->cgroup_path) + return; + + p = strappenda(UNIT(s)->cgroup_path, "/control"); + + cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, p, SIGKILL, true, true, true, NULL); +} + static void service_enter_start(Service *s) { + ExecCommand *c; pid_t pid; int r; - ExecCommand *c; assert(s); @@ -2141,7 +2161,7 @@ static void service_enter_start(Service *s) { /* We want to ensure that nobody leaks processes from * START_PRE here, so let's go on a killing spree, People * should not spawn long running processes from START_PRE. */ - cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, SIGKILL, true, true, NULL, "control"); + service_kill_control_processes(s); if (s->type == SERVICE_FORKING) { s->control_command_id = SERVICE_EXEC_START; @@ -2217,11 +2237,9 @@ static void service_enter_start_pre(Service *s) { s->control_command = s->exec_command[SERVICE_EXEC_START_PRE]; if (s->control_command) { - /* Before we start anything, let's clear up what might * be left from previous runs. */ - cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, SIGKILL, - true,true, NULL, "control"); + service_kill_control_processes(s); s->control_command_id = SERVICE_EXEC_START_PRE; @@ -3045,7 +3063,6 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { } } else if (s->control_pid == pid) { - s->control_pid = 0; if (s->control_command) { @@ -3066,8 +3083,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { /* Immediately get rid of the cgroup, so that the * kernel doesn't delay the cgroup empty messages for * the service cgroup any longer than necessary */ - cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, SIGKILL, - true, true, NULL, "control"); + service_kill_control_processes(s); if (s->control_command && s->control_command->command_next && @@ -3296,7 +3312,7 @@ static void service_timer_event(Unit *u, uint64_t elapsed, Watch* w) { } } -static void service_cgroup_notify_event(Unit *u) { +static void service_notify_cgroup_empty_event(Unit *u) { Service *s = SERVICE(u); assert(u); @@ -3823,8 +3839,9 @@ const UnitVTable service_vtable = { "Service\0" "Install\0", + .private_section = "Service", .exec_context_offset = offsetof(Service, exec_context), - .exec_section = "Service", + .cgroup_context_offset = offsetof(Service, cgroup_context), .init = service_init, .done = service_done, @@ -3857,7 +3874,7 @@ const UnitVTable service_vtable = { .reset_failed = service_reset_failed, - .cgroup_notify_empty = service_cgroup_notify_event, + .notify_cgroup_empty = service_notify_cgroup_empty_event, .notify_message = service_notify_message, .bus_name_owner_change = service_bus_name_owner_change, diff --git a/src/core/service.h b/src/core/service.h index 703d3faa45..182cba1333 100644 --- a/src/core/service.h +++ b/src/core/service.h @@ -135,6 +135,7 @@ struct Service { ExecContext exec_context; KillContext kill_context; + CGroupContext cgroup_context; ServiceState state, deserialized_state; diff --git a/src/core/slice.c b/src/core/slice.c index c1c33fe5c6..df2d91e473 100644 --- a/src/core/slice.c +++ b/src/core/slice.c @@ -36,6 +36,23 @@ static const UnitActiveState state_translation_table[_SLICE_STATE_MAX] = { [SLICE_ACTIVE] = UNIT_ACTIVE }; +static void slice_init(Unit *u) { + Slice *s = SLICE(u); + + assert(u); + assert(u->load_state == UNIT_STUB); + + cgroup_context_init(&s->cgroup_context); +} + +static void slice_done(Unit *u) { + Slice *s = SLICE(u); + + assert(u); + + cgroup_context_done(&s->cgroup_context); +} + static void slice_set_state(Slice *t, SliceState state) { SliceState old_state; assert(t); @@ -52,23 +69,25 @@ static void slice_set_state(Slice *t, SliceState state) { unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state], true); } -static int slice_add_slice_link(Slice *s) { +static int slice_add_parent_slice(Slice *s) { char *a, *dash; - int r; Unit *parent; + int r; assert(s); - if (UNIT_DEREF(UNIT(s)->slice)) + if (UNIT_ISSET(UNIT(s)->slice)) return 0; - a = strdupa(UNIT(s)->id); - - dash = strrchr(a, '-'); - if (!dash) + if (unit_has_name(UNIT(s), SPECIAL_ROOT_SLICE)) return 0; - strcpy(dash, ".slice"); + a = strdupa(UNIT(s)->id); + dash = strrchr(a, '-'); + if (dash) + strcpy(dash, ".slice"); + else + a = (char*) SPECIAL_ROOT_SLICE; r = manager_load_unit(UNIT(s)->manager, a, NULL, NULL, &parent); if (r < 0) @@ -102,14 +121,15 @@ static int slice_verify(Slice *s) { a = strdupa(UNIT(s)->id); dash = strrchr(a, '-'); - if (dash) { + if (dash) strcpy(dash, ".slice"); + else + a = (char*) SPECIAL_ROOT_SLICE; - if (!unit_has_name(UNIT_DEREF(UNIT(s)->slice), a)) { - log_error_unit(UNIT(s)->id, - "%s located outside its parent slice. Refusing.", UNIT(s)->id); - return -EINVAL; - } + if (!unit_has_name(UNIT_DEREF(UNIT(s)->slice), a)) { + log_error_unit(UNIT(s)->id, + "%s located outside its parent slice. Refusing.", UNIT(s)->id); + return -EINVAL; } } @@ -122,14 +142,14 @@ static int slice_load(Unit *u) { assert(s); - r = unit_load_fragment_and_dropin(u); + r = unit_load_fragment_and_dropin_optional(u); if (r < 0) return r; /* This is a new unit? Then let's add in some extras */ if (u->load_state == UNIT_LOADED) { - r = slice_add_slice_link(s); + r = slice_add_parent_slice(s); if (r < 0) return r; @@ -138,10 +158,6 @@ static int slice_load(Unit *u) { if (r < 0) return r; } - - r = unit_add_default_cgroups(UNIT(s)); - if (r < 0) - return r; } return slice_verify(s); @@ -168,20 +184,17 @@ static void slice_dump(Unit *u, FILE *f, const char *prefix) { fprintf(f, "%sSlice State: %s\n", prefix, slice_state_to_string(t->state)); + + cgroup_context_dump(&t->cgroup_context, f, prefix); } static int slice_start(Unit *u) { Slice *t = SLICE(u); - int r; assert(t); assert(t->state == SLICE_DEAD); - r = cgroup_bonding_realize_list(u->cgroup_bondings); - if (r < 0) - return r; - - cgroup_attribute_apply_list(u->cgroup_attributes, u->cgroup_bondings); + unit_realize_cgroup(u); slice_set_state(t, SLICE_ACTIVE); return 0; @@ -193,8 +206,8 @@ static int slice_stop(Unit *u) { assert(t); assert(t->state == SLICE_ACTIVE); - /* We do not need to trim the cgroup explicitly, unit_notify() - * will do that for us anyway. */ + /* We do not need to destroy the cgroup explicitly, + * unit_notify() will do that for us anyway. */ slice_set_state(t, SLICE_DEAD); return 0; @@ -264,10 +277,16 @@ const UnitVTable slice_vtable = { "Slice\0" "Install\0", + .private_section = "Slice", + .cgroup_context_offset = offsetof(Slice, cgroup_context), + .no_alias = true, .no_instances = true, + .init = slice_init, .load = slice_load, + .done = slice_done, + .coldplug = slice_coldplug, .dump = slice_dump, @@ -288,11 +307,11 @@ const UnitVTable slice_vtable = { .status_message_formats = { .finished_start_job = { - [JOB_DONE] = "Installed slice %s.", + [JOB_DONE] = "Created slice %s.", [JOB_DEPENDENCY] = "Dependency failed for %s.", }, .finished_stop_job = { - [JOB_DONE] = "Deinstalled slice %s.", + [JOB_DONE] = "Removed slice %s.", }, }, }; diff --git a/src/core/slice.h b/src/core/slice.h index 4320a6354b..ad0c63902b 100644 --- a/src/core/slice.h +++ b/src/core/slice.h @@ -36,6 +36,8 @@ struct Slice { Unit meta; SliceState state, deserialized_state; + + CGroupContext cgroup_context; }; extern const UnitVTable slice_vtable; diff --git a/src/core/socket.c b/src/core/socket.c index 2f25e25aa6..c1bbaec447 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -88,6 +88,7 @@ static void socket_init(Unit *u) { s->exec_context.std_output = u->manager->default_std_output; s->exec_context.std_error = u->manager->default_std_error; kill_context_init(&s->kill_context); + cgroup_context_init(&s->cgroup_context); s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID; } @@ -128,6 +129,8 @@ static void socket_done(Unit *u) { socket_free_ports(s); exec_context_done(&s->exec_context, manager_is_reloading_or_reexecuting(u->manager)); + cgroup_context_init(&s->cgroup_context); + exec_command_free_array(s->exec_command, _SOCKET_EXEC_COMMAND_MAX); s->control_command = NULL; @@ -399,10 +402,6 @@ static int socket_load(Unit *u) { if (r < 0) return r; - r = unit_add_default_cgroups(u); - if (r < 0) - return r; - if (UNIT(s)->default_dependencies) if ((r = socket_add_default_dependencies(s)) < 0) return r; @@ -1210,6 +1209,8 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) { assert(c); assert(_pid); + unit_realize_cgroup(UNIT(s)); + r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch); if (r < 0) goto fail; @@ -1229,9 +1230,8 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) { true, true, UNIT(s)->manager->confirm_spawn, - UNIT(s)->cgroup_bondings, - UNIT(s)->cgroup_attributes, - NULL, + UNIT(s)->cgroup_mask, + UNIT(s)->cgroup_path, UNIT(s)->id, NULL, &pid); @@ -2361,8 +2361,9 @@ const UnitVTable socket_vtable = { "Socket\0" "Install\0", + .private_section = "Socket", .exec_context_offset = offsetof(Socket, exec_context), - .exec_section = "Socket", + .cgroup_context_offset = offsetof(Socket, cgroup_context), .init = socket_init, .done = socket_done, diff --git a/src/core/socket.h b/src/core/socket.h index 9d48cde0a6..15942c1c90 100644 --- a/src/core/socket.h +++ b/src/core/socket.h @@ -102,6 +102,7 @@ struct Socket { ExecCommand* exec_command[_SOCKET_EXEC_COMMAND_MAX]; ExecContext exec_context; KillContext kill_context; + CGroupContext cgroup_context; /* For Accept=no sockets refers to the one service we'll activate. For Accept=yes sockets is either NULL, or filled diff --git a/src/core/special.h b/src/core/special.h index 337a0a43e9..6d252e7baa 100644 --- a/src/core/special.h +++ b/src/core/special.h @@ -118,3 +118,4 @@ #define SPECIAL_SYSTEM_SLICE "system.slice" #define SPECIAL_USER_SLICE "user.slice" #define SPECIAL_MACHINE_SLICE "machine.slice" +#define SPECIAL_ROOT_SLICE "-.slice" diff --git a/src/core/swap.c b/src/core/swap.c index d6721a6b31..0d4b4fa4f9 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -92,6 +92,7 @@ static void swap_init(Unit *u) { s->exec_context.std_output = u->manager->default_std_output; s->exec_context.std_error = u->manager->default_std_error; kill_context_init(&s->kill_context); + cgroup_context_init(&s->cgroup_context); s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1; @@ -129,6 +130,8 @@ static void swap_done(Unit *u) { exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX); s->control_command = NULL; + cgroup_context_done(&s->cgroup_context); + swap_unwatch_control_pid(s); unit_unwatch_timer(u, &s->timer_watch); @@ -291,10 +294,6 @@ static int swap_load(Unit *u) { if (r < 0) return r; - r = unit_add_default_cgroups(u); - if (r < 0) - return r; - if (UNIT(s)->default_dependencies) { r = swap_add_default_dependencies(s); if (r < 0) @@ -593,6 +592,8 @@ static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) { assert(c); assert(_pid); + unit_realize_cgroup(UNIT(s)); + r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch); if (r < 0) goto fail; @@ -606,9 +607,8 @@ static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) { true, true, UNIT(s)->manager->confirm_spawn, - UNIT(s)->cgroup_bondings, - UNIT(s)->cgroup_attributes, - NULL, + UNIT(s)->cgroup_mask, + UNIT(s)->cgroup_path, UNIT(s)->id, NULL, &pid); @@ -1327,8 +1327,9 @@ const UnitVTable swap_vtable = { "Swap\0" "Install\0", + .private_section = "Swap", .exec_context_offset = offsetof(Swap, exec_context), - .exec_section = "Swap", + .cgroup_context_offset = offsetof(Swap, cgroup_context), .no_alias = true, .no_instances = true, diff --git a/src/core/swap.h b/src/core/swap.h index 121889d1d5..7e48c0ea3b 100644 --- a/src/core/swap.h +++ b/src/core/swap.h @@ -88,6 +88,7 @@ struct Swap { ExecCommand exec_command[_SWAP_EXEC_COMMAND_MAX]; ExecContext exec_context; KillContext kill_context; + CGroupContext cgroup_context; SwapState state, deserialized_state; diff --git a/src/core/unit.c b/src/core/unit.c index f75045dc48..0dcf85b5e0 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -44,7 +44,6 @@ #include "special.h" #include "cgroup-util.h" #include "missing.h" -#include "cgroup-attr.h" #include "mkdir.h" #include "label.h" #include "fileio-label.h" @@ -402,9 +401,10 @@ void unit_free(Unit *u) { u->manager->n_in_gc_queue--; } - cgroup_bonding_free_list(u->cgroup_bondings, u->manager->n_reloading <= 0); - cgroup_attribute_free_list(u->cgroup_attributes); + if (u->in_cgroup_queue) + LIST_REMOVE(Unit, cgroup_queue, u->manager->cgroup_queue, u); + free(u->cgroup_path); free(u->description); strv_free(u->documentation); free(u->fragment_path); @@ -673,7 +673,10 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { "%s\tInactive Enter Timestamp: %s\n" "%s\tGC Check Good: %s\n" "%s\tNeed Daemon Reload: %s\n" - "%s\tSlice: %s\n", + "%s\tSlice: %s\n" + "%s\tCGroup: %s\n" + "%s\tCGroup realized: %s\n" + "%s\tCGroup mask: 0x%x\n", prefix, u->id, prefix, unit_description(u), prefix, strna(u->instance), @@ -685,7 +688,10 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { prefix, strna(format_timestamp(timestamp4, sizeof(timestamp4), u->inactive_enter_timestamp.realtime)), prefix, yes_no(unit_check_gc(u)), prefix, yes_no(unit_need_daemon_reload(u)), - prefix, strna(unit_slice_name(u))); + prefix, strna(unit_slice_name(u)), + prefix, strna(u->cgroup_path), + prefix, yes_no(u->cgroup_realized), + prefix, u->cgroup_mask); SET_FOREACH(t, u->names, i) fprintf(f, "%s\tName: %s\n", prefix, t); @@ -735,8 +741,6 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { } if (u->load_state == UNIT_LOADED) { - CGroupBonding *b; - CGroupAttribute *a; fprintf(f, "%s\tStopWhenUnneeded: %s\n" @@ -754,20 +758,6 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { prefix, yes_no(u->ignore_on_isolate), prefix, yes_no(u->ignore_on_snapshot)); - LIST_FOREACH(by_unit, b, u->cgroup_bondings) - fprintf(f, "%s\tControlGroup: %s:%s\n", - prefix, b->controller, b->path); - - LIST_FOREACH(by_unit, a, u->cgroup_attributes) { - _cleanup_free_ char *v = NULL; - - if (a->semantics && a->semantics->map_write) - a->semantics->map_write(a->semantics, a->value, &v); - - fprintf(f, "%s\tControlGroupAttribute: %s %s \"%s\"\n", - prefix, a->controller, a->name, v ? v : a->value); - } - if (UNIT_VTABLE(u)->dump) UNIT_VTABLE(u)->dump(u, f, prefix2); @@ -795,14 +785,16 @@ int unit_load_fragment_and_dropin(Unit *u) { assert(u); /* Load a .service file */ - if ((r = unit_load_fragment(u)) < 0) + r = unit_load_fragment(u); + if (r < 0) return r; if (u->load_state == UNIT_STUB) return -ENOENT; /* Load drop-in directory data */ - if ((r = unit_load_dropin(unit_follow_merge(u))) < 0) + r = unit_load_dropin(unit_follow_merge(u)); + if (r < 0) return r; return 0; @@ -818,14 +810,16 @@ int unit_load_fragment_and_dropin_optional(Unit *u) { * something can be loaded or not doesn't matter. */ /* Load a .service file */ - if ((r = unit_load_fragment(u)) < 0) + r = unit_load_fragment(u); + if (r < 0) return r; if (u->load_state == UNIT_STUB) u->load_state = UNIT_LOADED; /* Load drop-in directory data */ - if ((r = unit_load_dropin(unit_follow_merge(u))) < 0) + r = unit_load_dropin(unit_follow_merge(u)); + if (r < 0) return r; return 0; @@ -880,8 +874,12 @@ static int unit_add_default_dependencies(Unit *u) { return r; } - if (u->default_dependencies && UNIT_ISSET(u->slice)) { - r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_WANTS, UNIT_DEREF(u->slice), true); + if (u->default_dependencies && unit_get_cgroup_context(u)) { + if (UNIT_ISSET(u->slice)) + r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_WANTS, UNIT_DEREF(u->slice), true); + else + r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_WANTS, SPECIAL_ROOT_SLICE, NULL, true); + if (r < 0) return r; } @@ -1382,7 +1380,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su } if (UNIT_IS_INACTIVE_OR_FAILED(ns)) - cgroup_bonding_trim_list(u->cgroup_bondings, true); + unit_destroy_cgroup(u); if (UNIT_IS_INACTIVE_OR_FAILED(os) != UNIT_IS_INACTIVE_OR_FAILED(ns)) { ExecContext *ec = unit_get_exec_context(u); @@ -1952,51 +1950,16 @@ char *unit_dbus_path(Unit *u) { return unit_dbus_path_from_name(u->id); } -static int unit_add_cgroup(Unit *u, CGroupBonding *b) { - int r; - - assert(u); - assert(b); - - assert(b->path); - - if (!b->controller) { - b->controller = strdup(SYSTEMD_CGROUP_CONTROLLER); - if (!b->controller) - return log_oom(); - - b->ours = true; - } - - /* Ensure this hasn't been added yet */ - assert(!b->unit); - - if (streq(b->controller, SYSTEMD_CGROUP_CONTROLLER)) { - CGroupBonding *l; - - l = hashmap_get(u->manager->cgroup_bondings, b->path); - LIST_PREPEND(CGroupBonding, by_path, l, b); - - r = hashmap_replace(u->manager->cgroup_bondings, b->path, l); - if (r < 0) { - LIST_REMOVE(CGroupBonding, by_path, l, b); - return r; - } - } - - LIST_PREPEND(CGroupBonding, by_unit, u->cgroup_bondings, b); - b->unit = u; - - return 0; -} - char *unit_default_cgroup_path(Unit *u) { _cleanup_free_ char *escaped_instance = NULL, *slice = NULL; int r; assert(u); - if (UNIT_ISSET(u->slice)) { + if (unit_has_name(u, SPECIAL_ROOT_SLICE)) + return strdup(u->manager->cgroup_root); + + if (UNIT_ISSET(u->slice) && !unit_has_name(UNIT_DEREF(u->slice), SPECIAL_ROOT_SLICE)) { r = cg_slice_to_path(UNIT_DEREF(u->slice)->id, &slice); if (r < 0) return NULL; @@ -2026,148 +1989,6 @@ char *unit_default_cgroup_path(Unit *u) { escaped_instance, NULL); } -int unit_add_cgroup_from_text(Unit *u, const char *name, bool overwrite, CGroupBonding **ret) { - char *controller = NULL, *path = NULL; - CGroupBonding *b = NULL; - bool ours = false; - int r; - - assert(u); - assert(name); - - r = cg_split_spec(name, &controller, &path); - if (r < 0) - return r; - - if (!path) { - path = unit_default_cgroup_path(u); - ours = true; - } - - if (!controller) { - controller = strdup("systemd"); - ours = true; - } - - if (!path || !controller) { - free(path); - free(controller); - return log_oom(); - } - - if (streq(controller, "systemd")) { - /* Within the systemd unit hierarchy we do not allow changes. */ - if (path_startswith(path, "/system")) { - log_warning_unit(u->id, "Manipulating the systemd:/system cgroup hierarchy is not permitted."); - free(path); - free(controller); - return -EPERM; - } - } - - b = cgroup_bonding_find_list(u->cgroup_bondings, controller); - if (b) { - if (streq(path, b->path)) { - free(path); - free(controller); - - if (ret) - *ret = b; - return 0; - } - - if (overwrite && !b->essential) { - free(controller); - - free(b->path); - b->path = path; - - b->ours = ours; - b->realized = false; - - if (ret) - *ret = b; - - return 1; - } - - r = -EEXIST; - b = NULL; - goto fail; - } - - b = new0(CGroupBonding, 1); - if (!b) { - r = -ENOMEM; - goto fail; - } - - b->controller = controller; - b->path = path; - b->ours = ours; - b->essential = streq(controller, SYSTEMD_CGROUP_CONTROLLER); - - r = unit_add_cgroup(u, b); - if (r < 0) - goto fail; - - if (ret) - *ret = b; - - return 1; - -fail: - free(path); - free(controller); - free(b); - - return r; -} - -static int unit_add_one_default_cgroup(Unit *u, const char *controller) { - CGroupBonding *b = NULL; - int r = -ENOMEM; - - assert(u); - - if (controller && !cg_controller_is_valid(controller, true)) - return -EINVAL; - - if (!controller) - controller = SYSTEMD_CGROUP_CONTROLLER; - - if (cgroup_bonding_find_list(u->cgroup_bondings, controller)) - return 0; - - b = new0(CGroupBonding, 1); - if (!b) - return -ENOMEM; - - b->controller = strdup(controller); - if (!b->controller) - goto fail; - - b->path = unit_default_cgroup_path(u); - if (!b->path) - goto fail; - - b->ours = true; - b->essential = streq(controller, SYSTEMD_CGROUP_CONTROLLER); - - r = unit_add_cgroup(u, b); - if (r < 0) - goto fail; - - return 1; - -fail: - free(b->path); - free(b->controller); - free(b); - - return r; -} - int unit_add_default_slice(Unit *u) { Unit *slice; int r; @@ -2177,10 +1998,10 @@ int unit_add_default_slice(Unit *u) { if (UNIT_ISSET(u->slice)) return 0; - if (u->manager->running_as != SYSTEMD_SYSTEM) + if (!unit_get_cgroup_context(u)) return 0; - r = manager_load_unit(u->manager, SPECIAL_SYSTEM_SLICE, NULL, NULL, &slice); + r = manager_load_unit(u->manager, u->manager->running_as == SYSTEMD_SYSTEM ? SPECIAL_SYSTEM_SLICE : SPECIAL_ROOT_SLICE, NULL, NULL, &slice); if (r < 0) return r; @@ -2197,148 +2018,6 @@ const char *unit_slice_name(Unit *u) { return UNIT_DEREF(u->slice)->id; } -int unit_add_default_cgroups(Unit *u) { - CGroupAttribute *a; - char **c; - int r; - - assert(u); - - /* Adds in the default cgroups, if they weren't specified - * otherwise. */ - - if (!u->manager->cgroup_root) - return 0; - - r = unit_add_one_default_cgroup(u, NULL); - if (r < 0) - return r; - - STRV_FOREACH(c, u->manager->default_controllers) - unit_add_one_default_cgroup(u, *c); - - LIST_FOREACH(by_unit, a, u->cgroup_attributes) - unit_add_one_default_cgroup(u, a->controller); - - return 0; -} - -CGroupBonding* unit_get_default_cgroup(Unit *u) { - assert(u); - - return cgroup_bonding_find_list(u->cgroup_bondings, NULL); -} - -int unit_add_cgroup_attribute( - Unit *u, - const CGroupSemantics *semantics, - const char *controller, - const char *name, - const char *value, - CGroupAttribute **ret) { - - _cleanup_free_ char *c = NULL; - CGroupAttribute *a; - int r; - - assert(u); - assert(value); - - if (semantics) { - /* Semantics always take precedence */ - if (semantics->name) - name = semantics->name; - - if (semantics->controller) - controller = semantics->controller; - } - - if (!name) - return -EINVAL; - - if (!controller) { - r = cg_controller_from_attr(name, &c); - if (r < 0) - return -EINVAL; - - controller = c; - } - - if (!controller || - streq(controller, SYSTEMD_CGROUP_CONTROLLER) || - streq(controller, "systemd")) - return -EINVAL; - - if (!filename_is_safe(name)) - return -EINVAL; - - if (!cg_controller_is_valid(controller, false)) - return -EINVAL; - - /* Check if this attribute already exists. Note that we will - * explicitly check for the value here too, as there are - * attributes which accept multiple values. */ - a = cgroup_attribute_find_list(u->cgroup_attributes, controller, name); - if (a) { - if (streq(value, a->value)) { - /* Exactly the same value is always OK, let's ignore this */ - if (ret) - *ret = a; - - return 0; - } - - if (semantics && !semantics->multiple) { - char *v; - - /* If this is a single-item entry, we can - * simply patch the existing attribute */ - - v = strdup(value); - if (!v) - return -ENOMEM; - - free(a->value); - a->value = v; - - if (ret) - *ret = a; - return 1; - } - } - - a = new0(CGroupAttribute, 1); - if (!a) - return -ENOMEM; - - if (c) { - a->controller = c; - c = NULL; - } else - a->controller = strdup(controller); - - a->name = strdup(name); - a->value = strdup(value); - - if (!a->controller || !a->name || !a->value) { - free(a->controller); - free(a->name); - free(a->value); - free(a); - return -ENOMEM; - } - - a->semantics = semantics; - a->unit = u; - - LIST_PREPEND(CGroupAttribute, by_unit, u->cgroup_attributes, a); - - if (ret) - *ret = a; - - return 1; -} - int unit_load_related_unit(Unit *u, const char *type, Unit **_found) { _cleanup_free_ char *t = NULL; int r; @@ -2804,7 +2483,7 @@ int unit_kill_common( if (kill(main_pid, signo) < 0) r = -errno; - if (who == KILL_ALL) { + if (who == KILL_ALL && u->cgroup_path) { _cleanup_set_free_ Set *pid_set = NULL; int q; @@ -2825,7 +2504,7 @@ int unit_kill_common( return q; } - q = cgroup_bonding_kill_list(u->cgroup_bondings, signo, false, false, pid_set, NULL); + q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, signo, false, true, false, pid_set); if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT) r = q; } @@ -2924,7 +2603,6 @@ int unit_exec_context_defaults(Unit *u, ExecContext *c) { assert(c); /* This only copies in the ones that need memory */ - for (i = 0; i < RLIMIT_NLIMITS; i++) if (u->manager->rlimit[i] && !c->rlimit[i]) { c->rlimit[i] = newdup(struct rlimit, u->manager->rlimit[i], 1); @@ -2954,6 +2632,16 @@ ExecContext *unit_get_exec_context(Unit *u) { return (ExecContext*) ((uint8_t*) u + offset); } +CGroupContext *unit_get_cgroup_context(Unit *u) { + size_t offset; + + offset = UNIT_VTABLE(u)->cgroup_context_offset; + if (offset <= 0) + return NULL; + + return (CGroupContext*) ((uint8_t*) u + offset); +} + static int drop_in_file(Unit *u, bool runtime, const char *name, char **_p, char **_q) { char *p, *q; int r; @@ -3072,7 +2760,7 @@ int unit_kill_context( wait_for_exit = true; } - if (c->kill_mode == KILL_CONTROL_GROUP) { + if (c->kill_mode == KILL_CONTROL_GROUP && u->cgroup_path) { _cleanup_set_free_ Set *pid_set = NULL; pid_set = set_new(trivial_hash_func, trivial_compare_func); @@ -3092,7 +2780,7 @@ int unit_kill_context( return r; } - r = cgroup_bonding_kill_list(u->cgroup_bondings, sig, true, false, pid_set, NULL); + r = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, sig, true, true, false, pid_set); if (r < 0) { if (r != -EAGAIN && r != -ESRCH && r != -ENOENT) log_warning_unit(u->id, "Failed to kill control group: %s", strerror(-r)); diff --git a/src/core/unit.h b/src/core/unit.h index da52101bd2..fbcaabe167 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -37,10 +37,10 @@ typedef struct UnitStatusMessageFormats UnitStatusMessageFormats; #include "list.h" #include "socket-util.h" #include "execute.h" +#include "cgroup.h" #include "condition.h" #include "install.h" #include "unit-name.h" -#include "cgroup-semantics.h" enum UnitActiveState { UNIT_ACTIVE, @@ -115,8 +115,6 @@ enum UnitDependency { #include "manager.h" #include "job.h" -#include "cgroup.h" -#include "cgroup-attr.h" struct UnitRef { /* Keeps tracks of references to a unit. This is useful so @@ -174,8 +172,9 @@ struct Unit { dual_timestamp inactive_enter_timestamp; /* Counterparts in the cgroup filesystem */ - CGroupBonding *cgroup_bondings; - CGroupAttribute *cgroup_attributes; + char *cgroup_path; + bool cgroup_realized; + CGroupControllerMask cgroup_mask; UnitRef slice; @@ -197,6 +196,9 @@ struct Unit { /* GC queue */ LIST_FIELDS(Unit, gc_queue); + /* CGroup realize members queue */ + LIST_FIELDS(Unit, cgroup_queue); + /* Used during GC sweeps */ unsigned gc_marker; @@ -243,6 +245,7 @@ struct Unit { bool in_dbus_queue:1; bool in_cleanup_queue:1; bool in_gc_queue:1; + bool in_cgroup_queue:1; bool sent_dbus_new_signal:1; @@ -277,8 +280,12 @@ struct UnitVTable { * ExecContext is found, if the unit type has that */ size_t exec_context_offset; - /* The name of the section with the exec settings of ExecContext */ - const char *exec_section; + /* If greater than 0, the offset into the object where + * CGroupContext is found, if the unit type has that */ + size_t cgroup_context_offset; + + /* The name of the configuration file section with the private settings of this unit*/ + const char *private_section; /* Config file sections this unit type understands, separated * by NUL chars */ @@ -350,7 +357,7 @@ struct UnitVTable { /* Called whenever any of the cgroups this unit watches for * ran empty */ - void (*cgroup_notify_empty)(Unit *u); + void (*notify_cgroup_empty)(Unit *u); /* Called whenever a process of this unit sends us a message */ void (*notify_message)(Unit *u, pid_t pid, char **tags); @@ -454,11 +461,6 @@ int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDep int unit_add_exec_dependencies(Unit *u, ExecContext *c); -int unit_add_cgroup_from_text(Unit *u, const char *name, bool overwrite, CGroupBonding **ret); -int unit_add_default_cgroups(Unit *u); -CGroupBonding* unit_get_default_cgroup(Unit *u); -int unit_add_cgroup_attribute(Unit *u, const CGroupSemantics *semantics, const char *controller, const char *name, const char *value, CGroupAttribute **ret); - int unit_choose_id(Unit *u, const char *name); int unit_set_description(Unit *u, const char *description); @@ -573,6 +575,7 @@ int unit_add_mount_links(Unit *u); int unit_exec_context_defaults(Unit *u, ExecContext *c); ExecContext *unit_get_exec_context(Unit *u) _pure_; +CGroupContext *unit_get_cgroup_context(Unit *u) _pure_; int unit_write_drop_in(Unit *u, bool runtime, const char *name, const char *data); int unit_remove_drop_in(Unit *u, bool runtime, const char *name); diff --git a/src/login/logind-machine.c b/src/login/logind-machine.c index 347e5aa022..0b35a9e2d0 100644 --- a/src/login/logind-machine.c +++ b/src/login/logind-machine.c @@ -223,7 +223,7 @@ static int machine_create_one_group(Machine *m, const char *controller, const ch r = -EINVAL; if (r < 0) { - r = cg_create(controller, path, NULL); + r = cg_create(controller, path); if (r < 0) return r; } diff --git a/src/login/logind-session.c b/src/login/logind-session.c index aba517d1f7..760425329b 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -472,12 +472,12 @@ static int session_create_one_group(Session *s, const char *controller, const ch r = -EINVAL; if (r < 0) { - r = cg_create(controller, path, NULL); + r = cg_create(controller, path); if (r < 0) return r; } - r = cg_set_task_access(controller, path, 0644, s->user->uid, s->user->gid, -1); + r = cg_set_task_access(controller, path, 0644, s->user->uid, s->user->gid); if (r >= 0) r = cg_set_group_access(controller, path, 0755, s->user->uid, s->user->gid); diff --git a/src/login/logind-user.c b/src/login/logind-user.c index fb0c9b75d7..9f7b924a24 100644 --- a/src/login/logind-user.c +++ b/src/login/logind-user.c @@ -349,7 +349,7 @@ static int user_create_cgroup(User *u) { return log_oom(); } - r = cg_create(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, NULL); + r = cg_create(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path); if (r < 0) { log_error("Failed to create cgroup "SYSTEMD_CGROUP_CONTROLLER":%s: %s", u->cgroup_path, strerror(-r)); return r; @@ -360,7 +360,7 @@ static int user_create_cgroup(User *u) { if (strv_contains(u->manager->reset_controllers, *k)) continue; - r = cg_create(*k, u->cgroup_path, NULL); + r = cg_create(*k, u->cgroup_path); if (r < 0) log_warning("Failed to create cgroup %s:%s: %s", *k, u->cgroup_path, strerror(-r)); } diff --git a/src/shared/cgroup-label.c b/src/shared/cgroup-label.c index 5b5163c250..574a7be3ee 100644 --- a/src/shared/cgroup-label.c +++ b/src/shared/cgroup-label.c @@ -36,15 +36,18 @@ #include "util.h" #include "mkdir.h" -int cg_create(const char *controller, const char *path, const char *suffix) { +/* This is split out since it needs label calls, either directly or + * indirectly. */ + +int cg_create(const char *controller, const char *path) { _cleanup_free_ char *fs = NULL; int r; - r = cg_get_path_and_check(controller, path, suffix, &fs); + r = cg_get_path_and_check(controller, path, NULL, &fs); if (r < 0) return r; - r = mkdir_parents_label(fs, 0755); + r = mkdir_parents_prefix("/sys/fs/cgroup", fs, 0755); if (r < 0) return r; @@ -64,7 +67,7 @@ int cg_create_and_attach(const char *controller, const char *path, pid_t pid) { assert(pid >= 0); - r = cg_create(controller, path, NULL); + r = cg_create(controller, path); if (r < 0) return r; diff --git a/src/shared/cgroup-show.c b/src/shared/cgroup-show.c index 83cc0731b8..e971f36190 100644 --- a/src/shared/cgroup-show.c +++ b/src/shared/cgroup-show.c @@ -241,7 +241,6 @@ static int show_extra_pids(const char *controller, const char *path, const char unsigned i, j; int r; - assert(controller); assert(path); if (n_pids <= 0) diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index 9cbc64a541..5816b7d4d6 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -132,7 +132,7 @@ int cg_read_subgroup(DIR *d, char **fn) { return 0; } -int cg_rmdir(const char *controller, const char *path, bool honour_sticky) { +int cg_rmdir(const char *controller, const char *path) { _cleanup_free_ char *p = NULL; int r; @@ -140,34 +140,6 @@ int cg_rmdir(const char *controller, const char *path, bool honour_sticky) { if (r < 0) return r; - if (honour_sticky) { - char *fn; - - /* If the sticky bit is set on cgroup.procs, don't - * remove the directory */ - - fn = strappend(p, "/cgroup.procs"); - if (!fn) - return -ENOMEM; - - r = file_is_priv_sticky(fn); - free(fn); - - if (r > 0) - return 0; - - /* Compatibility ... */ - fn = strappend(p, "/tasks"); - if (!fn) - return -ENOMEM; - - r = file_is_priv_sticky(fn); - free(fn); - - if (r > 0) - return 0; - } - r = rmdir(p); if (r < 0 && errno != ENOENT) return -errno; @@ -298,7 +270,7 @@ int cg_kill_recursive(const char *controller, const char *path, int sig, bool si ret = r; if (rem) { - r = cg_rmdir(controller, path, true); + r = cg_rmdir(controller, path); if (r < 0 && ret >= 0 && r != -ENOENT && r != -EBUSY) return r; } @@ -407,7 +379,14 @@ int cg_migrate(const char *cfrom, const char *pfrom, const char *cto, const char return ret; } -int cg_migrate_recursive(const char *cfrom, const char *pfrom, const char *cto, const char *pto, bool ignore_self, bool rem) { +int cg_migrate_recursive( + const char *cfrom, + const char *pfrom, + const char *cto, + const char *pto, + bool ignore_self, + bool rem) { + _cleanup_closedir_ DIR *d = NULL; int r, ret = 0; char *fn; @@ -448,7 +427,7 @@ int cg_migrate_recursive(const char *cfrom, const char *pfrom, const char *cto, ret = r; if (rem) { - r = cg_rmdir(cfrom, pfrom, true); + r = cg_rmdir(cfrom, pfrom); if (r < 0 && ret >= 0 && r != -ENOENT && r != -EBUSY) return r; } @@ -558,8 +537,9 @@ int cg_get_path_and_check(const char *controller, const char *path, const char * } static int trim_cb(const char *path, const struct stat *sb, int typeflag, struct FTW *ftwbuf) { - char *p; - bool is_sticky; + assert(path); + assert(sb); + assert(ftwbuf); if (typeflag != FTW_DP) return 0; @@ -567,31 +547,6 @@ static int trim_cb(const char *path, const struct stat *sb, int typeflag, struct if (ftwbuf->level < 1) return 0; - p = strappend(path, "/cgroup.procs"); - if (!p) { - errno = ENOMEM; - return 1; - } - - is_sticky = file_is_priv_sticky(p) > 0; - free(p); - - if (is_sticky) - return 0; - - /* Compatibility */ - p = strappend(path, "/tasks"); - if (!p) { - errno = ENOMEM; - return 1; - } - - is_sticky = file_is_priv_sticky(p) > 0; - free(p); - - if (is_sticky) - return 0; - rmdir(path); return 0; } @@ -611,28 +566,8 @@ int cg_trim(const char *controller, const char *path, bool delete_root) { r = errno ? -errno : -EIO; if (delete_root) { - bool is_sticky; - char *p; - - p = strappend(fs, "/cgroup.procs"); - if (!p) - return -ENOMEM; - - is_sticky = file_is_priv_sticky(p) > 0; - free(p); - - if (!is_sticky) { - p = strappend(fs, "/tasks"); - if (!p) - return -ENOMEM; - - is_sticky = file_is_priv_sticky(p) > 0; - free(p); - } - - if (!is_sticky) - if (rmdir(fs) < 0 && errno != ENOENT && r == 0) - return -errno; + if (rmdir(fs) < 0 && errno != ENOENT) + return -errno; } return r; @@ -699,15 +634,14 @@ int cg_set_task_access( const char *path, mode_t mode, uid_t uid, - gid_t gid, - int sticky) { + gid_t gid) { _cleanup_free_ char *fs = NULL, *procs = NULL; int r; assert(path); - if (mode == (mode_t) -1 && uid == (uid_t) -1 && gid == (gid_t) -1 && sticky < 0) + if (mode == (mode_t) -1 && uid == (uid_t) -1 && gid == (gid_t) -1) return 0; if (mode != (mode_t) -1) @@ -717,28 +651,6 @@ int cg_set_task_access( if (r < 0) return r; - if (sticky >= 0 && mode != (mode_t) -1) - /* Both mode and sticky param are passed */ - mode |= (sticky ? S_ISVTX : 0); - else if ((sticky >= 0 && mode == (mode_t) -1) || - (mode != (mode_t) -1 && sticky < 0)) { - struct stat st; - - /* Only one param is passed, hence read the current - * mode from the file itself */ - - r = lstat(fs, &st); - if (r < 0) - return -errno; - - if (mode == (mode_t) -1) - /* No mode set, we just shall set the sticky bit */ - mode = (st.st_mode & ~S_ISVTX) | (sticky ? S_ISVTX : 0); - else - /* Only mode set, leave sticky bit untouched */ - mode = (st.st_mode & ~0777) | mode; - } - r = chmod_and_chown(fs, mode, uid, gid); if (r < 0) return r; @@ -1688,3 +1600,148 @@ int cg_slice_to_path(const char *unit, char **ret) { return 0; } + +int cg_set_attribute(const char *controller, const char *path, const char *attribute, const char *value) { + _cleanup_free_ char *p = NULL; + int r; + + r = cg_get_path(controller, path, attribute, &p); + if (r < 0) + return r; + + return write_string_file(p, value); +} + +static const char mask_names[] = + "cpu\0" + "cpuacct\0" + "blkio\0" + "memory\0" + "devices\0"; + +int cg_create_with_mask(CGroupControllerMask mask, const char *path) { + CGroupControllerMask bit = 1; + const char *n; + int r; + + /* This one will create a cgroup in our private tree, but also + * duplicate it in the trees specified in mask, and remove it + * in all others */ + + /* First create the cgroup in our own hierarchy. */ + r = cg_create(SYSTEMD_CGROUP_CONTROLLER, path); + if (r < 0) + return r; + + /* Then, do the same in the other hierarchies */ + NULSTR_FOREACH(n, mask_names) { + if (bit & mask) + cg_create(n, path); + else + cg_trim(n, path, true); + + bit <<= 1; + } + + return r; +} + +int cg_attach_with_mask(CGroupControllerMask mask, const char *path, pid_t pid) { + CGroupControllerMask bit = 1; + const char *n; + int r; + + r = cg_attach(SYSTEMD_CGROUP_CONTROLLER, path, pid); + + NULSTR_FOREACH(n, mask_names) { + if (bit & mask) + cg_attach(n, path, pid); + else { + char prefix[strlen(path) + 1], *slash; + + /* OK, this one is a bit harder... Now we need + * to add to the closest parent cgroup we + * can find */ + strcpy(prefix, path); + while ((slash = strrchr(prefix, '/'))) { + int q; + *slash = 0; + + q = cg_attach(n, prefix, pid); + if (q >= 0) + break; + } + } + + bit <<= 1; + } + + return r; +} + +int cg_migrate_with_mask(CGroupControllerMask mask, const char *from, const char *to) { + CGroupControllerMask bit = 1; + const char *n; + int r; + + if (path_equal(from, to)) + return 0; + + r = cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, from, SYSTEMD_CGROUP_CONTROLLER, to, false, true); + + NULSTR_FOREACH(n, mask_names) { + if (bit & mask) + cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, to, n, to, false, false); + else { + char prefix[strlen(to) + 1], *slash; + + strcpy(prefix, to); + while ((slash = strrchr(prefix, '/'))) { + int q; + + *slash = 0; + + q = cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, to, n, prefix, false, false); + if (q >= 0) + break; + } + } + + bit <<= 1; + } + + return r; +} + +int cg_trim_with_mask(CGroupControllerMask mask, const char *path, bool delete_root) { + CGroupControllerMask bit = 1; + const char *n; + int r; + + r = cg_trim(SYSTEMD_CGROUP_CONTROLLER, path, delete_root); + if (r < 0) + return r; + + NULSTR_FOREACH(n, mask_names) { + if (bit & mask) + cg_trim(n, path, delete_root); + + bit <<= 1; + } + + return r; +} + +CGroupControllerMask cg_mask_supported(void) { + CGroupControllerMask bit = 1, mask = 0; + const char *n; + + NULSTR_FOREACH(n, mask_names) { + if (check_hierarchy(n) >= 0) + mask |= bit; + + bit <<= 1; + } + + return mask; +} diff --git a/src/shared/cgroup-util.h b/src/shared/cgroup-util.h index 2d00bb3fff..9883d941c2 100644 --- a/src/shared/cgroup-util.h +++ b/src/shared/cgroup-util.h @@ -28,6 +28,15 @@ #include "set.h" #include "def.h" +/* A bit mask of well known cgroup controllers */ +typedef enum CGroupControllerMask { + CGROUP_CPU = 1, + CGROUP_CPUACCT = 2, + CGROUP_BLKIO = 4, + CGROUP_MEMORY = 8, + CGROUP_DEVICE = 16 +} CGroupControllerMask; + /* * General rules: * @@ -67,15 +76,17 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **path); int cg_trim(const char *controller, const char *path, bool delete_root); -int cg_rmdir(const char *controller, const char *path, bool honour_sticky); +int cg_rmdir(const char *controller, const char *path); int cg_delete(const char *controller, const char *path); -int cg_create(const char *controller, const char *path, const char *suffix); +int cg_create(const char *controller, const char *path); int cg_attach(const char *controller, const char *path, pid_t pid); int cg_create_and_attach(const char *controller, const char *path, pid_t pid); +int cg_set_attribute(const char *controller, const char *path, const char *attribute, const char *value); + int cg_set_group_access(const char *controller, const char *path, mode_t mode, uid_t uid, gid_t gid); -int cg_set_task_access(const char *controller, const char *path, mode_t mode, uid_t uid, gid_t gid, int sticky); +int cg_set_task_access(const char *controller, const char *path, mode_t mode, uid_t uid, gid_t gid); int cg_install_release_agent(const char *controller, const char *agent); @@ -113,3 +124,10 @@ char *cg_unescape(const char *p) _pure_; bool cg_controller_is_valid(const char *p, bool allow_named); int cg_slice_to_path(const char *unit, char **ret); + +int cg_create_with_mask(CGroupControllerMask mask, const char *path); +int cg_attach_with_mask(CGroupControllerMask mask, const char *path, pid_t pid); +int cg_migrate_with_mask(CGroupControllerMask mask, const char *from, const char *to); +int cg_trim_with_mask(CGroupControllerMask mask, const char *path, bool delete_root); + +CGroupControllerMask cg_mask_supported(void); diff --git a/src/shared/fileio.c b/src/shared/fileio.c index ad068bf30d..dc13c9ee63 100644 --- a/src/shared/fileio.c +++ b/src/shared/fileio.c @@ -24,7 +24,6 @@ #include "util.h" #include "strv.h" - int write_string_to_file(FILE *f, const char *line) { errno = 0; fputs(line, f); diff --git a/src/shared/mkdir.c b/src/shared/mkdir.c index 0e51b64f69..e21a0f3989 100644 --- a/src/shared/mkdir.c +++ b/src/shared/mkdir.c @@ -26,15 +26,16 @@ #include #include -#include "mkdir.h" #include "label.h" #include "util.h" +#include "path-util.h" +#include "mkdir.h" int mkdir_label(const char *path, mode_t mode) { return label_mkdir(path, mode, true); } -static int makedir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid, bool apply) { +static int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, bool apply) { struct stat st; if (label_mkdir(path, mode, apply) >= 0) @@ -56,36 +57,50 @@ static int makedir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid, boo } int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid) { - return makedir_safe(path, mode, uid, gid, false); + return mkdir_safe_internal(path, mode, uid, gid, false); } int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid) { - return makedir_safe(path, mode, uid, gid, true); + return mkdir_safe_internal(path, mode, uid, gid, true); } -static int makedir_parents(const char *path, mode_t mode, bool apply) { +static int is_dir(const char* path) { struct stat st; + + if (stat(path, &st) < 0) + return -errno; + + return S_ISDIR(st.st_mode); +} + +static int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, bool apply) { const char *p, *e; + int r; assert(path); + if (prefix && !path_startswith(path, prefix)) + return -ENOTDIR; + /* return immediately if directory exists */ e = strrchr(path, '/'); if (!e) return -EINVAL; + + if (e == path) + return 0; + p = strndupa(path, e - path); - if (stat(p, &st) >= 0) { - if ((st.st_mode & S_IFMT) == S_IFDIR) - return 0; - else - return -ENOTDIR; - } + r = is_dir(p); + if (r > 0) + return 0; + if (r == 0) + return -ENOTDIR; /* create every parent directory in the path, except the last component */ p = path + strspn(path, "/"); for (;;) { - int r; - char *t; + char t[strlen(path) + 1]; e = p + strcspn(p, "/"); p = e + strspn(e, "/"); @@ -95,39 +110,36 @@ static int makedir_parents(const char *path, mode_t mode, bool apply) { if (*p == 0) return 0; - t = strndup(path, e - path); - if (!t) - return -ENOMEM; + memcpy(t, path, e - path); + t[e-path] = 0; - r = label_mkdir(t, mode, apply); - free(t); + if (prefix && path_startswith(prefix, t)) + continue; + r = label_mkdir(t, mode, apply); if (r < 0 && errno != EEXIST) return -errno; } } int mkdir_parents(const char *path, mode_t mode) { - return makedir_parents(path, mode, false); + return mkdir_parents_internal(NULL, path, mode, false); } int mkdir_parents_label(const char *path, mode_t mode) { - return makedir_parents(path, mode, true); + return mkdir_parents_internal(NULL, path, mode, true); } -static int is_dir(const char* path) { - struct stat st; - if (stat(path, &st) < 0) - return -errno; - return S_ISDIR(st.st_mode); +int mkdir_parents_prefix(const char *prefix, const char *path, mode_t mode) { + return mkdir_parents_internal(prefix, path, mode, true); } -static int makedir_p(const char *path, mode_t mode, bool apply) { +static int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, bool apply) { int r; /* Like mkdir -p */ - r = makedir_parents(path, mode, apply); + r = mkdir_parents_internal(prefix, path, mode, apply); if (r < 0) return r; @@ -139,9 +151,13 @@ static int makedir_p(const char *path, mode_t mode, bool apply) { } int mkdir_p(const char *path, mode_t mode) { - return makedir_p(path, mode, false); + return mkdir_p_internal(NULL, path, mode, false); } int mkdir_p_label(const char *path, mode_t mode) { - return makedir_p(path, mode, true); + return mkdir_p_internal(NULL, path, mode, true); +} + +int mkdir_p_prefix(const char *prefix, const char *path, mode_t mode) { + return mkdir_p_internal(prefix, path, mode, false); } diff --git a/src/shared/mkdir.h b/src/shared/mkdir.h index ce1c35e9ba..3d39b2910f 100644 --- a/src/shared/mkdir.h +++ b/src/shared/mkdir.h @@ -22,11 +22,19 @@ along with systemd; If not, see . ***/ +#include + int mkdir_label(const char *path, mode_t mode); + int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid); int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid); + int mkdir_parents(const char *path, mode_t mode); int mkdir_parents_label(const char *path, mode_t mode); +int mkdir_parents_prefix(const char *prefix, const char *path, mode_t mode); + int mkdir_p(const char *path, mode_t mode); int mkdir_p_label(const char *path, mode_t mode); +int mkdir_p_prefix(const char *prefix, const char *path, mode_t mode); + #endif diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 24543ee06d..a4f8f2326e 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -2378,150 +2378,6 @@ static int kill_unit(DBusConnection *bus, char **args) { return 0; } -static int set_cgroup(DBusConnection *bus, char **args) { - _cleanup_free_ char *n = NULL; - const char *method, *runtime; - char **argument; - int r; - - assert(bus); - assert(args); - - method = - streq(args[0], "set-cgroup") ? "SetUnitControlGroup" : - streq(args[0], "unset-cgroup") ? "UnsetUnitControlGroup" - : "UnsetUnitControlGroupAttribute"; - - runtime = arg_runtime ? "runtime" : "persistent"; - - n = unit_name_mangle(args[1]); - if (!n) - return log_oom(); - - STRV_FOREACH(argument, args + 2) { - - r = bus_method_call_with_reply( - bus, - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - method, - NULL, - NULL, - DBUS_TYPE_STRING, &n, - DBUS_TYPE_STRING, argument, - DBUS_TYPE_STRING, &runtime, - DBUS_TYPE_INVALID); - if (r < 0) - return r; - } - - return 0; -} - -static int set_cgroup_attr(DBusConnection *bus, char **args) { - _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL; - DBusError error; - DBusMessageIter iter; - _cleanup_free_ char *n = NULL; - const char *runtime; - int r; - - assert(bus); - assert(args); - - dbus_error_init(&error); - - runtime = arg_runtime ? "runtime" : "persistent"; - - n = unit_name_mangle(args[1]); - if (!n) - return log_oom(); - - m = dbus_message_new_method_call( - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - "SetUnitControlGroupAttribute"); - if (!m) - return log_oom(); - - dbus_message_iter_init_append(m, &iter); - if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &n) || - !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &args[2])) - return log_oom(); - - r = bus_append_strv_iter(&iter, args + 3); - if (r < 0) - return log_oom(); - - if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &runtime)) - return log_oom(); - - reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); - if (!reply) { - log_error("Failed to issue method call: %s", bus_error_message(&error)); - dbus_error_free(&error); - return -EIO; - } - - return 0; -} - -static int get_cgroup_attr(DBusConnection *bus, char **args) { - _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; - _cleanup_free_ char *n = NULL; - char **argument; - int r; - - assert(bus); - assert(args); - - n = unit_name_mangle(args[1]); - if (!n) - return log_oom(); - - STRV_FOREACH(argument, args + 2) { - _cleanup_strv_free_ char **list = NULL; - DBusMessageIter iter; - char **a; - - r = bus_method_call_with_reply( - bus, - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - "GetUnitControlGroupAttribute", - &reply, - NULL, - DBUS_TYPE_STRING, &n, - DBUS_TYPE_STRING, argument, - DBUS_TYPE_INVALID); - if (r < 0) - return r; - - if (!dbus_message_iter_init(reply, &iter)) { - log_error("Failed to initialize iterator."); - return -EIO; - } - - r = bus_parse_strv_iter(&iter, &list); - if (r < 0) { - log_error("Failed to parse value list."); - return r; - } - - STRV_FOREACH(a, list) { - if (endswith(*a, "\n")) - fputs(*a, stdout); - else - puts(*a); - } - } - - return 0; -} - typedef struct ExecStatusInfo { char *name; @@ -2639,7 +2495,7 @@ typedef struct UnitStatusInfo { const char *fragment_path; const char *source_path; - const char *default_control_group; + const char *control_group; char **dropin_paths; @@ -2922,11 +2778,11 @@ static void print_status_info(UnitStatusInfo *i) { if (i->status_text) printf(" Status: \"%s\"\n", i->status_text); - if (i->default_control_group && - (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_by_spec(i->default_control_group, false) == 0)) { + if (i->control_group && + (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_by_spec(i->control_group, false) == 0)) { unsigned c; - printf(" CGroup: %s\n", i->default_control_group); + printf(" CGroup: %s\n", i->control_group); if (arg_transport != TRANSPORT_SSH) { unsigned k = 0; @@ -2945,7 +2801,7 @@ static void print_status_info(UnitStatusInfo *i) { if (i->control_pid > 0) extra[k++] = i->control_pid; - show_cgroup_and_extra_by_spec(i->default_control_group, prefix, + show_cgroup_and_extra_by_spec(i->control_group, prefix, c, false, extra, k, flags); } } @@ -3054,8 +2910,12 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn i->fragment_path = s; else if (streq(name, "SourcePath")) i->source_path = s; +#ifndef LEGACY else if (streq(name, "DefaultControlGroup")) - i->default_control_group = s; + i->control_group = s; +#endif + else if (streq(name, "ControlGroup")) + i->control_group = s; else if (streq(name, "StatusText")) i->status_text = s; else if (streq(name, "PIDFile")) @@ -3457,8 +3317,44 @@ static int print_property(const char *name, DBusMessageIter *iter) { } return 0; + + } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "DeviceAllow")) { + DBusMessageIter sub, sub2; + + dbus_message_iter_recurse(iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { + const char *path, *rwm; + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &rwm, false) >= 0) + printf("%s=%s %s\n", name, strna(path), strna(rwm)); + + dbus_message_iter_next(&sub); + } + return 0; + + } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) { + DBusMessageIter sub, sub2; + + dbus_message_iter_recurse(iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { + const char *path; + uint64_t bandwidth; + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &bandwidth, false) >= 0) + printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth); + + dbus_message_iter_next(&sub); + } + return 0; } + break; } @@ -4667,14 +4563,6 @@ static int systemctl_help(void) { " help [NAME...|PID...] Show manual for one or more units\n" " reset-failed [NAME...] Reset failed state for all, one, or more\n" " units\n" - " get-cgroup-attr [NAME] [ATTR] ...\n" - " Get control group attrubute\n" - " set-cgroup-attr [NAME] [ATTR] [VALUE] ...\n" - " Set control group attribute\n" - " unset-cgroup-attr [NAME] [ATTR...]\n" - " Unset control group attribute\n" - " set-cgroup [NAME] [CGROUP...] Add unit to a control group\n" - " unset-cgroup [NAME] [CGROUP...] Remove unit from a control group\n" " load [NAME...] Load one or more units\n" " list-dependencies [NAME] Recursively show units which are required\n" " or wanted by this unit or by which this\n" @@ -5711,11 +5599,6 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */ { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */ { "isolate", EQUAL, 2, start_unit }, - { "set-cgroup", MORE, 3, set_cgroup }, - { "unset-cgroup", MORE, 3, set_cgroup }, - { "get-cgroup-attr", MORE, 3, get_cgroup_attr }, - { "set-cgroup-attr", MORE, 4, set_cgroup_attr }, - { "unset-cgroup-attr", MORE, 3, set_cgroup }, { "kill", MORE, 2, kill_unit }, { "is-active", MORE, 2, check_unit_active }, { "check", MORE, 2, check_unit_active }, diff --git a/src/test/test-cgroup.c b/src/test/test-cgroup.c index 3a3489d6a2..2a0ce27206 100644 --- a/src/test/test-cgroup.c +++ b/src/test/test-cgroup.c @@ -31,10 +31,10 @@ int main(int argc, char*argv[]) { char *path; char *c, *p; - assert_se(cg_create(SYSTEMD_CGROUP_CONTROLLER, "/test-a", NULL) == 0); - assert_se(cg_create(SYSTEMD_CGROUP_CONTROLLER, "/test-a", NULL) == 0); - assert_se(cg_create(SYSTEMD_CGROUP_CONTROLLER, "/test-b", NULL) == 0); - assert_se(cg_create(SYSTEMD_CGROUP_CONTROLLER, "/test-b/test-c", NULL) == 0); + assert_se(cg_create(SYSTEMD_CGROUP_CONTROLLER, "/test-a") == 0); + assert_se(cg_create(SYSTEMD_CGROUP_CONTROLLER, "/test-a") == 0); + assert_se(cg_create(SYSTEMD_CGROUP_CONTROLLER, "/test-b") == 0); + assert_se(cg_create(SYSTEMD_CGROUP_CONTROLLER, "/test-b/test-c") == 0); assert_se(cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, "/test-b", 0) == 0); assert_se(cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, getpid(), &path) == 0); diff --git a/units/-.slice b/units/-.slice new file mode 100644 index 0000000000..ac82c35874 --- /dev/null +++ b/units/-.slice @@ -0,0 +1,12 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Root Slice +Documentation=man:systemd.special(7) +DefaultDependencies=no +Before=slices.target diff --git a/units/slices.target b/units/slices.target index cbfdba0055..a29310c047 100644 --- a/units/slices.target +++ b/units/slices.target @@ -8,5 +8,5 @@ [Unit] Description=Slices Documentation=man:systemd.special(7) -Wants=system.slice -After=system.slice +Wants=-.slice system.slice +After=-.slice system.slice diff --git a/units/system.slice b/units/system.slice index 8281fe58f6..c0e3df9d0f 100644 --- a/units/system.slice +++ b/units/system.slice @@ -10,3 +10,5 @@ Description=System Slice Documentation=man:systemd.special(7) DefaultDependencies=no Before=slices.target +Wants=-.slice +After=-.slice -- cgit v1.2.1 From 3b18ae6866043ac4d96ee9bcada1a42469c80129 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Wed, 26 Jun 2013 13:43:16 +0200 Subject: test: Add list testcase --- .gitignore | 1 + Makefile.am | 12 +++++- src/shared/list.h | 2 +- src/test/test-list.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 src/test/test-list.c diff --git a/.gitignore b/.gitignore index d1e2ae9915..866d8eba0b 100644 --- a/.gitignore +++ b/.gitignore @@ -116,6 +116,7 @@ /test-journal-syslog /test-journal-verify /test-libudev +/test-list /test-log /test-login /test-loopback diff --git a/Makefile.am b/Makefile.am index 12254e39a8..c64934efa5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1098,7 +1098,8 @@ tests += \ test-prioq \ test-fileio \ test-time \ - test-hashmap + test-hashmap \ + test-list EXTRA_DIST += \ test/sched_idle_bad.service \ @@ -1202,6 +1203,15 @@ test_hashmap_CFLAGS = \ test_hashmap_LDADD = \ libsystemd-core.la +test_list_SOURCES = \ + src/test/test-list.c + +test_list_CFLAGS = \ + $(AM_CFLAGS) + +test_list_LDADD = \ + libsystemd-core.la + test_prioq_SOURCES = \ src/test/test-prioq.c diff --git a/src/shared/list.h b/src/shared/list.h index 96d6237974..476757460a 100644 --- a/src/shared/list.h +++ b/src/shared/list.h @@ -81,7 +81,7 @@ (head) = _item; \ } while (false) -/* Find the head of the list */ +/* Find the tail of the list */ #define LIST_FIND_TAIL(t,name,item,tail) \ do { \ t *_item = (item); \ diff --git a/src/test/test-list.c b/src/test/test-list.c new file mode 100644 index 0000000000..2710504765 --- /dev/null +++ b/src/test/test-list.c @@ -0,0 +1,109 @@ +/*** + This file is part of systemd + + Copyright 2013 Jan Janssen + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include "list.h" +#include "util.h" + +int main(int argc, const char *argv[]) { + size_t i; + typedef struct list_item { + LIST_FIELDS(struct list_item, item); + } list_item; + LIST_HEAD(list_item, head); + list_item items[4]; + list_item *cursor; + + LIST_HEAD_INIT(list_item, head); + assert_se(head == NULL); + + for (i = 0; i < ELEMENTSOF(items); i++) { + LIST_INIT(list_item, item, &items[i]); + assert_se(LIST_JUST_US(item, &items[i])); + LIST_PREPEND(list_item, item, head, &items[i]); + } + + assert_se(!LIST_JUST_US(item, head)); + + assert_se(items[0].item_next == NULL); + assert_se(items[1].item_next == &items[0]); + assert_se(items[2].item_next == &items[1]); + assert_se(items[3].item_next == &items[2]); + + assert_se(items[0].item_prev == &items[1]); + assert_se(items[1].item_prev == &items[2]); + assert_se(items[2].item_prev == &items[3]); + assert_se(items[3].item_prev == NULL); + + LIST_FIND_HEAD(list_item, item, &items[0], cursor); + assert_se(cursor == &items[3]); + + LIST_FIND_TAIL(list_item, item, &items[3], cursor); + assert_se(cursor == &items[0]); + + LIST_REMOVE(list_item, item, head, &items[1]); + assert_se(LIST_JUST_US(item, &items[1])); + + assert_se(items[0].item_next == NULL); + assert_se(items[2].item_next == &items[0]); + assert_se(items[3].item_next == &items[2]); + + assert_se(items[0].item_prev == &items[2]); + assert_se(items[2].item_prev == &items[3]); + assert_se(items[3].item_prev == NULL); + + LIST_INSERT_AFTER(list_item, item, head, &items[3], &items[1]); + assert_se(items[0].item_next == NULL); + assert_se(items[2].item_next == &items[0]); + assert_se(items[1].item_next == &items[2]); + assert_se(items[3].item_next == &items[1]); + + assert_se(items[0].item_prev == &items[2]); + assert_se(items[2].item_prev == &items[1]); + assert_se(items[1].item_prev == &items[3]); + assert_se(items[3].item_prev == NULL); + + LIST_REMOVE(list_item, item, head, &items[0]); + assert_se(LIST_JUST_US(item, &items[0])); + + assert_se(items[2].item_next == NULL); + assert_se(items[1].item_next == &items[2]); + assert_se(items[3].item_next == &items[1]); + + assert_se(items[2].item_prev == &items[1]); + assert_se(items[1].item_prev == &items[3]); + assert_se(items[3].item_prev == NULL); + + LIST_REMOVE(list_item, item, head, &items[1]); + assert_se(LIST_JUST_US(item, &items[1])); + + assert_se(items[2].item_next == NULL); + assert_se(items[3].item_next == &items[2]); + + assert_se(items[2].item_prev == &items[3]); + assert_se(items[3].item_prev == NULL); + + LIST_REMOVE(list_item, item, head, &items[2]); + assert_se(LIST_JUST_US(item, &items[2])); + assert_se(LIST_JUST_US(item, head)); + + LIST_REMOVE(list_item, item, head, &items[3]); + assert_se(LIST_JUST_US(item, &items[3])); + + return 0; +} -- cgit v1.2.1 From aae72d6fa0910891aa446ec43c548512987d453a Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Thu, 27 Jun 2013 16:24:02 +0200 Subject: journal-verify: Use proper printf placeholder --- src/journal/journal-verify.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c index 781b1ee1de..3405811534 100644 --- a/src/journal/journal-verify.c +++ b/src/journal/journal-verify.c @@ -67,7 +67,7 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o } if (le64toh(o->object.size) - offsetof(DataObject, payload) <= 0) { - log_error(OFSfmt": bad object size (<= %"PRIu64"): %"PRIu64, + log_error(OFSfmt": bad object size (<= %zu): %"PRIu64, offset, offsetof(DataObject, payload), le64toh(o->object.size)); @@ -120,7 +120,7 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o case OBJECT_FIELD: if (le64toh(o->object.size) - offsetof(FieldObject, payload) <= 0) { - log_error(OFSfmt": bad field size (<= %"PRIu64"): %"PRIu64, + log_error(OFSfmt": bad field size (<= %zu): %"PRIu64, offset, offsetof(FieldObject, payload), le64toh(o->object.size)); @@ -139,7 +139,7 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o case OBJECT_ENTRY: if ((le64toh(o->object.size) - offsetof(EntryObject, items)) % sizeof(EntryItem) != 0) { - log_error(OFSfmt": bad entry size (<= %"PRIu64"): %"PRIu64, + log_error(OFSfmt": bad entry size (<= %zu): %"PRIu64, offset, offsetof(EntryObject, items), le64toh(o->object.size)); -- cgit v1.2.1 From 8e2af478402414f060bbc16e1b4bbe7de1779c13 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 27 Jun 2013 21:14:56 +0200 Subject: dbus: add infrastructure for changing multiple properties at once on units and hook some cgroup attributes up to it This introduces two bus calls to make runtime changes to selected bus properties, optionally with persistence. This currently hooks this up only for three cgroup atributes, but this brings the infrastructure to add more changable attributes. This allows setting multiple attributes at once, and takes an array rather than a dictionary of properties, in order to implement simple resetting of lists using the same approach as when they are sourced from unit files. This means, that list properties are appended to by this call, unless they are first reset via assigning the empty list. --- TODO | 4 ++ src/core/dbus-cgroup.c | 62 +++++++++++++++++++++++++++ src/core/dbus-cgroup.h | 2 + src/core/dbus-manager.c | 42 ++++++++++++++++-- src/core/dbus-slice.c | 30 ++++++++++++- src/core/dbus-slice.h | 3 ++ src/core/dbus-unit.c | 88 ++++++++++++++++++++++++++++++++++++++ src/core/dbus-unit.h | 20 +++------ src/core/slice.c | 2 + src/core/unit.c | 25 +++++++---- src/core/unit.h | 16 ++++++- src/systemctl/systemctl.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++ 12 files changed, 371 insertions(+), 29 deletions(-) diff --git a/TODO b/TODO index a61fa92b68..7098833881 100644 --- a/TODO +++ b/TODO @@ -28,6 +28,10 @@ Fedora 19: Features: +* implement system-wide DefaultCPUAccounting=1 switch (and similar for blockio, memory, fair scheduling?) + +* handle jointly mounted controllers correctly + * split out CreateMachine into systemd-machined * "transient" units, i.e units that are not sourced from disk but diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c index 08ee9c8db4..f7d1dd12ad 100644 --- a/src/core/dbus-cgroup.c +++ b/src/core/dbus-cgroup.c @@ -137,3 +137,65 @@ const BusProperty bus_cgroup_context_properties[] = { { "DeviceAllow", bus_cgroup_append_device_allow, "a(ss)", 0 }, {} }; + +int bus_cgroup_set_property( + Unit *u, + CGroupContext *c, + const char *name, + DBusMessageIter *i, + UnitSetPropertiesMode mode, + DBusError *error) { + + assert(name); + assert(u); + assert(c); + assert(i); + + if (streq(name, "CPUAccounting")) { + dbus_bool_t b; + + if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_BOOLEAN) + return -EINVAL; + + if (mode != UNIT_CHECK) { + dbus_message_iter_get_basic(i, &b); + + c->cpu_accounting = b; + unit_write_drop_in(u, mode, "cpu-accounting", b ? "CPUAccounting=yes" : "CPUAccounting=no"); + } + + return 1; + + } else if (streq(name, "BlockIOAccounting")) { + dbus_bool_t b; + + if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_BOOLEAN) + return -EINVAL; + + if (mode != UNIT_CHECK) { + dbus_message_iter_get_basic(i, &b); + + c->blockio_accounting = b; + unit_write_drop_in(u, mode, "block-io-accounting", b ? "BlockIOAccounting=yes" : "BlockIOAccounting=no"); + } + + return 1; + } else if (streq(name, "MemoryAccounting")) { + dbus_bool_t b; + + if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_BOOLEAN) + return -EINVAL; + + if (mode != UNIT_CHECK) { + dbus_message_iter_get_basic(i, &b); + + c->blockio_accounting = b; + unit_write_drop_in(u, mode, "memory-accounting", b ? "MemoryAccounting=yes" : "MemoryAccounting=no"); + } + + return 1; + } + + + return 0; +} diff --git a/src/core/dbus-cgroup.h b/src/core/dbus-cgroup.h index a0a7a7771e..c5908dd976 100644 --- a/src/core/dbus-cgroup.h +++ b/src/core/dbus-cgroup.h @@ -42,3 +42,5 @@ " \n" extern const BusProperty bus_cgroup_context_properties[]; + +int bus_cgroup_set_property(Unit *u, CGroupContext *c, const char *name, DBusMessageIter *i, UnitSetPropertiesMode mode, DBusError *error); diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index c081ff5d16..353cb22867 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -228,12 +228,17 @@ " \n" \ " \n" \ " \n" \ - " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ - " \n" \ - " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ " \n" #define BUS_MANAGER_INTERFACE_SIGNALS \ @@ -1725,13 +1730,42 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, goto oom; r = unit_file_get_default(scope, NULL, &default_target); - if (r < 0) return bus_send_error_reply(connection, message, NULL, r); if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &default_target, DBUS_TYPE_INVALID)) { goto oom; } + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "SetUnitProperties")) { + DBusMessageIter iter; + dbus_bool_t runtime; + const char *name; + Unit *u; + + if (!dbus_message_iter_init(message, &iter)) + goto oom; + + if (bus_iter_get_basic_and_next(&iter, DBUS_TYPE_STRING, &name, true) < 0 || + bus_iter_get_basic_and_next(&iter, DBUS_TYPE_BOOLEAN, &runtime, true) < 0) + return bus_send_error_reply(connection, message, NULL, -EINVAL); + + u = manager_get_unit(m, name); + if (!u) { + dbus_set_error(&error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name); + return bus_send_error_reply(connection, message, &error, -ENOENT); + } + + SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "start"); + + r = bus_unit_set_properties(u, &iter, runtime ? UNIT_RUNTIME : UNIT_PERSISTENT, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + } else { const BusBoundProperties bps[] = { { "org.freedesktop.systemd1.Manager", bus_systemd_properties, systemd_property_string }, diff --git a/src/core/dbus-slice.c b/src/core/dbus-slice.c index 8243305848..db356adf30 100644 --- a/src/core/dbus-slice.c +++ b/src/core/dbus-slice.c @@ -53,10 +53,38 @@ DBusHandlerResult bus_slice_message_handler(Unit *u, DBusConnection *c, DBusMess const BusBoundProperties bps[] = { { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, { "org.freedesktop.systemd1.Slice", bus_cgroup_context_properties, &s->cgroup_context }, - { NULL, } + {} }; SELINUX_UNIT_ACCESS_CHECK(u, c, message, "status"); return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps); } + +int bus_slice_set_property( + Unit *u, + const char *name, + DBusMessageIter *i, + UnitSetPropertiesMode mode, + DBusError *error) { + + Slice *s = SLICE(u); + int r; + + assert(name); + assert(u); + assert(i); + + r = bus_cgroup_set_property(u, &s->cgroup_context, name, i, mode, error); + if (r != 0) + return r; + + return 0; +} + +int bus_slice_commit_properties(Unit *u) { + assert(u); + + unit_realize_cgroup(u); + return 0; +} diff --git a/src/core/dbus-slice.h b/src/core/dbus-slice.h index 7e7e29982d..c5ac473763 100644 --- a/src/core/dbus-slice.h +++ b/src/core/dbus-slice.h @@ -27,4 +27,7 @@ DBusHandlerResult bus_slice_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); +int bus_slice_set_property(Unit *u, const char *name, DBusMessageIter *i, UnitSetPropertiesMode mode, DBusError *error); +int bus_slice_commit_properties(Unit *u); + extern const char bus_slice_interface[]; diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index cbd41342f4..1611da0172 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -403,6 +403,25 @@ static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusConnection *conn reply = dbus_message_new_method_return(message); if (!reply) goto oom; + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "SetProperties")) { + DBusMessageIter iter; + dbus_bool_t runtime; + + if (!dbus_message_iter_init(message, &iter)) + goto oom; + + if (bus_iter_get_basic_and_next(&iter, DBUS_TYPE_BOOLEAN, &runtime, true) < 0) + return bus_send_error_reply(connection, message, NULL, -EINVAL); + + SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "start"); + + r = bus_unit_set_properties(u, &iter, runtime ? UNIT_RUNTIME : UNIT_PERSISTENT, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; } else if (UNIT_VTABLE(u)->bus_message_handler) return UNIT_VTABLE(u)->bus_message_handler(u, connection, message); @@ -745,6 +764,75 @@ oom: return DBUS_HANDLER_RESULT_NEED_MEMORY; } +int bus_unit_set_properties(Unit *u, DBusMessageIter *iter, UnitSetPropertiesMode mode, DBusError *error) { + bool for_real = false; + DBusMessageIter sub; + unsigned n = 0; + int r; + + assert(u); + assert(iter); + + /* We iterate through the array twice. First run we just check + * if all passed data is valid, second run actually applies + * it. This is to implement transaction-like behaviour without + * actually providing full transactions. */ + + if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(iter) != DBUS_TYPE_STRUCT) + return -EINVAL; + + dbus_message_iter_recurse(iter, &sub); + + for (;;) { + DBusMessageIter sub2, sub3; + const char *name; + + if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_INVALID) { + + if (for_real) + break; + + /* Reached EOF. Let's try again, and this time for realz... */ + dbus_message_iter_recurse(iter, &sub); + for_real = true; + continue; + } + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) + return -EINVAL; + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0 || + dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_VARIANT) + return -EINVAL; + + if (!UNIT_VTABLE(u)->bus_set_property) { + dbus_set_error(error, DBUS_ERROR_PROPERTY_READ_ONLY, "Objects of this type do not support setting properties."); + return -ENOENT; + } + + dbus_message_iter_recurse(&sub2, &sub3); + r = UNIT_VTABLE(u)->bus_set_property(u, name, &sub3, for_real ? mode : UNIT_CHECK, error); + if (r < 0) + return r; + if (r == 0) { + dbus_set_error(error, DBUS_ERROR_PROPERTY_READ_ONLY, "Cannot set property %s, or unknown property.", name); + return -ENOENT; + } + + dbus_message_iter_next(&sub); + + n += for_real; + } + + if (n > 0 && UNIT_VTABLE(u)->bus_commit_properties) + UNIT_VTABLE(u)->bus_commit_properties(u); + + return 0; +} + const BusProperty bus_unit_properties[] = { { "Id", bus_property_append_string, "s", offsetof(Unit, id), true }, { "Names", bus_unit_append_names, "as", 0 }, diff --git a/src/core/dbus-unit.h b/src/core/dbus-unit.h index 1e226ef451..2fd56f25c3 100644 --- a/src/core/dbus-unit.h +++ b/src/core/dbus-unit.h @@ -61,6 +61,10 @@ " \n" \ " \n" \ " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ @@ -135,19 +139,9 @@ extern const BusProperty bus_unit_properties[]; void bus_unit_send_change_signal(Unit *u); void bus_unit_send_removed_signal(Unit *u); -DBusHandlerResult bus_unit_queue_job( - DBusConnection *connection, - DBusMessage *message, - Unit *u, - JobType type, - JobMode mode, - bool reload_if_possible); - -int bus_unit_cgroup_set(Unit *u, DBusMessageIter *iter); -int bus_unit_cgroup_unset(Unit *u, DBusMessageIter *iter); -int bus_unit_cgroup_attribute_get(Unit *u, DBusMessageIter *iter, char ***_result); -int bus_unit_cgroup_attribute_set(Unit *u, DBusMessageIter *iter); -int bus_unit_cgroup_attribute_unset(Unit *u, DBusMessageIter *iter); +DBusHandlerResult bus_unit_queue_job(DBusConnection *connection, DBusMessage *message, Unit *u, JobType type, JobMode mode, bool reload_if_possible); + +int bus_unit_set_properties(Unit *u, DBusMessageIter *i, UnitSetPropertiesMode mode, DBusError *error); extern const DBusObjectPathVTable bus_unit_vtable; diff --git a/src/core/slice.c b/src/core/slice.c index df2d91e473..557f829088 100644 --- a/src/core/slice.c +++ b/src/core/slice.c @@ -304,6 +304,8 @@ const UnitVTable slice_vtable = { .bus_interface = "org.freedesktop.systemd1.Slice", .bus_message_handler = bus_slice_message_handler, + .bus_set_property = bus_slice_set_property, + .bus_commit_properties = bus_slice_commit_properties, .status_message_formats = { .finished_start_job = { diff --git a/src/core/unit.c b/src/core/unit.c index 0dcf85b5e0..be554dac20 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -2642,7 +2642,7 @@ CGroupContext *unit_get_cgroup_context(Unit *u) { return (CGroupContext*) ((uint8_t*) u + offset); } -static int drop_in_file(Unit *u, bool runtime, const char *name, char **_p, char **_q) { +static int drop_in_file(Unit *u, UnitSetPropertiesMode mode, const char *name, char **_p, char **_q) { char *p, *q; int r; @@ -2650,8 +2650,9 @@ static int drop_in_file(Unit *u, bool runtime, const char *name, char **_p, char assert(name); assert(_p); assert(_q); + assert(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)); - if (u->manager->running_as == SYSTEMD_USER && runtime) + if (u->manager->running_as == SYSTEMD_USER && !(mode & UNIT_PERSISTENT)) return -ENOTSUP; if (!filename_is_safe(name)) @@ -2667,10 +2668,10 @@ static int drop_in_file(Unit *u, bool runtime, const char *name, char **_p, char return -ENOENT; p = strjoin(c, "/", u->id, ".d", NULL); - } else if (runtime) - p = strjoin("/run/systemd/system/", u->id, ".d", NULL); - else + } else if (mode & UNIT_PERSISTENT) p = strjoin("/etc/systemd/system/", u->id, ".d", NULL); + else + p = strjoin("/run/systemd/system/", u->id, ".d", NULL); if (!p) return -ENOMEM; @@ -2685,13 +2686,16 @@ static int drop_in_file(Unit *u, bool runtime, const char *name, char **_p, char return 0; } -int unit_write_drop_in(Unit *u, bool runtime, const char *name, const char *data) { +int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) { _cleanup_free_ char *p = NULL, *q = NULL; int r; assert(u); - r = drop_in_file(u, runtime, name, &p, &q); + if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME))) + return 0; + + r = drop_in_file(u, mode, name, &p, &q); if (r < 0) return r; @@ -2699,13 +2703,16 @@ int unit_write_drop_in(Unit *u, bool runtime, const char *name, const char *data return write_string_file_atomic_label(q, data); } -int unit_remove_drop_in(Unit *u, bool runtime, const char *name) { +int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name) { _cleanup_free_ char *p = NULL, *q = NULL; int r; assert(u); - r = drop_in_file(u, runtime, name, &p, &q); + if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME))) + return 0; + + r = drop_in_file(u, mode, name, &p, &q); if (unlink(q) < 0) r = -errno; else diff --git a/src/core/unit.h b/src/core/unit.h index fbcaabe167..c344719b16 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -260,6 +260,12 @@ struct UnitStatusMessageFormats { const char *finished_stop_job[_JOB_RESULT_MAX]; }; +typedef enum UnitSetPropertiesMode { + UNIT_CHECK = 0, + UNIT_RUNTIME = 1, + UNIT_PERSISTENT = 2, +} UnitSetPropertiesMode; + #include "service.h" #include "timer.h" #include "socket.h" @@ -372,6 +378,12 @@ struct UnitVTable { /* Called for each message received on the bus */ DBusHandlerResult (*bus_message_handler)(Unit *u, DBusConnection *c, DBusMessage *message); + /* Called for each property that is being set */ + int (*bus_set_property)(Unit *u, const char *name, DBusMessageIter *i, UnitSetPropertiesMode mode, DBusError *error); + + /* Called after at least one property got changed to apply the necessary change */ + int (*bus_commit_properties)(Unit *u); + /* Return the unit this unit is following */ Unit *(*following)(Unit *u); @@ -577,8 +589,8 @@ int unit_exec_context_defaults(Unit *u, ExecContext *c); ExecContext *unit_get_exec_context(Unit *u) _pure_; CGroupContext *unit_get_cgroup_context(Unit *u) _pure_; -int unit_write_drop_in(Unit *u, bool runtime, const char *name, const char *data); -int unit_remove_drop_in(Unit *u, bool runtime, const char *name); +int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data); +int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name); int unit_kill_context(Unit *u, KillContext *c, bool sigkill, pid_t main_pid, pid_t control_pid, bool main_pid_alien); diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index a4f8f2326e..1f81bda7e3 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -3596,6 +3596,109 @@ static int show(DBusConnection *bus, char **args) { return ret; } +static int append_assignment(DBusMessageIter *iter, const char *assignment) { + const char *eq; + char *field; + DBusMessageIter sub; + int r; + + assert(iter); + assert(assignment); + + eq = strchr(assignment, '='); + if (!eq) { + log_error("Not an assignment: %s", assignment); + return -EINVAL; + } + + field = strndupa(assignment, eq - assignment); + eq ++; + + if (!dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &field)) + return log_oom(); + + if (streq(field, "CPUAccounting") || + streq(field, "MemoryAccounting") || + streq(field, "BlockIOAccounting")) { + dbus_bool_t b; + + r = parse_boolean(eq); + if (r < 0) { + log_error("Failed to parse boolean assignment %s.", assignment); + return -EINVAL; + } + + b = r; + if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "b", &sub) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_BOOLEAN, &b)) + return log_oom(); + } else { + log_error("Unknown assignment %s.", assignment); + return -EINVAL; + } + + if (!dbus_message_iter_close_container(iter, &sub)) + return log_oom(); + + return 0; +} + +static int set_property(DBusConnection *bus, char **args) { + + _cleanup_free_ DBusMessage *m = NULL, *reply = NULL; + DBusMessageIter iter, sub; + dbus_bool_t runtime; + DBusError error; + char **i; + int r; + + dbus_error_init(&error); + + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "SetUnitProperties"); + if (!m) + return log_oom(); + + dbus_message_iter_init_append(m, &iter); + + runtime = arg_runtime; + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &args[1]) || + !dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &runtime) || + !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(sv)", &sub)) + return log_oom(); + + STRV_FOREACH(i, args + 2) { + DBusMessageIter sub2; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2)) + return log_oom(); + + r = append_assignment(&sub2, *i); + if (r < 0) + return r; + + if (!dbus_message_iter_close_container(&sub, &sub2)) + return log_oom(); + + } + + if (!dbus_message_iter_close_container(&iter, &sub)) + return log_oom(); + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + dbus_error_free(&error); + return -EIO; + } + + return 0; +} + static int dump(DBusConnection *bus, char **args) { _cleanup_free_ DBusMessage *reply = NULL; DBusError error; @@ -4560,6 +4663,8 @@ static int systemctl_help(void) { " status [NAME...|PID...] Show runtime status of one or more units\n" " show [NAME...|JOB...] Show properties of one or more\n" " units/jobs or the manager\n" + " set-property [NAME] [ASSIGNMENT...]\n" + " Sets one or more properties of a unit\n" " help [NAME...|PID...] Show manual for one or more units\n" " reset-failed [NAME...] Reset failed state for all, one, or more\n" " units\n" @@ -5639,6 +5744,7 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError { "set-default", EQUAL, 2, enable_unit }, { "get-default", LESS, 1, get_default }, { "set-log-level", EQUAL, 2, set_log_level }, + { "set-property", MORE, 3, set_property }, }; int left; -- cgit v1.2.1 From b42defe3b8ed3947d85db654a6cdb1b9999f394d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 27 Jun 2013 21:50:35 +0200 Subject: dbus: make more cgroup attributes runtime settable --- TODO | 2 ++ src/core/dbus-cgroup.c | 86 ++++++++++++++++++++++++++++++++++++++++++----- src/core/unit.c | 19 +++++++++++ src/core/unit.h | 1 + src/systemctl/systemctl.c | 29 ++++++++++++++++ 5 files changed, 129 insertions(+), 8 deletions(-) diff --git a/TODO b/TODO index 7098833881..19fc2cd604 100644 --- a/TODO +++ b/TODO @@ -28,6 +28,8 @@ Fedora 19: Features: +* when reloading configuration, apply new cgroup configuration + * implement system-wide DefaultCPUAccounting=1 switch (and similar for blockio, memory, fair scheduling?) * handle jointly mounted controllers correctly diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c index f7d1dd12ad..ae360eae33 100644 --- a/src/core/dbus-cgroup.c +++ b/src/core/dbus-cgroup.c @@ -152,50 +152,120 @@ int bus_cgroup_set_property( assert(i); if (streq(name, "CPUAccounting")) { - dbus_bool_t b; if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_BOOLEAN) return -EINVAL; if (mode != UNIT_CHECK) { + dbus_bool_t b; dbus_message_iter_get_basic(i, &b); c->cpu_accounting = b; - unit_write_drop_in(u, mode, "cpu-accounting", b ? "CPUAccounting=yes" : "CPUAccounting=no"); + unit_write_drop_in_private_section(u, mode, "cpu-accounting", b ? "CPUAccounting=yes" : "CPUAccounting=no"); + } + + return 1; + + } else if (streq(name, "CPUShares")) { + uint64_t u64; + unsigned long ul; + + if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_UINT64) + return -EINVAL; + + dbus_message_iter_get_basic(i, &u64); + ul = (unsigned long) u64; + + if (u64 <= 0 || u64 != (uint64_t) ul) + return -EINVAL; + + if (mode != UNIT_CHECK) { + char buf[sizeof("CPUShares=") + DECIMAL_STR_MAX(ul)]; + c->cpu_shares = ul; + + sprintf(buf, "CPUShares=%lu", ul); + unit_write_drop_in_private_section(u, mode, "cpu-shares", buf); } return 1; } else if (streq(name, "BlockIOAccounting")) { - dbus_bool_t b; if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_BOOLEAN) return -EINVAL; if (mode != UNIT_CHECK) { + dbus_bool_t b; dbus_message_iter_get_basic(i, &b); c->blockio_accounting = b; - unit_write_drop_in(u, mode, "block-io-accounting", b ? "BlockIOAccounting=yes" : "BlockIOAccounting=no"); + unit_write_drop_in_private_section(u, mode, "block-io-accounting", b ? "BlockIOAccounting=yes" : "BlockIOAccounting=no"); } return 1; + + } else if (streq(name, "BlockIOWeight")) { + uint64_t u64; + unsigned long ul; + + if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_UINT64) + return -EINVAL; + + dbus_message_iter_get_basic(i, &u64); + ul = (unsigned long) u64; + + if (u64 < 10 || u64 > 1000) + return -EINVAL; + + if (mode != UNIT_CHECK) { + char buf[sizeof("BlockIOWeight=") + DECIMAL_STR_MAX(ul)]; + c->cpu_shares = ul; + + sprintf(buf, "BlockIOWeight=%lu", ul); + unit_write_drop_in_private_section(u, mode, "blockio-weight", buf); + } + + return 1; + } else if (streq(name, "MemoryAccounting")) { - dbus_bool_t b; if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_BOOLEAN) return -EINVAL; if (mode != UNIT_CHECK) { + dbus_bool_t b; dbus_message_iter_get_basic(i, &b); - c->blockio_accounting = b; - unit_write_drop_in(u, mode, "memory-accounting", b ? "MemoryAccounting=yes" : "MemoryAccounting=no"); + c->memory_accounting = b; + unit_write_drop_in_private_section(u, mode, "memory-accounting", b ? "MemoryAccounting=yes" : "MemoryAccounting=no"); } return 1; - } + } else if (streq(name, "MemoryLimit") || streq(name, "MemorySoftLimit")) { + + if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_UINT64) + return -EINVAL; + + if (mode != UNIT_CHECK) { + uint64_t limit; + char buf[sizeof("MemorySoftLimit=") + DECIMAL_STR_MAX(limit)]; + + dbus_message_iter_get_basic(i, &limit); + + if (streq(name, "MemoryLimit")) { + c->memory_limit = limit; + sprintf(buf, "MemoryLimit=%" PRIu64, limit); + unit_write_drop_in_private_section(u, mode, "memory-limit", buf); + } else { + c->memory_soft_limit = limit; + sprintf(buf, "MemorySoftLimit=%" PRIu64, limit); + unit_write_drop_in_private_section(u, mode, "memory-soft-limit", buf); + } + } + + return 1; + } return 0; } diff --git a/src/core/unit.c b/src/core/unit.c index be554dac20..211704e230 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -2691,6 +2691,8 @@ int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, co int r; assert(u); + assert(name); + assert(data); if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME))) return 0; @@ -2703,6 +2705,23 @@ int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, co return write_string_file_atomic_label(q, data); } +int unit_write_drop_in_private_section(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) { + _cleanup_free_ char *ndata = NULL; + + assert(u); + assert(name); + assert(data); + + if (!UNIT_VTABLE(u)->private_section) + return -EINVAL; + + ndata = strjoin("[", UNIT_VTABLE(u)->private_section, "]\n", data, NULL); + if (!ndata) + return -ENOMEM; + + return unit_write_drop_in(u, mode, name, ndata); +} + int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name) { _cleanup_free_ char *p = NULL, *q = NULL; int r; diff --git a/src/core/unit.h b/src/core/unit.h index c344719b16..be6abaff98 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -590,6 +590,7 @@ ExecContext *unit_get_exec_context(Unit *u) _pure_; CGroupContext *unit_get_cgroup_context(Unit *u) _pure_; int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data); +int unit_write_drop_in_private_section(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data); int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name); int unit_kill_context(Unit *u, KillContext *c, bool sigkill, pid_t main_pid, pid_t control_pid, bool main_pid_alien); diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 1f81bda7e3..5048b529e1 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -3632,6 +3632,35 @@ static int append_assignment(DBusMessageIter *iter, const char *assignment) { if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "b", &sub) || !dbus_message_iter_append_basic(&sub, DBUS_TYPE_BOOLEAN, &b)) return log_oom(); + + } else if (streq(field, "MemoryLimit") || streq(field, "MemorySoftLimit")) { + off_t bytes; + uint64_t u; + + r = parse_bytes(eq, &bytes); + if (r < 0) { + log_error("Failed to parse bytes specification %s", assignment); + return -EINVAL; + } + + u = bytes; + if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "t", &sub) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_UINT64, &u)) + return log_oom(); + + } else if (streq(field, "CPUShares") || streq(field, "BlockIOWeight")) { + uint64_t u; + + r = safe_atou64(eq, &u); + if (r < 0) { + log_error("Failed to parse %s value %s.", field, eq); + return -EINVAL; + } + + if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "t", &sub) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_UINT64, &u)) + return log_oom(); + } else { log_error("Unknown assignment %s.", assignment); return -EINVAL; -- cgit v1.2.1 From 7041efe9600e569da6089c36d00fa3ff58e33178 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 27 Jun 2013 23:13:17 +0200 Subject: dbus: make DeviceAllow=/DevicePolicy= writable --- TODO | 4 ++ src/core/dbus-cgroup.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++ src/systemctl/systemctl.c | 37 ++++++++++++++++ 3 files changed, 146 insertions(+) diff --git a/TODO b/TODO index 19fc2cd604..c34f1dab0f 100644 --- a/TODO +++ b/TODO @@ -28,6 +28,10 @@ Fedora 19: Features: +* split up BlockIOWeight= and BlockIODeviceWeight= + +* how to reset dynamically changed attributes sanely? + * when reloading configuration, apply new cgroup configuration * implement system-wide DefaultCPUAccounting=1 switch (and similar for blockio, memory, fair scheduling?) diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c index ae360eae33..cf05f04ea1 100644 --- a/src/core/dbus-cgroup.c +++ b/src/core/dbus-cgroup.c @@ -21,6 +21,7 @@ #include +#include "path-util.h" #include "dbus-cgroup.h" static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_cgroup_append_device_policy, cgroup_device_policy, CGroupDevicePolicy); @@ -264,6 +265,110 @@ int bus_cgroup_set_property( } } + return 1; + + } else if (streq(name, "DevicePolicy")) { + const char *policy; + CGroupDevicePolicy p; + + if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(i, &policy); + p = cgroup_device_policy_from_string(policy); + if (p < 0) + return -EINVAL; + + if (mode != UNIT_CHECK) { + char *buf; + + c->device_policy = p; + + buf = strappenda("DevicePolicy=", policy); + unit_write_drop_in_private_section(u, mode, "device-policy", buf); + } + + return 1; + + } else if (streq(name, "DeviceAllow")) { + DBusMessageIter sub; + unsigned n = 0; + + if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(i) != DBUS_TYPE_STRUCT) + return -EINVAL; + + dbus_message_iter_recurse(i, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { + DBusMessageIter sub2; + const char *path, *rwm; + CGroupDeviceAllow *a; + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &rwm, false) < 0) + return -EINVAL; + + if (!path_startswith(path, "/dev")) { + dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "DeviceAllow= requires device node"); + return -EINVAL; + } + + if (isempty(rwm)) + rwm = "rwm"; + + if (!in_charset(rwm, "rwm")) { + dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "DeviceAllow= requires combination of rwm flags"); + return -EINVAL; + } + + n++; + + if (mode != UNIT_CHECK) { + a = new0(CGroupDeviceAllow, 1); + if (!a) + return -ENOMEM; + + a->path = strdup(path); + if (!a->path) { + free(a); + return -ENOMEM; + } + + a->r = !!strchr(rwm, 'r'); + a->w = !!strchr(rwm, 'w'); + a->m = !!strchr(rwm, 'm'); + + LIST_PREPEND(CGroupDeviceAllow, device_allow, c->device_allow, a); + } + + dbus_message_iter_next(&sub); + } + + if (mode != UNIT_CHECK) { + _cleanup_free_ char *buf = NULL; + _cleanup_fclose_ FILE *f = NULL; + CGroupDeviceAllow *a; + size_t size = 0; + + if (n == 0) { + while (c->device_allow) + cgroup_context_free_device_allow(c, c->device_allow); + } + + f = open_memstream(&buf, &size); + if (!f) + return -ENOMEM; + + fputs("DeviceAllow=\n", f); + LIST_FOREACH(device_allow, a, c->device_allow) + fprintf(f, "DeviceAllow=%s %s%s%s\n", a->path, a->r ? "r" : "", a->w ? "w" : "", a->m ? "m" : ""); + + fflush(f); + unit_write_drop_in_private_section(u, mode, "device-allow", buf); + } + return 1; } diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 5048b529e1..ef1a079911 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -3661,6 +3661,43 @@ static int append_assignment(DBusMessageIter *iter, const char *assignment) { !dbus_message_iter_append_basic(&sub, DBUS_TYPE_UINT64, &u)) return log_oom(); + } else if (streq(field, "DevicePolicy")) { + + if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "s", &sub) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &eq)) + return log_oom(); + + } else if (streq(field, "DeviceAllow")) { + DBusMessageIter sub2; + + if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "a(ss)", &sub) || + !dbus_message_iter_open_container(&sub, DBUS_TYPE_ARRAY, "(ss)", &sub2)) + return log_oom(); + + if (!isempty(eq)) { + const char *path, *rwm; + DBusMessageIter sub3; + char *e; + + e = strchr(eq, ' '); + if (e) { + path = strndupa(eq, e - eq); + rwm = e+1; + } else { + path = eq; + rwm = ""; + } + + if (!dbus_message_iter_open_container(&sub2, DBUS_TYPE_STRUCT, NULL, &sub3) || + !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, &path) || + !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, &rwm) || + !dbus_message_iter_close_container(&sub2, &sub3)) + return log_oom(); + } + + if (!dbus_message_iter_close_container(&sub, &sub2)) + return log_oom(); + } else { log_error("Unknown assignment %s.", assignment); return -EINVAL; -- cgit v1.2.1 From 74c964d369b11bbf465c140c3f2dfcde2c7f5977 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 27 Jun 2013 23:21:21 +0200 Subject: dbus: hookup runtime property changes for mouns, services, sockets, swaps too --- src/core/dbus-mount.c | 28 ++++++++++++++++++++++++++++ src/core/dbus-mount.h | 3 +++ src/core/dbus-service.c | 28 ++++++++++++++++++++++++++++ src/core/dbus-service.h | 3 +++ src/core/dbus-socket.c | 28 ++++++++++++++++++++++++++++ src/core/dbus-socket.h | 3 +++ src/core/dbus-swap.c | 28 ++++++++++++++++++++++++++++ src/core/dbus-swap.h | 3 +++ src/core/mount.c | 2 ++ src/core/service.c | 2 ++ src/core/socket.c | 2 ++ src/core/swap.c | 2 ++ 12 files changed, 132 insertions(+) diff --git a/src/core/dbus-mount.c b/src/core/dbus-mount.c index 16b7afe8b7..ae04ab8c47 100644 --- a/src/core/dbus-mount.c +++ b/src/core/dbus-mount.c @@ -168,3 +168,31 @@ DBusHandlerResult bus_mount_message_handler(Unit *u, DBusConnection *c, DBusMess return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps ); } + +int bus_mount_set_property( + Unit *u, + const char *name, + DBusMessageIter *i, + UnitSetPropertiesMode mode, + DBusError *error) { + + Mount *m = MOUNT(u); + int r; + + assert(name); + assert(u); + assert(i); + + r = bus_cgroup_set_property(u, &m->cgroup_context, name, i, mode, error); + if (r != 0) + return r; + + return 0; +} + +int bus_mount_commit_properties(Unit *u) { + assert(u); + + unit_realize_cgroup(u); + return 0; +} diff --git a/src/core/dbus-mount.h b/src/core/dbus-mount.h index 8597394373..f4ec8b1625 100644 --- a/src/core/dbus-mount.h +++ b/src/core/dbus-mount.h @@ -27,5 +27,8 @@ DBusHandlerResult bus_mount_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); +int bus_mount_set_property(Unit *u, const char *name, DBusMessageIter *i, UnitSetPropertiesMode mode, DBusError *error); +int bus_mount_commit_properties(Unit *u); + extern const char bus_mount_interface[]; extern const char bus_mount_invalidating_properties[]; diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c index bbac1b8167..867ef7e54c 100644 --- a/src/core/dbus-service.c +++ b/src/core/dbus-service.c @@ -161,3 +161,31 @@ DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *connectio return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps); } + +int bus_service_set_property( + Unit *u, + const char *name, + DBusMessageIter *i, + UnitSetPropertiesMode mode, + DBusError *error) { + + Service *s = SERVICE(u); + int r; + + assert(name); + assert(u); + assert(i); + + r = bus_cgroup_set_property(u, &s->cgroup_context, name, i, mode, error); + if (r != 0) + return r; + + return 0; +} + +int bus_service_commit_properties(Unit *u) { + assert(u); + + unit_realize_cgroup(u); + return 0; +} diff --git a/src/core/dbus-service.h b/src/core/dbus-service.h index 143aed7ae5..9b9f13701c 100644 --- a/src/core/dbus-service.h +++ b/src/core/dbus-service.h @@ -27,5 +27,8 @@ DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); +int bus_service_set_property(Unit *u, const char *name, DBusMessageIter *i, UnitSetPropertiesMode mode, DBusError *error); +int bus_service_commit_properties(Unit *u); + extern const char bus_service_interface[]; extern const char bus_service_invalidating_properties[]; diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c index 7ec4f33924..7ef55ec711 100644 --- a/src/core/dbus-socket.c +++ b/src/core/dbus-socket.c @@ -213,3 +213,31 @@ DBusHandlerResult bus_socket_message_handler(Unit *u, DBusConnection *c, DBusMes return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps); } + +int bus_socket_set_property( + Unit *u, + const char *name, + DBusMessageIter *i, + UnitSetPropertiesMode mode, + DBusError *error) { + + Socket *s = SOCKET(u); + int r; + + assert(name); + assert(u); + assert(i); + + r = bus_cgroup_set_property(u, &s->cgroup_context, name, i, mode, error); + if (r != 0) + return r; + + return 0; +} + +int bus_socket_commit_properties(Unit *u) { + assert(u); + + unit_realize_cgroup(u); + return 0; +} diff --git a/src/core/dbus-socket.h b/src/core/dbus-socket.h index 5369b22e5e..eb035c1a94 100644 --- a/src/core/dbus-socket.h +++ b/src/core/dbus-socket.h @@ -27,5 +27,8 @@ DBusHandlerResult bus_socket_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); +int bus_socket_set_property(Unit *u, const char *name, DBusMessageIter *i, UnitSetPropertiesMode mode, DBusError *error); +int bus_socket_commit_properties(Unit *u); + extern const char bus_socket_interface[]; extern const char bus_socket_invalidating_properties[]; diff --git a/src/core/dbus-swap.c b/src/core/dbus-swap.c index 4ae1cd08e0..0248b4b391 100644 --- a/src/core/dbus-swap.c +++ b/src/core/dbus-swap.c @@ -115,3 +115,31 @@ DBusHandlerResult bus_swap_message_handler(Unit *u, DBusConnection *c, DBusMessa return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps); } + +int bus_swap_set_property( + Unit *u, + const char *name, + DBusMessageIter *i, + UnitSetPropertiesMode mode, + DBusError *error) { + + Swap *s = SWAP(u); + int r; + + assert(name); + assert(u); + assert(i); + + r = bus_cgroup_set_property(u, &s->cgroup_context, name, i, mode, error); + if (r != 0) + return r; + + return 0; +} + +int bus_swap_commit_properties(Unit *u) { + assert(u); + + unit_realize_cgroup(u); + return 0; +} diff --git a/src/core/dbus-swap.h b/src/core/dbus-swap.h index 41fe4447ff..9b586a1ad2 100644 --- a/src/core/dbus-swap.h +++ b/src/core/dbus-swap.h @@ -28,5 +28,8 @@ DBusHandlerResult bus_swap_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); +int bus_swap_set_property(Unit *u, const char *name, DBusMessageIter *i, UnitSetPropertiesMode mode, DBusError *error); +int bus_swap_commit_properties(Unit *u); + extern const char bus_swap_interface[]; extern const char bus_swap_invalidating_properties[]; diff --git a/src/core/mount.c b/src/core/mount.c index c71d51bfa4..c1af903b12 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -1916,6 +1916,8 @@ const UnitVTable mount_vtable = { .bus_interface = "org.freedesktop.systemd1.Mount", .bus_message_handler = bus_mount_message_handler, .bus_invalidating_properties = bus_mount_invalidating_properties, + .bus_set_property = bus_mount_set_property, + .bus_commit_properties = bus_mount_commit_properties, .enumerate = mount_enumerate, .shutdown = mount_shutdown, diff --git a/src/core/service.c b/src/core/service.c index 5fdbdb13a3..1dcd5cf443 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -3883,6 +3883,8 @@ const UnitVTable service_vtable = { .bus_interface = "org.freedesktop.systemd1.Service", .bus_message_handler = bus_service_message_handler, .bus_invalidating_properties = bus_service_invalidating_properties, + .bus_set_property = bus_service_set_property, + .bus_commit_properties = bus_service_commit_properties, #ifdef HAVE_SYSV_COMPAT .enumerate = service_enumerate, diff --git a/src/core/socket.c b/src/core/socket.c index c1bbaec447..2def0c9ead 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -2396,6 +2396,8 @@ const UnitVTable socket_vtable = { .bus_interface = "org.freedesktop.systemd1.Socket", .bus_message_handler = bus_socket_message_handler, .bus_invalidating_properties = bus_socket_invalidating_properties, + .bus_set_property = bus_socket_set_property, + .bus_commit_properties = bus_socket_commit_properties, .status_message_formats = { /*.starting_stopping = { diff --git a/src/core/swap.c b/src/core/swap.c index 0d4b4fa4f9..825503f3de 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -1363,6 +1363,8 @@ const UnitVTable swap_vtable = { .bus_interface = "org.freedesktop.systemd1.Swap", .bus_message_handler = bus_swap_message_handler, .bus_invalidating_properties = bus_swap_invalidating_properties, + .bus_set_property = bus_swap_set_property, + .bus_commit_properties = bus_swap_commit_properties, .following = swap_following, .following_set = swap_following_set, -- cgit v1.2.1 From 241da3287d0c16f79e2f415f17543599b3e73c85 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 28 Jun 2013 00:41:24 +0200 Subject: unit: make sure the dropins we write are high-priority --- TODO | 2 ++ src/core/dbus-manager.c | 4 ++-- src/core/dbus-unit.c | 3 +-- src/core/dbus-unit.h | 2 +- src/core/unit.c | 6 +++--- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/TODO b/TODO index c34f1dab0f..c729215077 100644 --- a/TODO +++ b/TODO @@ -28,6 +28,8 @@ Fedora 19: Features: +* make BlockIODeviceWeight=, BlockIODeviceBandwidth= runtime settable + * split up BlockIOWeight= and BlockIODeviceWeight= * how to reset dynamically changed attributes sanely? diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 353cb22867..c512265903 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -178,8 +178,8 @@ " \n" \ " \n" \ " \n" \ - " \n" \ - " \n" \ + " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index 1611da0172..b3724b679b 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -783,7 +783,6 @@ int bus_unit_set_properties(Unit *u, DBusMessageIter *iter, UnitSetPropertiesMod return -EINVAL; dbus_message_iter_recurse(iter, &sub); - for (;;) { DBusMessageIter sub2, sub3; const char *name; @@ -830,7 +829,7 @@ int bus_unit_set_properties(Unit *u, DBusMessageIter *iter, UnitSetPropertiesMod if (n > 0 && UNIT_VTABLE(u)->bus_commit_properties) UNIT_VTABLE(u)->bus_commit_properties(u); - return 0; + return n; } const BusProperty bus_unit_properties[] = { diff --git a/src/core/dbus-unit.h b/src/core/dbus-unit.h index 2fd56f25c3..1b42757b47 100644 --- a/src/core/dbus-unit.h +++ b/src/core/dbus-unit.h @@ -62,7 +62,7 @@ " \n" \ " \n" \ " \n" \ - " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ diff --git a/src/core/unit.c b/src/core/unit.c index 211704e230..afeb15c154 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -2675,7 +2675,7 @@ static int drop_in_file(Unit *u, UnitSetPropertiesMode mode, const char *name, c if (!p) return -ENOMEM; - q = strjoin(p, "/50-", name, ".conf", NULL); + q = strjoin(p, "/90-", name, ".conf", NULL); if (!q) { free(p); return -ENOMEM; @@ -2733,9 +2733,9 @@ int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name) { r = drop_in_file(u, mode, name, &p, &q); if (unlink(q) < 0) - r = -errno; + r = errno == ENOENT ? 0 : -errno; else - r = 0; + r = 1; rmdir(p); return r; -- cgit v1.2.1 From 1508e85878cff23a220b2ff8d6c71418e19797de Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 28 Jun 2013 03:47:40 +0200 Subject: dbus: fix minor memory leak when sending job change signals --- src/core/dbus-job.c | 42 +++++++++++++++++------------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/src/core/dbus-job.c b/src/core/dbus-job.c index 98ccfa62ec..a85d3185c2 100644 --- a/src/core/dbus-job.c +++ b/src/core/dbus-job.c @@ -261,55 +261,51 @@ static int job_send_message(Job *j, DBusMessage* (*new_message)(Job *j)) { } static DBusMessage* new_change_signal_message(Job *j) { - DBusMessage *m = NULL; - char *p = NULL; + _cleanup_free_ char *p = NULL; + DBusMessage *m; p = job_dbus_path(j); if (!p) - goto oom; + return NULL; if (j->sent_dbus_new_signal) { /* Send a properties changed signal */ m = bus_properties_changed_new(p, "org.freedesktop.systemd1.Job", INVALIDATING_PROPERTIES); if (!m) - goto oom; + return NULL; } else { /* Send a new signal */ m = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "JobNew"); if (!m) - goto oom; + return NULL; if (!dbus_message_append_args(m, DBUS_TYPE_UINT32, &j->id, DBUS_TYPE_OBJECT_PATH, &p, DBUS_TYPE_STRING, &j->unit->id, - DBUS_TYPE_INVALID)) - goto oom; + DBUS_TYPE_INVALID)) { + dbus_message_unref(m); + return NULL; + } } return m; - -oom: - if (m) - dbus_message_unref(m); - free(p); - return NULL; } static DBusMessage* new_removed_signal_message(Job *j) { - DBusMessage *m = NULL; - char *p = NULL; + _cleanup_free_ char *p = NULL; + DBusMessage *m; const char *r; p = job_dbus_path(j); if (!p) - goto oom; + return NULL; m = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "JobRemoved"); if (!m) - goto oom; + return NULL; r = job_result_to_string(j->result); @@ -318,16 +314,12 @@ static DBusMessage* new_removed_signal_message(Job *j) { DBUS_TYPE_OBJECT_PATH, &p, DBUS_TYPE_STRING, &j->unit->id, DBUS_TYPE_STRING, &r, - DBUS_TYPE_INVALID)) - goto oom; + DBUS_TYPE_INVALID)) { + dbus_message_unref(m); + return NULL; + } return m; - -oom: - if (m) - dbus_message_unref(m); - free(p); - return NULL; } void bus_job_send_change_signal(Job *j) { -- cgit v1.2.1 From c2756a68401102786be343712c0c35acbd73d28d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 28 Jun 2013 04:12:58 +0200 Subject: core: add transient units Transient units can be created via the bus API. They are configured via the method call parameters rather than on-disk files. They are subject to normal GC. Transient units currently may only be created for services (however, we will extend this), and currently only ExecStart= and the cgroup parameters can be configured (also to be extended). Transient units require a unique name, that previously had no configuration file on disk. A tool systemd-run is added that makes use of this functionality to run arbitrary command lines as transient services: $ systemd-run /bin/ping www.heise.de Will cause systemd to create a new transient service and run ping in it. --- .gitignore | 1 + Makefile.am | 15 ++++- TODO | 4 +- src/core/dbus-cgroup.c | 3 +- src/core/dbus-manager.c | 69 ++++++++++++++++++++- src/core/dbus-service.c | 128 ++++++++++++++++++++++++++++++++++++++ src/core/dbus-unit.c | 18 ++++-- src/core/dbus-unit.h | 3 +- src/core/job.c | 7 ++- src/core/load-fragment.c | 4 +- src/core/main.c | 4 +- src/core/manager.c | 16 ++++- src/core/mount.c | 2 +- src/core/service.c | 25 +++++--- src/core/transaction.c | 3 +- src/core/unit.c | 143 +++++++++++++++++++++++++++++++++++-------- src/core/unit.h | 8 +++ src/run/Makefile | 1 + src/run/run.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++ src/shared/unit-name.c | 2 +- src/shared/unit-name.h | 1 + 21 files changed, 559 insertions(+), 54 deletions(-) create mode 120000 src/run/Makefile create mode 100644 src/run/run.c diff --git a/.gitignore b/.gitignore index 866d8eba0b..53b1597f4a 100644 --- a/.gitignore +++ b/.gitignore @@ -65,6 +65,7 @@ /systemd-remount-api-vfs /systemd-remount-fs /systemd-reply-password +/systemd-run /systemd-shutdown /systemd-shutdownd /systemd-sleep diff --git a/Makefile.am b/Makefile.am index c64934efa5..3ab14753ac 100644 --- a/Makefile.am +++ b/Makefile.am @@ -290,7 +290,8 @@ bin_PROGRAMS = \ systemd-nspawn \ systemd-detect-virt \ systemd-delta \ - systemd-analyze + systemd-analyze \ + systemd-run dist_bin_SCRIPTS = \ src/kernel-install/kernel-install @@ -1715,6 +1716,18 @@ systemd_nspawn_LDADD = \ libsystemd-id128-internal.la \ libsystemd-bus.la +# ------------------------------------------------------------------------------ +systemd_run_SOURCES = \ + src/run/run.c + +systemd_run_LDADD = \ + libsystemd-label.la \ + libsystemd-capability.la \ + libsystemd-shared.la \ + libsystemd-daemon.la \ + libsystemd-id128-internal.la \ + libsystemd-bus.la + # ------------------------------------------------------------------------------ systemd_stdio_bridge_SOURCES = \ src/stdio-bridge/stdio-bridge.c diff --git a/TODO b/TODO index c729215077..055d9739d2 100644 --- a/TODO +++ b/TODO @@ -36,7 +36,9 @@ Features: * when reloading configuration, apply new cgroup configuration -* implement system-wide DefaultCPUAccounting=1 switch (and similar for blockio, memory, fair scheduling?) +* implement system-wide DefaultCPUAccounting=1 switch (and similar for blockio, memory?) + +* implement per-slice CPUFairScheduling=1 switch * handle jointly mounted controllers correctly diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c index cf05f04ea1..d1d35633c1 100644 --- a/src/core/dbus-cgroup.c +++ b/src/core/dbus-cgroup.c @@ -323,8 +323,6 @@ int bus_cgroup_set_property( return -EINVAL; } - n++; - if (mode != UNIT_CHECK) { a = new0(CGroupDeviceAllow, 1); if (!a) @@ -343,6 +341,7 @@ int bus_cgroup_set_property( LIST_PREPEND(CGroupDeviceAllow, device_allow, c->device_allow, a); } + n++; dbus_message_iter_next(&sub); } diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index c512265903..fe2f749803 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -239,6 +239,13 @@ " \n" \ " \n" \ " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ " \n" #define BUS_MANAGER_INTERFACE_SIGNALS \ @@ -1758,7 +1765,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "start"); - r = bus_unit_set_properties(u, &iter, runtime ? UNIT_RUNTIME : UNIT_PERSISTENT, &error); + r = bus_unit_set_properties(u, &iter, runtime ? UNIT_RUNTIME : UNIT_PERSISTENT, true, &error); if (r < 0) return bus_send_error_reply(connection, message, &error, r); @@ -1766,6 +1773,66 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, if (!reply) goto oom; + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "StartTransientUnit")) { + const char *name, *smode; + DBusMessageIter iter; + JobMode mode; + UnitType t; + Unit *u; + + if (!dbus_message_iter_init(message, &iter)) + goto oom; + + if (bus_iter_get_basic_and_next(&iter, DBUS_TYPE_STRING, &name, true) < 0 || + bus_iter_get_basic_and_next(&iter, DBUS_TYPE_STRING, &smode, true) < 0) + return bus_send_error_reply(connection, message, NULL, -EINVAL); + + t = unit_name_to_type(name); + if (t < 0) + return bus_send_error_reply(connection, message, NULL, -EINVAL); + if (!unit_vtable[t]->can_transient) { + dbus_set_error(&error, DBUS_ERROR_INVALID_ARGS, "Unit type %s does not support transient units.", unit_type_to_string(t)); + return bus_send_error_reply(connection, message, &error, -EINVAL); + } + + mode = job_mode_from_string(smode); + if (mode < 0) { + dbus_set_error(&error, BUS_ERROR_INVALID_JOB_MODE, "Job mode %s is invalid.", smode); + return bus_send_error_reply(connection, message, &error, -EINVAL); + } + + r = manager_load_unit(m, name, NULL, NULL, &u); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "start"); + + if (u->load_state != UNIT_NOT_FOUND || set_size(u->dependencies[UNIT_REFERENCED_BY]) > 0) { + dbus_set_error(&error, BUS_ERROR_UNIT_EXISTS, "Unit %s already exists.", name); + return bus_send_error_reply(connection, message, &error, -EEXIST); + } + + /* OK, the unit failed to load and is unreferenced, + * now let's fill in the transient data instead */ + r = unit_make_transient(u); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + /* Set our properties */ + r = bus_unit_set_properties(u, &iter, UNIT_RUNTIME, false, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + /* And load this stub fully */ + r = unit_load(u); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + manager_dispatch_load_queue(m); + + /* Finally, start it */ + return bus_unit_queue_job(connection, message, u, JOB_START, mode, false); + } else { const BusBoundProperties bps[] = { { "org.freedesktop.systemd1.Manager", bus_systemd_properties, systemd_property_string }, diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c index 867ef7e54c..c2031c3bf1 100644 --- a/src/core/dbus-service.c +++ b/src/core/dbus-service.c @@ -21,6 +21,8 @@ #include +#include "strv.h" +#include "path-util.h" #include "dbus-unit.h" #include "dbus-execute.h" #include "dbus-kill.h" @@ -162,6 +164,124 @@ DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *connectio return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps); } +static int bus_service_set_transient_properties( + Service *s, + const char *name, + DBusMessageIter *i, + UnitSetPropertiesMode mode, + DBusError *error) { + + int r; + + assert(name); + assert(s); + assert(i); + + if (streq(name, "ExecStart")) { + DBusMessageIter sub; + unsigned n = 0; + + if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(i) != DBUS_TYPE_STRUCT) + return -EINVAL; + + dbus_message_iter_recurse(i, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { + _cleanup_strv_free_ char **argv = NULL; + DBusMessageIter sub2; + dbus_bool_t ignore; + const char *path; + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, true) < 0) + return -EINVAL; + + if (!path_is_absolute(path)) { + dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "Path %s is not absolute.", path); + return -EINVAL; + } + + r = bus_parse_strv_iter(&sub2, &argv); + if (r < 0) + return r; + + dbus_message_iter_next(&sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_BOOLEAN, &ignore, false) < 0) + return -EINVAL; + + if (mode != UNIT_CHECK) { + ExecCommand *c; + + c = new0(ExecCommand, 1); + if (!c) + return -ENOMEM; + + c->path = strdup(path); + if (!c->path) { + free(c); + return -ENOMEM; + } + + c->argv = argv; + argv = NULL; + + c->ignore = ignore; + + path_kill_slashes(c->path); + exec_command_append_list(&s->exec_command[SERVICE_EXEC_START], c); + } + + n++; + dbus_message_iter_next(&sub); + } + + if (mode != UNIT_CHECK) { + _cleanup_free_ char *buf = NULL; + _cleanup_fclose_ FILE *f = NULL; + ExecCommand *c; + size_t size = 0; + + if (n == 0) { + exec_command_free_list(s->exec_command[SERVICE_EXEC_START]); + s->exec_command[SERVICE_EXEC_START] = NULL; + } + + f = open_memstream(&buf, &size); + if (!f) + return -ENOMEM; + + fputs("ExecStart=\n", f); + + LIST_FOREACH(command, c, s->exec_command[SERVICE_EXEC_START]) { + char **a; + fputs("ExecStart=", f); + + if (c->ignore) + fputc('-', f); + + fputc('@', f); + fputs(c->path, f); + + STRV_FOREACH(a, c->argv) { + fputc(' ', f); + fputs(*a, f); + } + + fputc('\n', f); + } + + fflush(f); + unit_write_drop_in_private_section(UNIT(s), mode, "exec-start", buf); + } + + return 1; + } + + return 0; +} + int bus_service_set_property( Unit *u, const char *name, @@ -180,6 +300,14 @@ int bus_service_set_property( if (r != 0) return r; + if (u->transient && u->load_state == UNIT_STUB) { + /* This is a transient unit, let's load a little more */ + + r = bus_service_set_transient_properties(s, name, i, mode, error); + if (r != 0) + return r; + } + return 0; } diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index b3724b679b..f518505750 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -415,7 +415,7 @@ static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusConnection *conn SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "start"); - r = bus_unit_set_properties(u, &iter, runtime ? UNIT_RUNTIME : UNIT_PERSISTENT, &error); + r = bus_unit_set_properties(u, &iter, runtime ? UNIT_RUNTIME : UNIT_PERSISTENT, true, &error); if (r < 0) return bus_send_error_reply(connection, message, &error, r); @@ -716,7 +716,7 @@ DBusHandlerResult bus_unit_queue_job( (type == JOB_START || type == JOB_RESTART || type == JOB_TRY_RESTART) ? "start" : type == JOB_STOP ? "stop" : "reload"); - if (type == JOB_STOP && u->load_state == UNIT_ERROR && unit_active_state(u) == UNIT_INACTIVE) { + if (type == JOB_STOP && (u->load_state == UNIT_NOT_FOUND || u->load_state == UNIT_ERROR) && unit_active_state(u) == UNIT_INACTIVE) { dbus_set_error(&error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", u->id); return bus_send_error_reply(connection, message, &error, -EPERM); } @@ -764,7 +764,13 @@ oom: return DBUS_HANDLER_RESULT_NEED_MEMORY; } -int bus_unit_set_properties(Unit *u, DBusMessageIter *iter, UnitSetPropertiesMode mode, DBusError *error) { +int bus_unit_set_properties( + Unit *u, + DBusMessageIter *iter, + UnitSetPropertiesMode mode, + bool commit, + DBusError *error) { + bool for_real = false; DBusMessageIter sub; unsigned n = 0; @@ -773,6 +779,9 @@ int bus_unit_set_properties(Unit *u, DBusMessageIter *iter, UnitSetPropertiesMod assert(u); assert(iter); + if (u->transient) + mode &= UNIT_RUNTIME; + /* We iterate through the array twice. First run we just check * if all passed data is valid, second run actually applies * it. This is to implement transaction-like behaviour without @@ -826,7 +835,7 @@ int bus_unit_set_properties(Unit *u, DBusMessageIter *iter, UnitSetPropertiesMod n += for_real; } - if (n > 0 && UNIT_VTABLE(u)->bus_commit_properties) + if (commit && n > 0 && UNIT_VTABLE(u)->bus_commit_properties) UNIT_VTABLE(u)->bus_commit_properties(u); return n; @@ -896,5 +905,6 @@ const BusProperty bus_unit_properties[] = { { "ConditionResult", bus_property_append_bool, "b", offsetof(Unit, condition_result) }, { "LoadError", bus_unit_append_load_error, "(ss)", 0 }, { "ControlGroup", bus_property_append_string, "s", offsetof(Unit, cgroup_path), true }, + { "Transient", bus_property_append_bool, "b", offsetof(Unit, transient) }, { NULL, } }; diff --git a/src/core/dbus-unit.h b/src/core/dbus-unit.h index 1b42757b47..18f7c4f088 100644 --- a/src/core/dbus-unit.h +++ b/src/core/dbus-unit.h @@ -128,6 +128,7 @@ " \n" \ " \n" \ " \n" \ + " \n" \ " \n" #define BUS_UNIT_INTERFACES_LIST \ @@ -141,7 +142,7 @@ void bus_unit_send_removed_signal(Unit *u); DBusHandlerResult bus_unit_queue_job(DBusConnection *connection, DBusMessage *message, Unit *u, JobType type, JobMode mode, bool reload_if_possible); -int bus_unit_set_properties(Unit *u, DBusMessageIter *i, UnitSetPropertiesMode mode, DBusError *error); +int bus_unit_set_properties(Unit *u, DBusMessageIter *i, UnitSetPropertiesMode mode, bool commit, DBusError *error); extern const DBusObjectPathVTable bus_unit_vtable; diff --git a/src/core/job.c b/src/core/job.c index d304a16d06..85f77e8f0d 100644 --- a/src/core/job.c +++ b/src/core/job.c @@ -1088,10 +1088,13 @@ void job_shutdown_magic(Job *j) { * asynchronous sync() would cause their exit to be * delayed. */ - if (!unit_has_name(j->unit, SPECIAL_SHUTDOWN_TARGET)) + if (j->type != JOB_START) return; - if (j->type != JOB_START) + if (j->unit->manager->running_as != SYSTEMD_SYSTEM) + return; + + if (!unit_has_name(j->unit, SPECIAL_SHUTDOWN_TARGET)) return; if (detect_container(NULL) > 0) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 57c8156fdd..2b10d72ab3 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -2439,14 +2439,14 @@ static int load_from_path(Unit *u, const char *path) { if (null_or_empty(&st)) u->load_state = UNIT_MASKED; else { + u->load_state = UNIT_LOADED; + /* Now, parse the file contents */ r = config_parse(u->id, filename, f, UNIT_VTABLE(u)->sections, config_item_perf_lookup, (void*) load_fragment_gperf_lookup, false, true, u); if (r < 0) goto finish; - - u->load_state = UNIT_LOADED; } free(u->fragment_path); diff --git a/src/core/main.c b/src/core/main.c index 3c6fccf527..102cc3b315 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1666,7 +1666,7 @@ int main(int argc, char *argv[]) { if (r < 0) { log_error("Failed to load default target: %s", bus_error(&error, r)); dbus_error_free(&error); - } else if (target->load_state == UNIT_ERROR) + } else if (target->load_state == UNIT_ERROR || target->load_state == UNIT_NOT_FOUND) log_error("Failed to load default target: %s", strerror(-target->load_error)); else if (target->load_state == UNIT_MASKED) log_error("Default target masked."); @@ -1679,7 +1679,7 @@ int main(int argc, char *argv[]) { log_error("Failed to load rescue target: %s", bus_error(&error, r)); dbus_error_free(&error); goto finish; - } else if (target->load_state == UNIT_ERROR) { + } else if (target->load_state == UNIT_ERROR || target->load_state == UNIT_ERROR) { log_error("Failed to load rescue target: %s", strerror(-target->load_error)); goto finish; } else if (target->load_state == UNIT_MASKED) { diff --git a/src/core/manager.c b/src/core/manager.c index 6ba51a4116..42c9bcd48c 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -993,7 +993,13 @@ unsigned manager_dispatch_load_queue(Manager *m) { return n; } -int manager_load_unit_prepare(Manager *m, const char *name, const char *path, DBusError *e, Unit **_ret) { +int manager_load_unit_prepare( + Manager *m, + const char *name, + const char *path, + DBusError *e, + Unit **_ret) { + Unit *ret; UnitType t; int r; @@ -1053,7 +1059,13 @@ int manager_load_unit_prepare(Manager *m, const char *name, const char *path, DB return 0; } -int manager_load_unit(Manager *m, const char *name, const char *path, DBusError *e, Unit **_ret) { +int manager_load_unit( + Manager *m, + const char *name, + const char *path, + DBusError *e, + Unit **_ret) { + int r; assert(m); diff --git a/src/core/mount.c b/src/core/mount.c index c1af903b12..3cc3e65b23 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -1562,7 +1562,7 @@ static int mount_add_one( } } - if (u->load_state == UNIT_ERROR) { + if (u->load_state == UNIT_NOT_FOUND) { u->load_state = UNIT_LOADED; u->load_error = 0; diff --git a/src/core/service.c b/src/core/service.c index 1dcd5cf443..6f18cbf759 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -983,7 +983,7 @@ static int service_load_sysv_name(Service *s, const char *name) { assert(s); assert(name); - /* For SysV services we strip the *.sh suffixes. */ + /* For SysV services we strip the *.sh suffixes. */ if (endswith(name, ".sh.service")) return -ENOENT; @@ -1193,27 +1193,32 @@ static int service_load(Unit *u) { assert(s); /* Load a .service file */ - if ((r = unit_load_fragment(u)) < 0) + r = unit_load_fragment(u); + if (r < 0) return r; #ifdef HAVE_SYSV_COMPAT /* Load a classic init script as a fallback, if we couldn't find anything */ - if (u->load_state == UNIT_STUB) - if ((r = service_load_sysv(s)) < 0) + if (u->load_state == UNIT_STUB) { + r = service_load_sysv(s); + if (r < 0) return r; + } #endif /* Still nothing found? Then let's give up */ if (u->load_state == UNIT_STUB) return -ENOENT; - /* We were able to load something, then let's add in the - * dropin directories. */ - if ((r = unit_load_dropin(unit_follow_merge(u))) < 0) - return r; - /* This is a new unit? Then let's add in some extras */ if (u->load_state == UNIT_LOADED) { + + /* We were able to load something, then let's add in + * the dropin directories. */ + r = unit_load_dropin(u); + if (r < 0) + return r; + if (s->type == _SERVICE_TYPE_INVALID) s->type = s->bus_name ? SERVICE_DBUS : SERVICE_SIMPLE; @@ -3886,6 +3891,8 @@ const UnitVTable service_vtable = { .bus_set_property = bus_service_set_property, .bus_commit_properties = bus_service_commit_properties, + .can_transient = true, + #ifdef HAVE_SYSV_COMPAT .enumerate = service_enumerate, #endif diff --git a/src/core/transaction.c b/src/core/transaction.c index fa97b69755..5259a5b7ca 100644 --- a/src/core/transaction.c +++ b/src/core/transaction.c @@ -851,12 +851,13 @@ int transaction_add_job_and_dependencies( if (unit->load_state != UNIT_LOADED && unit->load_state != UNIT_ERROR && + unit->load_state != UNIT_NOT_FOUND && unit->load_state != UNIT_MASKED) { dbus_set_error(e, BUS_ERROR_LOAD_FAILED, "Unit %s is not loaded properly.", unit->id); return -EINVAL; } - if (type != JOB_STOP && unit->load_state == UNIT_ERROR) { + if (type != JOB_STOP && (unit->load_state == UNIT_ERROR || unit->load_state == UNIT_NOT_FOUND)) { dbus_set_error(e, BUS_ERROR_LOAD_FAILED, "Unit %s failed to load: %s. " "See system logs and 'systemctl status %s' for details.", diff --git a/src/core/unit.c b/src/core/unit.c index afeb15c154..c6c9c18653 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -348,6 +348,29 @@ static void bidi_set_free(Unit *u, Set *s) { set_free(s); } +static void unit_remove_transient(Unit *u) { + char **i; + + assert(u); + + if (!u->transient) + return; + + if (u->fragment_path) + unlink(u->fragment_path); + + STRV_FOREACH(i, u->dropin_paths) { + _cleanup_free_ char *p = NULL; + int r; + + unlink(*i); + + r = path_get_parent(*i, &p); + if (r >= 0) + rmdir(p); + } +} + void unit_free(Unit *u) { UnitDependency d; Iterator i; @@ -355,6 +378,9 @@ void unit_free(Unit *u) { assert(u); + if (u->manager->n_reloading <= 0) + unit_remove_transient(u); + bus_unit_send_removed_signal(u); if (u->load_state != UNIT_STUB) @@ -524,7 +550,7 @@ int unit_merge(Unit *u, Unit *other) { return -EINVAL; if (other->load_state != UNIT_STUB && - other->load_state != UNIT_ERROR) + other->load_state != UNIT_NOT_FOUND) return -EEXIST; if (other->job) @@ -580,7 +606,8 @@ int unit_merge_by_name(Unit *u, const char *name) { name = s; } - if (!(other = manager_get_unit(u->manager, name))) + other = manager_get_unit(u->manager, name); + if (!other) r = unit_add_name(u, name); else r = unit_merge(u, other); @@ -673,6 +700,7 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { "%s\tInactive Enter Timestamp: %s\n" "%s\tGC Check Good: %s\n" "%s\tNeed Daemon Reload: %s\n" + "%s\tTransient: %s\n" "%s\tSlice: %s\n" "%s\tCGroup: %s\n" "%s\tCGroup realized: %s\n" @@ -688,6 +716,7 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { prefix, strna(format_timestamp(timestamp4, sizeof(timestamp4), u->inactive_enter_timestamp.realtime)), prefix, yes_no(unit_check_gc(u)), prefix, yes_no(unit_need_daemon_reload(u)), + prefix, yes_no(u->transient), prefix, strna(unit_slice_name(u)), prefix, strna(u->cgroup_path), prefix, yes_no(u->cgroup_realized), @@ -903,34 +932,38 @@ int unit_load(Unit *u) { if (u->load_state != UNIT_STUB) return 0; - if (UNIT_VTABLE(u)->load) - if ((r = UNIT_VTABLE(u)->load(u)) < 0) + if (UNIT_VTABLE(u)->load) { + r = UNIT_VTABLE(u)->load(u); + if (r < 0) goto fail; + } if (u->load_state == UNIT_STUB) { r = -ENOENT; goto fail; } - if (u->load_state == UNIT_LOADED && - u->default_dependencies) - if ((r = unit_add_default_dependencies(u)) < 0) - goto fail; - if (u->load_state == UNIT_LOADED) { + + if (u->default_dependencies) { + r = unit_add_default_dependencies(u); + if (r < 0) + goto fail; + } + r = unit_add_mount_links(u); if (r < 0) - return r; - } + goto fail; - if (u->on_failure_isolate && - set_size(u->dependencies[UNIT_ON_FAILURE]) > 1) { + if (u->on_failure_isolate && + set_size(u->dependencies[UNIT_ON_FAILURE]) > 1) { - log_error_unit(u->id, - "More than one OnFailure= dependencies specified for %s but OnFailureIsolate= enabled. Refusing.", u->id); + log_error_unit(u->id, + "More than one OnFailure= dependencies specified for %s but OnFailureIsolate= enabled. Refusing.", u->id); - r = -EINVAL; - goto fail; + r = -EINVAL; + goto fail; + } } assert((u->load_state != UNIT_MERGED) == !u->merged_into); @@ -941,7 +974,7 @@ int unit_load(Unit *u) { return 0; fail: - u->load_state = UNIT_ERROR; + u->load_state = u->load_state == UNIT_STUB ? UNIT_NOT_FOUND : UNIT_ERROR; u->load_error = r; unit_add_to_dbus_queue(u); unit_add_to_gc_queue(u); @@ -2117,6 +2150,11 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) { if (dual_timestamp_is_set(&u->condition_timestamp)) unit_serialize_item(u, f, "condition-result", yes_no(u->condition_result)); + unit_serialize_item(u, f, "transient", yes_no(u->transient)); + + if (u->cgroup_path) + unit_serialize_item(u, f, "cgroup", u->cgroup_path); + /* End marker */ fputc('\n', f); return 0; @@ -2239,15 +2277,38 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) { } else if (streq(l, "condition-result")) { int b; - if ((b = parse_boolean(v)) < 0) + b = parse_boolean(v); + if (b < 0) log_debug("Failed to parse condition result value %s", v); else u->condition_result = b; continue; + + } else if (streq(l, "transient")) { + int b; + + b = parse_boolean(v); + if (b < 0) + log_debug("Failed to parse transient bool %s", v); + else + u->transient = b; + + continue; + } else if (streq(l, "cgroup")) { + char *s; + + s = strdup(v); + if (!v) + return -ENOMEM; + + free(u->cgroup_path); + u->cgroup_path = s; + continue; } - if ((r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds)) < 0) + r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds); + if (r < 0) return r; } } @@ -2652,9 +2713,6 @@ static int drop_in_file(Unit *u, UnitSetPropertiesMode mode, const char *name, c assert(_q); assert(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)); - if (u->manager->running_as == SYSTEMD_USER && !(mode & UNIT_PERSISTENT)) - return -ENOTSUP; - if (!filename_is_safe(name)) return -EINVAL; @@ -2668,7 +2726,7 @@ static int drop_in_file(Unit *u, UnitSetPropertiesMode mode, const char *name, c return -ENOENT; p = strjoin(c, "/", u->id, ".d", NULL); - } else if (mode & UNIT_PERSISTENT) + } else if (mode & UNIT_PERSISTENT) p = strjoin("/etc/systemd/system/", u->id, ".d", NULL); else p = strjoin("/run/systemd/system/", u->id, ".d", NULL); @@ -2741,6 +2799,43 @@ int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name) { return r; } +int unit_make_transient(Unit *u) { + int r; + + assert(u); + + u->load_state = UNIT_STUB; + u->load_error = 0; + u->transient = true; + + free(u->fragment_path); + u->fragment_path = NULL; + + if (u->manager->running_as == SYSTEMD_USER) { + _cleanup_free_ char *c = NULL; + + r = user_config_home(&c); + if (r < 0) + return r; + if (r == 0) + return -ENOENT; + + u->fragment_path = strjoin(c, "/", u->id, NULL); + if (!u->fragment_path) + return -ENOMEM; + + mkdir_p(c, 0755); + } else { + u->fragment_path = strappend("/run/systemd/system/", u->id); + if (!u->fragment_path) + return -ENOMEM; + + mkdir_p("/run/systemd/system", 0755); + } + + return write_string_file_atomic_label(u->fragment_path, "# Transient stub"); +} + int unit_kill_context( Unit *u, KillContext *c, diff --git a/src/core/unit.h b/src/core/unit.h index be6abaff98..8a62787b38 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -241,6 +241,9 @@ struct Unit { /* Did the last condition check succeed? */ bool condition_result; + /* Is this a transient unit? */ + bool transient; + bool in_load_queue:1; bool in_dbus_queue:1; bool in_cleanup_queue:1; @@ -425,6 +428,9 @@ struct UnitVTable { /* Exclude from automatic gc */ bool no_gc:1; + + /* True if transient units of this type are OK */ + bool can_transient:1; }; extern const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX]; @@ -595,6 +601,8 @@ int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name); int unit_kill_context(Unit *u, KillContext *c, bool sigkill, pid_t main_pid, pid_t control_pid, bool main_pid_alien); +int unit_make_transient(Unit *u); + const char *unit_active_state_to_string(UnitActiveState i) _const_; UnitActiveState unit_active_state_from_string(const char *s) _pure_; diff --git a/src/run/Makefile b/src/run/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/run/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/run/run.c b/src/run/run.c new file mode 100644 index 0000000000..9f8bda48af --- /dev/null +++ b/src/run/run.c @@ -0,0 +1,156 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include + +#include "sd-bus.h" +#include "bus-internal.h" +#include "bus-message.h" +#include "strv.h" + +static int start_transient_service( + sd_bus *bus, + const char *name, + char **argv, + sd_bus_error *error) { + + _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL; + char **i; + int r; + + r = sd_bus_message_new_method_call( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "StartTransientUnit", &m); + if (r < 0) + return r; + + r = sd_bus_message_append(m, "ss", name, "fail"); + if (r < 0) + return r; + + r = sd_bus_message_open_container(m, 'a', "(sv)"); + if (r < 0) + return r; + + r = sd_bus_message_open_container(m, 'r', "sv"); + if (r < 0) + return r; + + r = sd_bus_message_append(m, "s", "ExecStart"); + if (r < 0) + return r; + + r = sd_bus_message_open_container(m, 'v', "a(sasb)"); + if (r < 0) + return r; + + r = sd_bus_message_open_container(m, 'a', "(sasb)"); + if (r < 0) + return r; + + r = sd_bus_message_open_container(m, 'r', "sasb"); + if (r < 0) + return r; + + r = sd_bus_message_append(m, "s", argv[0]); + if (r < 0) + return r; + + r = sd_bus_message_open_container(m, 'a', "s"); + if (r < 0) + return r; + + STRV_FOREACH(i, argv) { + r = sd_bus_message_append(m, "s", *i); + if (r < 0) + return r; + } + + r = sd_bus_message_close_container(m); + if (r < 0) + return r; + + r = sd_bus_message_append(m, "b", false); + if (r < 0) + return r; + + r = sd_bus_message_close_container(m); + if (r < 0) + return r; + + r = sd_bus_message_close_container(m); + if (r < 0) + return r; + + r = sd_bus_message_close_container(m); + if (r < 0) + return r; + + r = sd_bus_message_close_container(m); + if (r < 0) + return r; + + r = sd_bus_message_close_container(m); + if (r < 0) + return r; + + return sd_bus_send_with_reply_and_block(bus, m, 0, error, &reply); +} + +int main(int argc, char* argv[]) { + sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_bus_unref_ sd_bus *bus = NULL; + _cleanup_free_ char *name = NULL; + int r; + + log_parse_environment(); + log_open(); + + if (argc < 2) { + log_error("Missing command line."); + r = -EINVAL; + goto fail; + } + + r = sd_bus_open_user(&bus); + if (r < 0) { + log_error("Failed to create new bus: %s", strerror(-r)); + goto fail; + } + + if (asprintf(&name, "run-%lu.service", (unsigned long) getpid()) < 0) { + r = log_oom(); + goto fail; + } + + r = start_transient_service(bus, name, argv + 1, &error); + if (r < 0) { + log_error("Failed start transient service: %s", error.message); + sd_bus_error_free(&error); + goto fail; + } + +fail: + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/shared/unit-name.c b/src/shared/unit-name.c index 0910e86f10..bf1ab794a8 100644 --- a/src/shared/unit-name.c +++ b/src/shared/unit-name.c @@ -52,6 +52,7 @@ DEFINE_STRING_TABLE_LOOKUP(unit_type, UnitType); static const char* const unit_load_state_table[_UNIT_LOAD_STATE_MAX] = { [UNIT_STUB] = "stub", [UNIT_LOADED] = "loaded", + [UNIT_NOT_FOUND] = "not-found", [UNIT_ERROR] = "error", [UNIT_MERGED] = "merged", [UNIT_MASKED] = "masked" @@ -403,7 +404,6 @@ char *unit_name_template(const char *f) { strcpy(mempcpy(r, f, a), e); return r; - } char *unit_name_from_path(const char *path, const char *suffix) { diff --git a/src/shared/unit-name.h b/src/shared/unit-name.h index baa487a81d..922d75232d 100644 --- a/src/shared/unit-name.h +++ b/src/shared/unit-name.h @@ -49,6 +49,7 @@ enum UnitType { enum UnitLoadState { UNIT_STUB = 0, UNIT_LOADED, + UNIT_NOT_FOUND, UNIT_ERROR, UNIT_MERGED, UNIT_MASKED, -- cgit v1.2.1 From cda4380d9ffb18f626ba1c146e270e0e664f6739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9E=A5=EB=8F=99=EC=A4=80?= Date: Fri, 28 Jun 2013 10:51:28 +0200 Subject: keymap: Add Samsung Series 3 Signed-off-by: Martin Pitt --- Makefile.am | 2 ++ keymaps-force-release/samsung-series-3 | 2 ++ keymaps/samsung-series-3 | 3 +++ src/udev/keymap/95-keyboard-force-release.rules | 1 + src/udev/keymap/95-keymap.rules | 1 + 5 files changed, 9 insertions(+) create mode 100644 keymaps-force-release/samsung-series-3 create mode 100644 keymaps/samsung-series-3 diff --git a/Makefile.am b/Makefile.am index 3ab14753ac..e0bcfaa381 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2598,6 +2598,7 @@ dist_udevkeymap_DATA = \ keymaps/oqo-model2 \ keymaps/samsung-other \ keymaps/samsung-series-9 \ + keymaps/samsung-series-3 \ keymaps/samsung-sq1us \ keymaps/samsung-sx20s \ keymaps/toshiba-satellite_a100 \ @@ -2612,6 +2613,7 @@ dist_udevkeymapforcerel_DATA = \ keymaps-force-release/hp-other \ keymaps-force-release/samsung-other \ keymaps-force-release/samsung-series-9 \ + keymaps-force-release/samsung-series-3 \ keymaps-force-release/common-volume-keys src/udev/keymap/keys.txt: Makefile diff --git a/keymaps-force-release/samsung-series-3 b/keymaps-force-release/samsung-series-3 new file mode 100644 index 0000000000..bfa06e10b7 --- /dev/null +++ b/keymaps-force-release/samsung-series-3 @@ -0,0 +1,2 @@ +0xCE # Fn+F1 launch control setting +0xD5 # Fn+F12 wifi on/off diff --git a/keymaps/samsung-series-3 b/keymaps/samsung-series-3 new file mode 100644 index 0000000000..52b2d64b44 --- /dev/null +++ b/keymaps/samsung-series-3 @@ -0,0 +1,3 @@ +0xCE prog1 # Fn+F1 launch control setting +0xB3 prog2 # Fn+F11 performance mode +0xD5 wlan # Fn+F12 wifi on/off diff --git a/src/udev/keymap/95-keyboard-force-release.rules b/src/udev/keymap/95-keyboard-force-release.rules index a13403c73f..431a28358a 100644 --- a/src/udev/keymap/95-keyboard-force-release.rules +++ b/src/udev/keymap/95-keyboard-force-release.rules @@ -20,6 +20,7 @@ ENV{DMI_VENDOR}="$attr{[dmi/id]sys_vendor}" ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", RUN+="keyboard-force-release.sh $devpath samsung-other" ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*90X3A*|*900X3*|*900X4*|*900XC3*", RUN+="keyboard-force-release.sh $devpath samsung-series-9" +ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*300E5*|*300E4*|*300E7*|*270E5*|*270E4*", RUN+="keyboard-force-release.sh $devpath samsung-series-3" ENV{DMI_VENDOR}=="Dell Inc.", ATTR{[dmi/id]product_name}=="Studio 1557|Studio 1558", RUN+="keyboard-force-release.sh $devpath common-volume-keys" ENV{DMI_VENDOR}=="Dell Inc.", ATTR{[dmi/id]product_name}=="*Latitude*|*Precision*", RUN+="keyboard-force-release.sh $devpath dell-touchpad" diff --git a/src/udev/keymap/95-keymap.rules b/src/udev/keymap/95-keymap.rules index 18816f17bb..30c28a480d 100644 --- a/src/udev/keymap/95-keymap.rules +++ b/src/udev/keymap/95-keymap.rules @@ -163,6 +163,7 @@ ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="S ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*700Z*", RUN+="keymap $name 0xBA ejectcd 0x96 keyboardbrightnessup 0x97 keyboardbrightnessdown" ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*700T*", RUN+="keymap $name 0xAD leftmeta" ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*90X3A*|*900X3*|*900X4*|*900XC3*", RUN+="keymap $name samsung-series-9" +ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*300E5*|*300E4*|*300E7*|*270E5*|*270E4*", RUN+="keymap $name samsung-series-3" ENV{DMI_VENDOR}=="TOSHIBA", ATTR{[dmi/id]product_name}=="SATELLITE A100", RUN+="keymap $name toshiba-satellite_a100" ENV{DMI_VENDOR}=="TOSHIBA", ATTR{[dmi/id]product_name}=="Satellite A110", RUN+="keymap $name toshiba-satellite_a110" -- cgit v1.2.1 From 11ddb6f48e367ae4b51c31d199b28f5be041a301 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 28 Jun 2013 18:37:15 +0200 Subject: main: fix loading of default target --- TODO | 5 ++--- src/core/main.c | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/TODO b/TODO index 055d9739d2..8a3df6037c 100644 --- a/TODO +++ b/TODO @@ -28,6 +28,8 @@ Fedora 19: Features: +* transient units: allow creating auxiliary units with the same call + * make BlockIODeviceWeight=, BlockIODeviceBandwidth= runtime settable * split up BlockIOWeight= and BlockIODeviceWeight= @@ -44,9 +46,6 @@ Features: * split out CreateMachine into systemd-machined -* "transient" units, i.e units that are not sourced from disk but - created only transiently via bus calls - * introduce new Scope unit type then make logind's session and machine registration use this to set up cgroups diff --git a/src/core/main.c b/src/core/main.c index 102cc3b315..2bd1efd5d0 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1679,7 +1679,7 @@ int main(int argc, char *argv[]) { log_error("Failed to load rescue target: %s", bus_error(&error, r)); dbus_error_free(&error); goto finish; - } else if (target->load_state == UNIT_ERROR || target->load_state == UNIT_ERROR) { + } else if (target->load_state == UNIT_ERROR || target->load_state == UNIT_NOT_FOUND) { log_error("Failed to load rescue target: %s", strerror(-target->load_error)); goto finish; } else if (target->load_state == UNIT_MASKED) { -- cgit v1.2.1 From 54ca4fc85b3f0b9bf7f52a7be782161d780246e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 28 Jun 2013 22:29:21 -0400 Subject: build-sys: "link" libsystemd-id128.so with libsystemd-label Fixed build on debian wheezy: ./.libs/libudev.so: undefined reference to `cg_create' Appears to have no influence on the resulting binaries and libraries. Cf. b5fafdf63f. --- Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile.am b/Makefile.am index e0bcfaa381..ea18640456 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1999,6 +1999,7 @@ libudev_la_LDFLAGS = \ libudev_la_LIBADD = \ libsystemd-shared.la \ + libsystemd-label.la \ libsystemd-daemon-internal.la \ libsystemd-id128-internal.la @@ -2664,6 +2665,7 @@ libsystemd_id128_la_LDFLAGS = \ libsystemd_id128_la_LIBADD = \ libsystemd-shared.la \ + libsystemd-label.la \ libsystemd-daemon-internal.la libsystemd_id128_internal_la_SOURCES = \ -- cgit v1.2.1 From 1e158d273bb63883566358cbb886cd4167421df6 Mon Sep 17 00:00:00 2001 From: "Jason St. John" Date: Thu, 27 Jun 2013 18:38:15 +0200 Subject: man: fix spacing issue in various man pages Before: libsystemd-daemonpkg-config(1) After: libsystemd-daemon pkg-config(1) This fix is more complicated than it should be due to the consecutive XML elements separated by collapsible whitespace. Merging the lines and separating the XML elements with an en space or a non-breaking space is the only solution that results in one, and only one, space being inserted between them when testing. An em space results in two spaces being inserted. --- man/sd-daemon.xml | 3 +-- man/sd-id128.xml | 3 +-- man/sd-journal.xml | 3 +-- man/sd-login.xml | 3 +-- man/sd_booted.xml | 3 +-- man/sd_get_seats.xml | 3 +-- man/sd_id128_get_machine.xml | 3 +-- man/sd_id128_randomize.xml | 3 +-- man/sd_id128_to_string.xml | 3 +-- man/sd_is_fifo.xml | 3 +-- man/sd_journal_add_match.xml | 3 +-- man/sd_journal_get_catalog.xml | 3 +-- man/sd_journal_get_cursor.xml | 3 +-- man/sd_journal_get_cutoff_realtime_usec.xml | 3 +-- man/sd_journal_get_data.xml | 3 +-- man/sd_journal_get_fd.xml | 3 +-- man/sd_journal_get_realtime_usec.xml | 3 +-- man/sd_journal_get_usage.xml | 3 +-- man/sd_journal_next.xml | 3 +-- man/sd_journal_open.xml | 3 +-- man/sd_journal_print.xml | 3 +-- man/sd_journal_query_unique.xml | 3 +-- man/sd_journal_seek_head.xml | 3 +-- man/sd_journal_stream_fd.xml | 3 +-- man/sd_listen_fds.xml | 3 +-- man/sd_login_monitor_new.xml | 3 +-- man/sd_notify.xml | 3 +-- man/sd_pid_get_session.xml | 3 +-- man/sd_seat_get_active.xml | 3 +-- man/sd_session_is_active.xml | 3 +-- man/sd_uid_get_state.xml | 3 +-- 31 files changed, 31 insertions(+), 62 deletions(-) diff --git a/man/sd-daemon.xml b/man/sd-daemon.xml index 55ee1fd893..136415f0a1 100644 --- a/man/sd-daemon.xml +++ b/man/sd-daemon.xml @@ -146,8 +146,7 @@ sd-daemon.h files. These interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-daemon - pkg-config1 + libsystemd-daemon pkg-config1 file. Alternatively, applications consuming these APIs may copy the implementation into their source tree, either verbatim or in excerpts. diff --git a/man/sd-id128.xml b/man/sd-id128.xml index 51a16e35d4..c194f57458 100644 --- a/man/sd-id128.xml +++ b/man/sd-id128.xml @@ -157,8 +157,7 @@ These APIs are implemented as a shared library, which can be compiled and linked to with the - libsystemd-id128 - pkg-config1 + libsystemd-id128 pkg-config1 file. diff --git a/man/sd-journal.xml b/man/sd-journal.xml index 490b971f19..6d39611447 100644 --- a/man/sd-journal.xml +++ b/man/sd-journal.xml @@ -100,8 +100,7 @@ These APIs are implemented as shared library, which can be compiled and linked to with the - libsystemd-journal - pkg-config1 + libsystemd-journal pkg-config1 file. diff --git a/man/sd-login.xml b/man/sd-login.xml index c186324f83..251b35b06f 100644 --- a/man/sd-login.xml +++ b/man/sd-login.xml @@ -122,8 +122,7 @@ These APIs are implemented as shared library, which can be compiled and linked to with the - libsystemd-login - pkg-config1 + libsystemd-login pkg-config1 file. diff --git a/man/sd_booted.xml b/man/sd_booted.xml index 32d0fd095d..84af8fbd95 100644 --- a/man/sd_booted.xml +++ b/man/sd_booted.xml @@ -102,8 +102,7 @@ sd-daemon.h files. These interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-daemon - pkg-config1 + libsystemd-daemon pkg-config1 file. Alternatively, applications consuming these APIs may copy the implementation into their source tree. For more details about the reference diff --git a/man/sd_get_seats.xml b/man/sd_get_seats.xml index 9fb0732c10..8254b7cae4 100644 --- a/man/sd_get_seats.xml +++ b/man/sd_get_seats.xml @@ -124,8 +124,7 @@ sd_get_machine_names() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-login - pkg-config1 + libsystemd-login pkg-config1 file. diff --git a/man/sd_id128_get_machine.xml b/man/sd_id128_get_machine.xml index 039c1dd64c..12887a240a 100644 --- a/man/sd_id128_get_machine.xml +++ b/man/sd_id128_get_machine.xml @@ -118,8 +118,7 @@ and sd_id128_get_boot() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-id128 - pkg-config1 + libsystemd-id128 pkg-config1 file. diff --git a/man/sd_id128_randomize.xml b/man/sd_id128_randomize.xml index 37efe164cd..15e17619d0 100644 --- a/man/sd_id128_randomize.xml +++ b/man/sd_id128_randomize.xml @@ -98,8 +98,7 @@ The sd_id128_randomize() interface is available as shared library, which can be compiled and linked to with the - libsystemd-id128 - pkg-config1 + libsystemd-id128 pkg-config1 file. diff --git a/man/sd_id128_to_string.xml b/man/sd_id128_to_string.xml index 593d0752d5..6d5cf45f90 100644 --- a/man/sd_id128_to_string.xml +++ b/man/sd_id128_to_string.xml @@ -118,8 +118,7 @@ The sd_id128_to_string() and sd_id128_from_string() interfaces are available as shared library, which can be compiled and - linked to with the libsystemd-id128 - pkg-config1 + linked to with the libsystemd-id128 pkg-config1 file. diff --git a/man/sd_is_fifo.xml b/man/sd_is_fifo.xml index 5eaf1585a2..44b41abf86 100644 --- a/man/sd_is_fifo.xml +++ b/man/sd_is_fifo.xml @@ -192,8 +192,7 @@ sd-daemon.h files. These interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-daemon - pkg-config1 + libsystemd-daemon pkg-config1 file. Alternatively, applications consuming these APIs may copy the implementation into their source tree. For more details about the reference diff --git a/man/sd_journal_add_match.xml b/man/sd_journal_add_match.xml index 82edf21834..d02285f205 100644 --- a/man/sd_journal_add_match.xml +++ b/man/sd_journal_add_match.xml @@ -176,8 +176,7 @@ sd_journal_flush_matches() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-journal - pkg-config1 + libsystemd-journal pkg-config1 file. diff --git a/man/sd_journal_get_catalog.xml b/man/sd_journal_get_catalog.xml index d1962e4ca1..53ca3083b1 100644 --- a/man/sd_journal_get_catalog.xml +++ b/man/sd_journal_get_catalog.xml @@ -120,8 +120,7 @@ sd_journal_get_catalog_for_message_id() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-journal - pkg-config1 + libsystemd-journal pkg-config1 file. diff --git a/man/sd_journal_get_cursor.xml b/man/sd_journal_get_cursor.xml index d83c5191f5..861927e2e1 100644 --- a/man/sd_journal_get_cursor.xml +++ b/man/sd_journal_get_cursor.xml @@ -132,8 +132,7 @@ and sd_journal_test_cursor() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-journal - pkg-config1 + libsystemd-journal pkg-config1 file. diff --git a/man/sd_journal_get_cutoff_realtime_usec.xml b/man/sd_journal_get_cutoff_realtime_usec.xml index 506c02c38c..d987011a8b 100644 --- a/man/sd_journal_get_cutoff_realtime_usec.xml +++ b/man/sd_journal_get_cutoff_realtime_usec.xml @@ -124,8 +124,7 @@ sd_journal_get_cutoff_monotonic_usec() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-journal - pkg-config1 + libsystemd-journal pkg-config1 file. diff --git a/man/sd_journal_get_data.xml b/man/sd_journal_get_data.xml index ba50b8d092..460b709dbf 100644 --- a/man/sd_journal_get_data.xml +++ b/man/sd_journal_get_data.xml @@ -205,8 +205,7 @@ sd_journal_get_data_threshold() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-journal - pkg-config1 + libsystemd-journal pkg-config1 file. diff --git a/man/sd_journal_get_fd.xml b/man/sd_journal_get_fd.xml index f3fbe69c32..1c6f25005e 100644 --- a/man/sd_journal_get_fd.xml +++ b/man/sd_journal_get_fd.xml @@ -255,8 +255,7 @@ else { sd_journal_wait() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-journal - pkg-config1 + libsystemd-journal pkg-config1 file. diff --git a/man/sd_journal_get_realtime_usec.xml b/man/sd_journal_get_realtime_usec.xml index b57a7c15b2..e7e4e4e4d1 100644 --- a/man/sd_journal_get_realtime_usec.xml +++ b/man/sd_journal_get_realtime_usec.xml @@ -124,8 +124,7 @@ sd_journal_get_monotonic_usec() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-journal - pkg-config1 + libsystemd-journal pkg-config1 file. diff --git a/man/sd_journal_get_usage.xml b/man/sd_journal_get_usage.xml index 490317ac91..50953f5065 100644 --- a/man/sd_journal_get_usage.xml +++ b/man/sd_journal_get_usage.xml @@ -86,8 +86,7 @@ The sd_journal_get_usage() interface is available as shared library, which can be compiled and linked to with the - libsystemd-journal - pkg-config1 + libsystemd-journal pkg-config1 file. diff --git a/man/sd_journal_next.xml b/man/sd_journal_next.xml index 11066611f1..6e437d1822 100644 --- a/man/sd_journal_next.xml +++ b/man/sd_journal_next.xml @@ -158,8 +158,7 @@ sd_journal_previous_skip() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-journal - pkg-config1 + libsystemd-journal pkg-config1 file. diff --git a/man/sd_journal_open.xml b/man/sd_journal_open.xml index d7ea8ff95b..eae851e731 100644 --- a/man/sd_journal_open.xml +++ b/man/sd_journal_open.xml @@ -191,8 +191,7 @@ sd_journal_close() interfaces are available as a shared library, which can be compiled and linked to with the - libsystemd-journal - pkg-config1 + libsystemd-journal pkg-config1 file. diff --git a/man/sd_journal_print.xml b/man/sd_journal_print.xml index 7292d33456..81900dbdfb 100644 --- a/man/sd_journal_print.xml +++ b/man/sd_journal_print.xml @@ -229,8 +229,7 @@ sd_journal_send("MESSAGE=Hello World, this is PID %lu!", (unsigned long) getpid( sd_journal_sendv() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-journal - pkg-config1 + libsystemd-journal pkg-config1 file. diff --git a/man/sd_journal_query_unique.xml b/man/sd_journal_query_unique.xml index dde52cf5fb..f5d9d2bfb5 100644 --- a/man/sd_journal_query_unique.xml +++ b/man/sd_journal_query_unique.xml @@ -158,8 +158,7 @@ sd_journal_restart_unique() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-journal - pkg-config1 + libsystemd-journal pkg-config1 file. diff --git a/man/sd_journal_seek_head.xml b/man/sd_journal_seek_head.xml index 9cf9dd07a8..c4e64096e1 100644 --- a/man/sd_journal_seek_head.xml +++ b/man/sd_journal_seek_head.xml @@ -158,8 +158,7 @@ and sd_journal_seek_cursor() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-journal - pkg-config1 + libsystemd-journal pkg-config1 file. diff --git a/man/sd_journal_stream_fd.xml b/man/sd_journal_stream_fd.xml index ec42e8cb1b..3577526f20 100644 --- a/man/sd_journal_stream_fd.xml +++ b/man/sd_journal_stream_fd.xml @@ -114,8 +114,7 @@ The sd_journal_stream_fd() interface is available as shared library, which can be compiled and linked to with the - libsystemd-journal - pkg-config1 + libsystemd-journal pkg-config1 file. diff --git a/man/sd_listen_fds.xml b/man/sd_listen_fds.xml index 9d9f4d0d76..c9b3997015 100644 --- a/man/sd_listen_fds.xml +++ b/man/sd_listen_fds.xml @@ -151,8 +151,7 @@ sd-daemon.h files. These interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-daemon - pkg-config1 + libsystemd-daemon pkg-config1 file. Alternatively, applications consuming these APIs may copy the implementation into their source tree. For more details about the reference diff --git a/man/sd_login_monitor_new.xml b/man/sd_login_monitor_new.xml index c7650e6ba3..e93f93f9ce 100644 --- a/man/sd_login_monitor_new.xml +++ b/man/sd_login_monitor_new.xml @@ -226,8 +226,7 @@ else { sd_login_monitor_get_timeout() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-login - pkg-config1 + libsystemd-login pkg-config1 file. diff --git a/man/sd_notify.xml b/man/sd_notify.xml index 52614a2071..a7bf17f9c6 100644 --- a/man/sd_notify.xml +++ b/man/sd_notify.xml @@ -238,8 +238,7 @@ sd-daemon.h files. These interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-daemon - pkg-config1 + libsystemd-daemon pkg-config1 file. Alternatively, applications consuming these APIs may copy the implementation into their source tree. For more details about the reference implementation see diff --git a/man/sd_pid_get_session.xml b/man/sd_pid_get_session.xml index b45c9a5526..fd1ce4b87e 100644 --- a/man/sd_pid_get_session.xml +++ b/man/sd_pid_get_session.xml @@ -169,8 +169,7 @@ sd_pid_get_machine_name() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-login - pkg-config1 + libsystemd-login pkg-config1 file. Note that the login session identifier as diff --git a/man/sd_seat_get_active.xml b/man/sd_seat_get_active.xml index 3060ec7d52..8b32bdc669 100644 --- a/man/sd_seat_get_active.xml +++ b/man/sd_seat_get_active.xml @@ -163,8 +163,7 @@ sd_seat_can_grapical() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-login - pkg-config1 + libsystemd-login pkg-config1 file. diff --git a/man/sd_session_is_active.xml b/man/sd_session_is_active.xml index 0146fb427b..e89117d990 100644 --- a/man/sd_session_is_active.xml +++ b/man/sd_session_is_active.xml @@ -241,8 +241,7 @@ sd_session_get_tty() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-login - pkg-config1 + libsystemd-login pkg-config1 file. diff --git a/man/sd_uid_get_state.xml b/man/sd_uid_get_state.xml index 9a20b5453c..ba614f932b 100644 --- a/man/sd_uid_get_state.xml +++ b/man/sd_uid_get_state.xml @@ -172,8 +172,7 @@ sd_uid_get_sessions(), and sd_uid_get_seats() interfaces are available as shared library, which can be compiled and - linked to with the libsystemd-login - pkg-config1 + linked to with the libsystemd-login pkg-config1 file. -- cgit v1.2.1 From 0a1eb06d9aacc1f007be04c4133031e0acc91cdd Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 30 Jun 2013 23:55:36 +0200 Subject: cgroup: readd proper cgroup empty tracking --- src/core/cgroup.c | 30 +++++++++++++++++++++--------- src/core/cgroup.h | 2 +- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 79467a82ce..1c818ab300 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -389,6 +389,10 @@ static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) { if (!path) return -ENOMEM; + r = hashmap_put(u->manager->cgroup_unit, path, u); + if (r < 0) + return r; + /* First, create our own group */ r = cg_create_with_mask(mask, path); if (r < 0) @@ -410,7 +414,7 @@ static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) { return 0; } -static void unit_realize_cgroup_now(Unit *u) { +static int unit_realize_cgroup_now(Unit *u) { CGroupControllerMask mask; assert(u); @@ -425,14 +429,14 @@ static void unit_realize_cgroup_now(Unit *u) { if (u->cgroup_realized && u->cgroup_mask == mask) - return; + return 0; /* First, realize parents */ if (UNIT_ISSET(u->slice)) unit_realize_cgroup_now(UNIT_DEREF(u->slice)); /* And then do the real work */ - unit_create_cgroups(u, mask); + return unit_create_cgroups(u, mask); } static void unit_add_to_cgroup_queue(Unit *u) { @@ -451,8 +455,9 @@ unsigned manager_dispatch_cgroup_queue(Manager *m) { while ((i = m->cgroup_queue)) { assert(i->in_cgroup_queue); - unit_realize_cgroup_now(i); - cgroup_context_apply(unit_get_cgroup_context(i), i->cgroup_mask, i->cgroup_path); + if (unit_realize_cgroup_now(i) >= 0) + cgroup_context_apply(unit_get_cgroup_context(i), i->cgroup_mask, i->cgroup_path); + n++; } @@ -484,14 +489,15 @@ static void unit_queue_siblings(Unit *u) { } } -void unit_realize_cgroup(Unit *u) { +int unit_realize_cgroup(Unit *u) { CGroupContext *c; + int r; assert(u); c = unit_get_cgroup_context(u); if (!c) - return; + return 0; /* So, here's the deal: when realizing the cgroups for this * unit, we need to first create all parents, but there's more @@ -508,10 +514,13 @@ void unit_realize_cgroup(Unit *u) { unit_queue_siblings(u); /* And realize this one now */ - unit_realize_cgroup_now(u); + r = unit_realize_cgroup_now(u); /* And apply the values */ - cgroup_context_apply(c, u->cgroup_mask, u->cgroup_path); + if (r >= 0) + cgroup_context_apply(c, u->cgroup_mask, u->cgroup_path); + + return r; } void unit_destroy_cgroup(Unit *u) { @@ -526,10 +535,13 @@ void unit_destroy_cgroup(Unit *u) { if (r < 0) log_error("Failed to destroy cgroup %s: %s", u->cgroup_path, strerror(-r)); + hashmap_remove(u->manager->cgroup_unit, u->cgroup_path); + free(u->cgroup_path); u->cgroup_path = NULL; u->cgroup_realized = false; u->cgroup_mask = 0; + } pid_t unit_search_main_pid(Unit *u) { diff --git a/src/core/cgroup.h b/src/core/cgroup.h index 96f1d9f7b6..786bd71c8b 100644 --- a/src/core/cgroup.h +++ b/src/core/cgroup.h @@ -97,7 +97,7 @@ void cgroup_context_free_device_allow(CGroupContext *c, CGroupDeviceAllow *a); void cgroup_context_free_blockio_device_weight(CGroupContext *c, CGroupBlockIODeviceWeight *w); void cgroup_context_free_blockio_device_bandwidth(CGroupContext *c, CGroupBlockIODeviceBandwidth *b); -void unit_realize_cgroup(Unit *u); +int unit_realize_cgroup(Unit *u); void unit_destroy_cgroup(Unit *u); int manager_setup_cgroup(Manager *m); -- cgit v1.2.1 From b56c28c31adc101df82c1c3c30740b47cbd4f782 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 30 Jun 2013 23:56:11 +0200 Subject: cgroup: implicitly add units to GC queue when their cgroups run empty --- src/core/cgroup.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 1c818ab300..cdccf3ff15 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -733,8 +733,12 @@ int manager_notify_cgroup_empty(Manager *m, const char *cgroup) { return 0; u = manager_get_unit_by_cgroup(m, cgroup); - if (u && UNIT_VTABLE(u)->notify_cgroup_empty) - UNIT_VTABLE(u)->notify_cgroup_empty(u); + if (u) { + if (UNIT_VTABLE(u)->notify_cgroup_empty) + UNIT_VTABLE(u)->notify_cgroup_empty(u); + + unit_add_to_gc_queue(u); + } return 0; } -- cgit v1.2.1 From 64fad95a324fde85aeb2dd6f3291a55374ee0113 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 30 Jun 2013 23:56:59 +0200 Subject: service: correct service bus introspection for timeouts --- src/core/dbus-service.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c index c2031c3bf1..e93ac55115 100644 --- a/src/core/dbus-service.c +++ b/src/core/dbus-service.c @@ -38,7 +38,8 @@ " \n" \ " \n" \ " \n" \ - " \n" \ + " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ @@ -110,7 +111,7 @@ static const BusProperty bus_exec_main_status_properties[] = { { "ExecMainPID", bus_property_append_pid, "u", offsetof(ExecStatus, pid) }, { "ExecMainCode", bus_property_append_int, "i", offsetof(ExecStatus, code) }, { "ExecMainStatus", bus_property_append_int, "i", offsetof(ExecStatus, status) }, - { NULL, } + {} }; static const BusProperty bus_service_properties[] = { @@ -119,7 +120,6 @@ static const BusProperty bus_service_properties[] = { { "PIDFile", bus_property_append_string, "s", offsetof(Service, pid_file), true }, { "NotifyAccess", bus_service_append_notify_access, "s", offsetof(Service, notify_access) }, { "RestartUSec", bus_property_append_usec, "t", offsetof(Service, restart_usec) }, - { "TimeoutUSec", bus_property_append_usec, "t", offsetof(Service, timeout_start_usec) }, { "TimeoutStartUSec", bus_property_append_usec, "t", offsetof(Service, timeout_start_usec) }, { "TimeoutStopUSec", bus_property_append_usec, "t", offsetof(Service, timeout_stop_usec) }, { "WatchdogUSec", bus_property_append_usec, "t", offsetof(Service, watchdog_usec) }, @@ -143,7 +143,7 @@ static const BusProperty bus_service_properties[] = { { "BusName", bus_property_append_string, "s", offsetof(Service, bus_name), true }, { "StatusText", bus_property_append_string, "s", offsetof(Service, status_text), true }, { "Result", bus_service_append_service_result,"s", offsetof(Service, result) }, - { NULL, } + {} }; DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *connection, DBusMessage *message) { @@ -156,7 +156,7 @@ DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *connectio { "org.freedesktop.systemd1.Service", bus_kill_context_properties, &s->kill_context }, { "org.freedesktop.systemd1.Service", bus_cgroup_context_properties, &s->cgroup_context }, { "org.freedesktop.systemd1.Service", bus_exec_main_status_properties, &s->main_exec_status }, - { NULL, } + {} }; SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "status"); -- cgit v1.2.1 From 6a95dff87daf899a96135c7ab87aa1b1a67f6afc Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 1 Jul 2013 00:01:29 +0200 Subject: dbus: expose cgroup properties in introspection everywhere --- src/core/dbus-cgroup.h | 2 +- src/core/dbus-mount.c | 1 + src/core/dbus-service.c | 1 + src/core/dbus-slice.c | 1 + src/core/dbus-socket.c | 1 + src/core/dbus-swap.c | 1 + 6 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/core/dbus-cgroup.h b/src/core/dbus-cgroup.h index c5908dd976..4ce1e7e7fa 100644 --- a/src/core/dbus-cgroup.h +++ b/src/core/dbus-cgroup.h @@ -27,7 +27,7 @@ #include "dbus-common.h" #include "cgroup.h" -#define BUS_CGROUP_CONTEXT_INTERFACE \ +#define BUS_CGROUP_CONTEXT_INTERFACE \ " \n" \ " \n" \ " \n" \ diff --git a/src/core/dbus-mount.c b/src/core/dbus-mount.c index ae04ab8c47..ef55fcb173 100644 --- a/src/core/dbus-mount.c +++ b/src/core/dbus-mount.c @@ -41,6 +41,7 @@ BUS_EXEC_COMMAND_INTERFACE("ExecRemount") \ BUS_EXEC_CONTEXT_INTERFACE \ BUS_KILL_CONTEXT_INTERFACE \ + BUS_CGROUP_CONTEXT_INTERFACE \ " \n" \ " \n" \ " \n" \ diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c index e93ac55115..e5e95a1ab9 100644 --- a/src/core/dbus-service.c +++ b/src/core/dbus-service.c @@ -54,6 +54,7 @@ BUS_EXEC_COMMAND_INTERFACE("ExecStopPost") \ BUS_EXEC_CONTEXT_INTERFACE \ BUS_KILL_CONTEXT_INTERFACE \ + BUS_CGROUP_CONTEXT_INTERFACE \ " \n" \ " \n" \ " \n" \ diff --git a/src/core/dbus-slice.c b/src/core/dbus-slice.c index db356adf30..3b677792fd 100644 --- a/src/core/dbus-slice.c +++ b/src/core/dbus-slice.c @@ -29,6 +29,7 @@ #define BUS_SLICE_INTERFACE \ " \n" \ + BUS_CGROUP_CONTEXT_INTERFACE \ " \n" #define INTROSPECTION \ diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c index 7ef55ec711..a431fa1921 100644 --- a/src/core/dbus-socket.c +++ b/src/core/dbus-socket.c @@ -40,6 +40,7 @@ BUS_EXEC_COMMAND_INTERFACE("ExecStopPost") \ BUS_EXEC_CONTEXT_INTERFACE \ BUS_KILL_CONTEXT_INTERFACE \ + BUS_CGROUP_CONTEXT_INTERFACE \ " \n" \ " \n" \ " \n" \ diff --git a/src/core/dbus-swap.c b/src/core/dbus-swap.c index 0248b4b391..d854e0fb5e 100644 --- a/src/core/dbus-swap.c +++ b/src/core/dbus-swap.c @@ -39,6 +39,7 @@ BUS_EXEC_COMMAND_INTERFACE("ExecDeactivate") \ BUS_EXEC_CONTEXT_INTERFACE \ BUS_KILL_CONTEXT_INTERFACE \ + BUS_CGROUP_CONTEXT_INTERFACE \ " \n" \ " \n" \ " \n" -- cgit v1.2.1 From a190eeb884840e1a431e22eee2c3b93c96ca7fa3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 1 Jul 2013 00:02:03 +0200 Subject: snapshot: snapshots are just a special kind of transient units now --- src/core/snapshot.c | 30 ++++++++++++++++-------------- src/core/snapshot.h | 1 - 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/core/snapshot.c b/src/core/snapshot.c index a63eccd8de..1423854098 100644 --- a/src/core/snapshot.c +++ b/src/core/snapshot.c @@ -40,6 +40,7 @@ static void snapshot_init(Unit *u) { UNIT(s)->ignore_on_isolate = true; UNIT(s)->ignore_on_snapshot = true; + UNIT(s)->allow_isolate = true; } static void snapshot_set_state(Snapshot *s, SnapshotState state) { @@ -66,7 +67,7 @@ static int snapshot_load(Unit *u) { /* Make sure that only snapshots created via snapshot_create() * can be loaded */ - if (!s->by_snapshot_create && UNIT(s)->manager->n_reloading <= 0) + if (!u->transient && UNIT(s)->manager->n_reloading <= 0) return -ENOENT; u->load_state = UNIT_LOADED; @@ -151,21 +152,24 @@ static int snapshot_deserialize_item(Unit *u, const char *key, const char *value if (streq(key, "state")) { SnapshotState state; - if ((state = snapshot_state_from_string(value)) < 0) + state = snapshot_state_from_string(value); + if (state < 0) log_debug("Failed to parse state value %s", value); else s->deserialized_state = state; } else if (streq(key, "cleanup")) { - if ((r = parse_boolean(value)) < 0) + r = parse_boolean(value); + if (r < 0) log_debug("Failed to parse cleanup value %s", value); else s->cleanup = r; } else if (streq(key, "wants")) { - if ((r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_WANTS, value, NULL, true)) < 0) + r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_WANTS, value, NULL, true); + if (r < 0) return r; } else log_debug("Unknown serialization key '%s'", key); @@ -186,9 +190,9 @@ _pure_ static const char *snapshot_sub_state_to_string(Unit *u) { } int snapshot_create(Manager *m, const char *name, bool cleanup, DBusError *e, Snapshot **_s) { - Iterator i; + _cleanup_free_ char *n = NULL; Unit *other, *u = NULL; - char *n = NULL; + Iterator i; int r; const char *k; @@ -221,24 +225,22 @@ int snapshot_create(Manager *m, const char *name, bool cleanup, DBusError *e, Sn break; free(n); + n = NULL; } - - name = n; } r = manager_load_unit_prepare(m, name, NULL, e, &u); - free(n); - if (r < 0) goto fail; - SNAPSHOT(u)->by_snapshot_create = true; + u->transient = true; manager_dispatch_load_queue(m); assert(u->load_state == UNIT_LOADED); HASHMAP_FOREACH_KEY(other, k, m->units, i) { - if (other->ignore_on_snapshot) + if (other->ignore_on_snapshot || + other->transient) continue; if (k != other->id) @@ -251,12 +253,12 @@ int snapshot_create(Manager *m, const char *name, bool cleanup, DBusError *e, Sn if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other))) continue; - if ((r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_WANTS, other, true)) < 0) + r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_WANTS, other, true); + if (r < 0) goto fail; } SNAPSHOT(u)->cleanup = cleanup; - u->allow_isolate = true; *_s = SNAPSHOT(u); return 0; diff --git a/src/core/snapshot.h b/src/core/snapshot.h index 56f87cff4d..2675b1b242 100644 --- a/src/core/snapshot.h +++ b/src/core/snapshot.h @@ -38,7 +38,6 @@ struct Snapshot { SnapshotState state, deserialized_state; bool cleanup; - bool by_snapshot_create:1; }; extern const UnitVTable snapshot_vtable; -- cgit v1.2.1 From a00963a2e4e98c0e4ef477b63b70c5e71d65fdc1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 1 Jul 2013 00:02:41 +0200 Subject: systemctl: show per-unit cgroup tree correctly following the new property --- src/systemctl/systemctl.c | 52 +++++++++++++++++------------------------------ 1 file changed, 19 insertions(+), 33 deletions(-) diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index ef1a079911..fde3f43a17 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -435,8 +435,12 @@ static void output_units_list(const struct unit_info *unit_infos, unsigned c) { } } -static int get_unit_list(DBusConnection *bus, DBusMessage **reply, - struct unit_info **unit_infos, unsigned *c) { +static int get_unit_list( + DBusConnection *bus, + DBusMessage **reply, + struct unit_info **unit_infos, + unsigned *c) { + DBusMessageIter iter, sub; size_t size = 0; int r; @@ -498,9 +502,11 @@ static int list_units(DBusConnection *bus, char **args) { return 0; } -static int get_triggered_units(DBusConnection *bus, const char* unit_path, - char*** triggered) -{ +static int get_triggered_units( + DBusConnection *bus, + const char* unit_path, + char*** triggered) { + const char *interface = "org.freedesktop.systemd1.Unit", *triggers_property = "Triggers"; _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; @@ -2779,7 +2785,7 @@ static void print_status_info(UnitStatusInfo *i) { printf(" Status: \"%s\"\n", i->status_text); if (i->control_group && - (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_by_spec(i->control_group, false) == 0)) { + (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) { unsigned c; printf(" CGroup: %s\n", i->control_group); @@ -2801,7 +2807,7 @@ static void print_status_info(UnitStatusInfo *i) { if (i->control_pid > 0) extra[k++] = i->control_pid; - show_cgroup_and_extra_by_spec(i->control_group, prefix, + show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, flags); } } @@ -2911,8 +2917,12 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn else if (streq(name, "SourcePath")) i->source_path = s; #ifndef LEGACY - else if (streq(name, "DefaultControlGroup")) - i->control_group = s; + else if (streq(name, "DefaultControlGroup")) { + const char *e; + e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":"); + if (e) + i->control_group = e; + } #endif else if (streq(name, "ControlGroup")) i->control_group = s; @@ -3259,30 +3269,6 @@ static int print_property(const char *name, DBusMessageIter *iter) { return 0; - } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "ControlGroupAttributes")) { - DBusMessageIter sub, sub2; - - dbus_message_iter_recurse(iter, &sub); - while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { - const char *controller, *attr, *value; - - dbus_message_iter_recurse(&sub, &sub2); - - if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &controller, true) >= 0 && - bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &attr, true) >= 0 && - bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &value, false) >= 0) { - - printf("ControlGroupAttributes={ controller=%s ; attribute=%s ; value=\"%s\" }\n", - controller, - attr, - value); - } - - dbus_message_iter_next(&sub); - } - - return 0; - } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && startswith(name, "Exec")) { DBusMessageIter sub; -- cgit v1.2.1 From 6c12b52e19640747e96f89d85422941a23dc6b29 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 1 Jul 2013 00:03:57 +0200 Subject: core: add new "scope" unit type for making a unit of pre-existing processes "Scope" units are very much like service units, however with the difference that they are created from pre-existing processes, rather than processes that systemd itself forks off. This means they are generated programmatically via the bus API as transient units rather than from static configuration read from disk. Also, they do not provide execution-time parameters, as at the time systemd adds the processes to the scope unit they already exist and the parameters cannot be applied anymore. The primary benefit of this new unit type is to create arbitrary cgroups for worker-processes forked off an existing service. This commit also adds a a new mode to "systemd-run" to run the specified processes in a scope rather then a transient service. --- Makefile.am | 4 + TODO | 2 + src/core/dbus-scope.c | 162 ++++++++++++++++ src/core/dbus-scope.h | 33 ++++ src/core/scope.c | 466 +++++++++++++++++++++++++++++++++++++++++++++++ src/core/scope.h | 69 +++++++ src/core/service.c | 5 +- src/core/slice.c | 5 +- src/core/unit.c | 3 +- src/core/unit.h | 2 + src/notify/notify.c | 3 +- src/run/run.c | 194 +++++++++++++++++--- src/shared/cgroup-util.c | 17 ++ src/shared/cgroup-util.h | 1 + src/shared/unit-name.c | 3 +- src/shared/unit-name.h | 1 + 16 files changed, 939 insertions(+), 31 deletions(-) create mode 100644 src/core/dbus-scope.c create mode 100644 src/core/dbus-scope.h create mode 100644 src/core/scope.c create mode 100644 src/core/scope.h diff --git a/Makefile.am b/Makefile.am index ea18640456..4593245d40 100644 --- a/Makefile.am +++ b/Makefile.am @@ -850,6 +850,8 @@ libsystemd_core_la_SOURCES = \ src/core/path.h \ src/core/slice.c \ src/core/slice.h \ + src/core/scope.c \ + src/core/scope.h \ src/core/load-dropin.c \ src/core/load-dropin.h \ src/core/execute.c \ @@ -886,6 +888,8 @@ libsystemd_core_la_SOURCES = \ src/core/dbus-path.h \ src/core/dbus-slice.c \ src/core/dbus-slice.h \ + src/core/dbus-scope.c \ + src/core/dbus-scope.h \ src/core/dbus-execute.c \ src/core/dbus-execute.h \ src/core/dbus-kill.c \ diff --git a/TODO b/TODO index 8a3df6037c..279446e6e0 100644 --- a/TODO +++ b/TODO @@ -28,6 +28,8 @@ Fedora 19: Features: +* service_coldplug() appears to reinstall the wrong stop timeout watch? + * transient units: allow creating auxiliary units with the same call * make BlockIODeviceWeight=, BlockIODeviceBandwidth= runtime settable diff --git a/src/core/dbus-scope.c b/src/core/dbus-scope.c new file mode 100644 index 0000000000..1497b76761 --- /dev/null +++ b/src/core/dbus-scope.c @@ -0,0 +1,162 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include + +#include "dbus-unit.h" +#include "dbus-common.h" +#include "dbus-cgroup.h" +#include "dbus-kill.h" +#include "selinux-access.h" +#include "dbus-scope.h" + +#define BUS_SCOPE_INTERFACE \ + " \n" \ + " \n" \ + BUS_KILL_CONTEXT_INTERFACE \ + BUS_CGROUP_CONTEXT_INTERFACE \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_UNIT_INTERFACE \ + BUS_SCOPE_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Scope\0" + +const char bus_scope_interface[] _introspect_("Scope") = BUS_SCOPE_INTERFACE; + +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_scope_append_scope_result, scope_result, ScopeResult); + +static const BusProperty bus_scope_properties[] = { + { "TimeoutStopUSec", bus_property_append_usec, "t", offsetof(Scope, timeout_stop_usec) }, + { "Result", bus_scope_append_scope_result, "s", offsetof(Scope, result) }, + {} +}; + +DBusHandlerResult bus_scope_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { + Scope *s = SCOPE(u); + + const BusBoundProperties bps[] = { + { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Scope", bus_scope_properties, s }, + { "org.freedesktop.systemd1.Scope", bus_cgroup_context_properties, &s->cgroup_context }, + { "org.freedesktop.systemd1.Scope", bus_kill_context_properties, &s->kill_context }, + {} + }; + + SELINUX_UNIT_ACCESS_CHECK(u, c, message, "status"); + + return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps); +} + +static int bus_scope_set_transient_properties( + Scope *s, + const char *name, + DBusMessageIter *i, + UnitSetPropertiesMode mode, + DBusError *error) { + + int r; + + assert(name); + assert(s); + assert(i); + + if (streq(name, "PIDs")) { + DBusMessageIter sub; + + if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(i) != DBUS_TYPE_UINT32) + return -EINVAL; + + r = set_ensure_allocated(&s->pids, trivial_hash_func, trivial_compare_func); + if (r < 0) + return r; + + dbus_message_iter_recurse(i, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_UINT32) { + uint32_t pid; + + dbus_message_iter_get_basic(&sub, &pid); + + if (pid <= 1) + return -EINVAL; + + r = set_put(s->pids, LONG_TO_PTR(pid)); + if (r < 0 && r != -EEXIST) + return r; + + dbus_message_iter_next(&sub); + } + + if (set_size(s->pids) <= 0) + return -EINVAL; + + return 1; + } + + return 0; +} + +int bus_scope_set_property( + Unit *u, + const char *name, + DBusMessageIter *i, + UnitSetPropertiesMode mode, + DBusError *error) { + + Scope *s = SCOPE(u); + int r; + + assert(name); + assert(u); + assert(i); + + r = bus_cgroup_set_property(u, &s->cgroup_context, name, i, mode, error); + if (r != 0) + return r; + + if (u->load_state == UNIT_STUB) { + /* While we are created we still accept PIDs */ + + r = bus_scope_set_transient_properties(s, name, i, mode, error); + if (r != 0) + return r; + } + + return 0; +} + +int bus_scope_commit_properties(Unit *u) { + assert(u); + + unit_realize_cgroup(u); + return 0; +} diff --git a/src/core/dbus-scope.h b/src/core/dbus-scope.h new file mode 100644 index 0000000000..e6836f13f0 --- /dev/null +++ b/src/core/dbus-scope.h @@ -0,0 +1,33 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include + +#include "unit.h" + +DBusHandlerResult bus_scope_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); + +int bus_scope_set_property(Unit *u, const char *name, DBusMessageIter *i, UnitSetPropertiesMode mode, DBusError *error); +int bus_scope_commit_properties(Unit *u); + +extern const char bus_scope_interface[]; diff --git a/src/core/scope.c b/src/core/scope.c new file mode 100644 index 0000000000..f88addadf3 --- /dev/null +++ b/src/core/scope.c @@ -0,0 +1,466 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +#include "unit.h" +#include "scope.h" +#include "load-fragment.h" +#include "log.h" +#include "dbus-scope.h" +#include "special.h" +#include "unit-name.h" +#include "load-dropin.h" + +static const UnitActiveState state_translation_table[_SCOPE_STATE_MAX] = { + [SCOPE_DEAD] = UNIT_INACTIVE, + [SCOPE_RUNNING] = UNIT_ACTIVE, + [SCOPE_STOP_SIGTERM] = UNIT_DEACTIVATING, + [SCOPE_STOP_SIGKILL] = UNIT_DEACTIVATING, + [SCOPE_FAILED] = UNIT_FAILED +}; + +static void scope_init(Unit *u) { + Scope *s = SCOPE(u); + + assert(u); + assert(u->load_state == UNIT_STUB); + + s->timeout_stop_usec = DEFAULT_TIMEOUT_USEC; + + watch_init(&s->timer_watch); + + cgroup_context_init(&s->cgroup_context); + kill_context_init(&s->kill_context); + + UNIT(s)->ignore_on_isolate = true; + UNIT(s)->ignore_on_snapshot = true; +} + +static void scope_done(Unit *u) { + Scope *s = SCOPE(u); + + assert(u); + + cgroup_context_done(&s->cgroup_context); + + set_free(s->pids); + s->pids = NULL; + + unit_unwatch_timer(u, &s->timer_watch); +} + +static void scope_set_state(Scope *s, ScopeState state) { + ScopeState old_state; + assert(s); + + old_state = s->state; + s->state = state; + + if (state != SCOPE_STOP_SIGTERM && + state != SCOPE_STOP_SIGKILL) + unit_unwatch_timer(UNIT(s), &s->timer_watch); + + if (state != old_state) + log_debug("%s changed %s -> %s", + UNIT(s)->id, + scope_state_to_string(old_state), + scope_state_to_string(state)); + + unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true); +} + +static int scope_add_default_dependencies(Scope *s) { + int r; + + assert(s); + + /* Make sure scopes are unloaded on shutdown */ + r = unit_add_two_dependencies_by_name( + UNIT(s), + UNIT_BEFORE, UNIT_CONFLICTS, + SPECIAL_SHUTDOWN_TARGET, NULL, true); + if (r < 0) + return r; + + return 0; +} + +static int scope_verify(Scope *s) { + assert(s); + + if (UNIT(s)->load_state != UNIT_LOADED) + return 0; + + if (set_size(s->pids) <= 0) { + log_error_unit(UNIT(s)->id, "Scope %s has no PIDs. Refusing.", UNIT(s)->id); + return -EINVAL; + } + + return 0; +} + +static int scope_load(Unit *u) { + Scope *s = SCOPE(u); + int r; + + assert(s); + assert(u->load_state == UNIT_STUB); + + if (!u->transient && UNIT(s)->manager->n_reloading <= 0) + return -ENOENT; + + u->load_state = UNIT_LOADED; + + r = unit_load_dropin(u); + if (r < 0) + return r; + + r = unit_add_default_slice(u); + if (r < 0) + return r; + + if (u->default_dependencies) { + r = scope_add_default_dependencies(s); + if (r < 0) + return r; + } + + return scope_verify(s); +} + +static int scope_coldplug(Unit *u) { + Scope *s = SCOPE(u); + int r; + + assert(s); + assert(s->state == SCOPE_DEAD); + + if (s->deserialized_state != s->state) { + + if ((s->deserialized_state == SCOPE_STOP_SIGKILL || s->deserialized_state == SCOPE_STOP_SIGTERM) + && s->timeout_stop_usec > 0) { + r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_stop_usec, &s->timer_watch); + if (r < 0) + + return r; + } + + scope_set_state(s, s->deserialized_state); + } + + return 0; +} + +static void scope_dump(Unit *u, FILE *f, const char *prefix) { + Scope *s = SCOPE(u); + + assert(s); + assert(f); + + fprintf(f, + "%sScope State: %s\n" + "%sResult: %s\n", + prefix, scope_state_to_string(s->state), + prefix, scope_result_to_string(s->result)); + + cgroup_context_dump(&s->cgroup_context, f, prefix); + kill_context_dump(&s->kill_context, f, prefix); +} + +static void scope_enter_dead(Scope *s, ScopeResult f) { + assert(s); + + if (f != SCOPE_SUCCESS) + s->result = f; + + scope_set_state(s, s->result != SCOPE_SUCCESS ? SCOPE_FAILED : SCOPE_DEAD); +} + +static void scope_enter_signal(Scope *s, ScopeState state, ScopeResult f) { + int r; + + assert(s); + + if (f != SCOPE_SUCCESS) + s->result = f; + + r = unit_kill_context( + UNIT(s), + &s->kill_context, + state != SCOPE_STOP_SIGTERM, + -1, -1, false); + if (r < 0) + goto fail; + + if (r > 0) { + if (s->timeout_stop_usec > 0) { + r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_stop_usec, &s->timer_watch); + if (r < 0) + goto fail; + } + + scope_set_state(s, state); + } else + scope_enter_dead(s, SCOPE_SUCCESS); + + return; + +fail: + log_warning_unit(UNIT(s)->id, + "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r)); + + scope_enter_dead(s, SCOPE_FAILURE_RESOURCES); +} + +static int scope_start(Unit *u) { + Scope *s = SCOPE(u); + int r; + + assert(s); + + if (s->state == SCOPE_STOP_SIGTERM || + s->state == SCOPE_STOP_SIGKILL) + return -EAGAIN; + + assert(s->state == SCOPE_DEAD); + + if (!u->transient && UNIT(s)->manager->n_reloading <= 0) + return -ENOENT; + + r = unit_realize_cgroup(u); + if (r < 0) { + log_error("Failed to realize cgroup: %s", strerror(-r)); + return r; + } + + r = cg_attach_many_with_mask(u->cgroup_mask, u->cgroup_path, s->pids); + if (r < 0) + return r; + + set_free(s->pids); + s->pids = NULL; + + s->result = SCOPE_SUCCESS; + + scope_set_state(s, SCOPE_RUNNING); + return 0; +} + +static int scope_stop(Unit *u) { + Scope *s = SCOPE(u); + + assert(s); + assert(s->state == SCOPE_RUNNING); + + if (s->state == SCOPE_STOP_SIGTERM || + s->state == SCOPE_STOP_SIGKILL) + return 0; + + assert(s->state == SCOPE_RUNNING); + + scope_enter_signal(s, SCOPE_STOP_SIGTERM, SCOPE_SUCCESS); + return 0; +} + +static int scope_kill(Unit *u, KillWho who, int signo, DBusError *error) { + return unit_kill_common(u, who, signo, -1, -1, error); +} + +static int scope_serialize(Unit *u, FILE *f, FDSet *fds) { + Scope *s = SCOPE(u); + + assert(s); + assert(f); + assert(fds); + + unit_serialize_item(u, f, "state", scope_state_to_string(s->state)); + return 0; +} + +static int scope_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) { + Scope *s = SCOPE(u); + + assert(u); + assert(key); + assert(value); + assert(fds); + + if (streq(key, "state")) { + ScopeState state; + + state = scope_state_from_string(value); + if (state < 0) + log_debug("Failed to parse state value %s", value); + else + s->deserialized_state = state; + + } else + log_debug("Unknown serialization key '%s'", key); + + return 0; +} + +static bool scope_check_gc(Unit *u) { + Scope *s = SCOPE(u); + int r; + + assert(s); + + /* Never clean up scopes that still have a process around, + * even if the scope is formally dead. */ + + if (UNIT(s)->cgroup_path) { + r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, UNIT(s)->cgroup_path, true); + if (r <= 0) + return true; + } + + return false; +} + +static void scope_timer_event(Unit *u, uint64_t elapsed, Watch*w) { + Scope *s = SCOPE(u); + + assert(s); + assert(elapsed == 1); + assert(w == &s->timer_watch); + + switch (s->state) { + + case SCOPE_STOP_SIGTERM: + if (s->kill_context.send_sigkill) { + log_warning_unit(u->id, "%s stopping timed out. Killing.", u->id); + scope_enter_signal(s, SCOPE_STOP_SIGKILL, SCOPE_FAILURE_TIMEOUT); + } else { + log_warning_unit(u->id, "%s stopping timed out. Skipping SIGKILL.", u->id); + scope_enter_dead(s, SCOPE_FAILURE_TIMEOUT); + } + + break; + + case SCOPE_STOP_SIGKILL: + log_warning_unit(u->id, "%s still around after SIGKILL. Ignoring.", u->id); + scope_enter_dead(s, SCOPE_FAILURE_TIMEOUT); + break; + + default: + assert_not_reached("Timeout at wrong time."); + } +} + +static void scope_notify_cgroup_empty_event(Unit *u) { + Scope *s = SCOPE(u); + assert(u); + + log_debug_unit(u->id, "%s: cgroup is empty", u->id); + + switch (s->state) { + + case SCOPE_RUNNING: + case SCOPE_STOP_SIGTERM: + case SCOPE_STOP_SIGKILL: + scope_enter_dead(s, SCOPE_SUCCESS); + + break; + + default: + ; + } +} + +_pure_ static UnitActiveState scope_active_state(Unit *u) { + assert(u); + + return state_translation_table[SCOPE(u)->state]; +} + +_pure_ static const char *scope_sub_state_to_string(Unit *u) { + assert(u); + + return scope_state_to_string(SCOPE(u)->state); +} + +static const char* const scope_state_table[_SCOPE_STATE_MAX] = { + [SCOPE_DEAD] = "dead", + [SCOPE_RUNNING] = "active", + [SCOPE_STOP_SIGTERM] = "stop-sigterm", + [SCOPE_STOP_SIGKILL] = "stop-sigkill", + [SCOPE_FAILED] = "failed", +}; + +DEFINE_STRING_TABLE_LOOKUP(scope_state, ScopeState); + +static const char* const scope_result_table[_SCOPE_RESULT_MAX] = { + [SCOPE_SUCCESS] = "success", + [SCOPE_FAILURE_RESOURCES] = "resources", + [SCOPE_FAILURE_TIMEOUT] = "timeout", +}; + +DEFINE_STRING_TABLE_LOOKUP(scope_result, ScopeResult); + +const UnitVTable scope_vtable = { + .object_size = sizeof(Scope), + .sections = + "Unit\0" + "Scope\0" + "Install\0", + + .private_section = "Scope", + .cgroup_context_offset = offsetof(Scope, cgroup_context), + + .no_alias = true, + .no_instances = true, + + .init = scope_init, + .load = scope_load, + .done = scope_done, + + .coldplug = scope_coldplug, + + .dump = scope_dump, + + .start = scope_start, + .stop = scope_stop, + + .kill = scope_kill, + + .serialize = scope_serialize, + .deserialize_item = scope_deserialize_item, + + .active_state = scope_active_state, + .sub_state_to_string = scope_sub_state_to_string, + + .check_gc = scope_check_gc, + + .timer_event = scope_timer_event, + + .notify_cgroup_empty = scope_notify_cgroup_empty_event, + + .bus_interface = "org.freedesktop.systemd1.Scope", + .bus_message_handler = bus_scope_message_handler, + .bus_set_property = bus_scope_set_property, + .bus_commit_properties = bus_scope_commit_properties, + + .can_transient = true +}; diff --git a/src/core/scope.h b/src/core/scope.h new file mode 100644 index 0000000000..2a3dcb73d7 --- /dev/null +++ b/src/core/scope.h @@ -0,0 +1,69 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +typedef struct Scope Scope; + +#include "unit.h" +#include "kill.h" + +typedef enum ScopeState { + SCOPE_DEAD, + SCOPE_RUNNING, + SCOPE_STOP_SIGTERM, + SCOPE_STOP_SIGKILL, + SCOPE_FAILED, + _SCOPE_STATE_MAX, + _SCOPE_STATE_INVALID = -1 +} ScopeState; + +typedef enum ScopeResult { + SCOPE_SUCCESS, + SCOPE_FAILURE_RESOURCES, + SCOPE_FAILURE_TIMEOUT, + _SCOPE_RESULT_MAX, + _SCOPE_RESULT_INVALID = -1 +} ScopeResult; + +struct Scope { + Unit meta; + + CGroupContext cgroup_context; + KillContext kill_context; + + ScopeState state, deserialized_state; + ScopeResult result; + + usec_t timeout_stop_usec; + + Set *pids; + + Watch timer_watch; +}; + +extern const UnitVTable scope_vtable; + +const char* scope_state_to_string(ScopeState i) _const_; +ScopeState scope_state_from_string(const char *s) _pure_; + +const char* scope_result_to_string(ScopeResult i) _const_; +ScopeResult scope_result_from_string(const char *s) _pure_; diff --git a/src/core/service.c b/src/core/service.c index 6f18cbf759..2bc0dc5877 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -1617,6 +1617,7 @@ static int service_coldplug(Unit *u) { s->deserialized_state == SERVICE_FINAL_SIGTERM || s->deserialized_state == SERVICE_FINAL_SIGKILL || s->deserialized_state == SERVICE_AUTO_RESTART) { + if (s->deserialized_state == SERVICE_AUTO_RESTART || s->timeout_start_usec > 0) { usec_t k; @@ -2144,7 +2145,6 @@ static void service_kill_control_processes(Service *s) { return; p = strappenda(UNIT(s)->cgroup_path, "/control"); - cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, p, SIGKILL, true, true, true, NULL); } @@ -3322,8 +3322,7 @@ static void service_notify_cgroup_empty_event(Unit *u) { assert(u); - log_debug_unit(u->id, - "%s: cgroup is empty", u->id); + log_debug_unit(u->id, "%s: cgroup is empty", u->id); switch (s->state) { diff --git a/src/core/slice.c b/src/core/slice.c index 557f829088..40d416e35e 100644 --- a/src/core/slice.c +++ b/src/core/slice.c @@ -103,7 +103,10 @@ static int slice_add_default_dependencies(Slice *s) { assert(s); /* Make sure slices are unloaded on shutdown */ - r = unit_add_dependency_by_name(UNIT(s), UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true); + r = unit_add_two_dependencies_by_name( + UNIT(s), + UNIT_BEFORE, UNIT_CONFLICTS, + SPECIAL_SHUTDOWN_TARGET, NULL, true); if (r < 0) return r; diff --git a/src/core/unit.c b/src/core/unit.c index c6c9c18653..991111ab31 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -60,7 +60,8 @@ const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = { [UNIT_SNAPSHOT] = &snapshot_vtable, [UNIT_SWAP] = &swap_vtable, [UNIT_PATH] = &path_vtable, - [UNIT_SLICE] = &slice_vtable + [UNIT_SLICE] = &slice_vtable, + [UNIT_SCOPE] = &scope_vtable }; Unit *unit_new(Manager *m, size_t size) { diff --git a/src/core/unit.h b/src/core/unit.h index 8a62787b38..ed4df18246 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -280,6 +280,7 @@ typedef enum UnitSetPropertiesMode { #include "swap.h" #include "path.h" #include "slice.h" +#include "scope.h" struct UnitVTable { /* How much memory does an object of this unit type need */ @@ -462,6 +463,7 @@ DEFINE_CAST(SNAPSHOT, Snapshot); DEFINE_CAST(SWAP, Swap); DEFINE_CAST(PATH, Path); DEFINE_CAST(SLICE, Slice); +DEFINE_CAST(SCOPE, Scope); Unit *unit_new(Manager *m, size_t size); void unit_free(Unit *u); diff --git a/src/notify/notify.c b/src/notify/notify.c index 1e9766f862..a688a9f879 100644 --- a/src/notify/notify.c +++ b/src/notify/notify.c @@ -157,7 +157,8 @@ int main(int argc, char* argv[]) { log_parse_environment(); log_open(); - if ((r = parse_argv(argc, argv)) <= 0) { + r = parse_argv(argc, argv); + if (r <= 0) { retval = r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; goto finish; } diff --git a/src/run/run.c b/src/run/run.c index 9f8bda48af..b45116870c 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -20,22 +20,104 @@ ***/ #include +#include #include "sd-bus.h" #include "bus-internal.h" #include "bus-message.h" #include "strv.h" +#include "build.h" +#include "unit-name.h" -static int start_transient_service( - sd_bus *bus, - const char *name, - char **argv, - sd_bus_error *error) { +static bool arg_scope = false; +static bool arg_user = false; +static const char *arg_unit = NULL; - _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL; - char **i; +static int help(void) { + + printf("%s [OPTIONS...] [COMMAND LINE...]\n\n" + "Notify the init system about service status updates.\n\n" + " -h --help Show this help\n" + " --version Show package version\n" + " --user Run as user unit\n" + " --scope Run this as scope rather than service\n" + " --unit=UNIT Run under the specified unit name\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_VERSION = 0x100, + ARG_USER, + ARG_SCOPE, + ARG_UNIT + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "user", no_argument, NULL, ARG_USER }, + { "scope", no_argument, NULL, ARG_SCOPE }, + { "unit", required_argument, NULL, ARG_UNIT }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "+h", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_VERSION: + puts(PACKAGE_STRING); + puts(SYSTEMD_FEATURES); + return 0; + + case ARG_USER: + arg_user = true; + break; + + case ARG_SCOPE: + arg_scope = true; + break; + + case ARG_UNIT: + arg_unit = optarg; + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + if (optind >= argc) { + log_error("Command line to execute required."); + return -EINVAL; + } + + return 1; +} + +static int message_start_transient_unit_new(sd_bus *bus, const char *name, sd_bus_message **ret) { + _cleanup_bus_message_unref_ sd_bus_message *m = NULL; int r; + log_info("Running as unit %s.", name); + r = sd_bus_message_new_method_call( bus, "org.freedesktop.systemd1", @@ -57,6 +139,47 @@ static int start_transient_service( if (r < 0) return r; + *ret = m; + m = NULL; + + return 0; +} + +static int message_start_transient_unit_send(sd_bus *bus, sd_bus_message *m, sd_bus_error *error, sd_bus_message **reply) { + int r; + + r = sd_bus_message_close_container(m); + if (r < 0) + return r; + + r = sd_bus_message_close_container(m); + if (r < 0) + return r; + + return sd_bus_send_with_reply_and_block(bus, m, 0, error, reply); +} + +static int start_transient_service( + sd_bus *bus, + char **argv, + sd_bus_error *error) { + + _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL; + _cleanup_free_ char *name = NULL; + char **i; + int r; + + if (arg_unit) + name = unit_name_mangle_with_suffix(arg_unit, ".service"); + else + asprintf(&name, "run-%lu.service", (unsigned long) getpid()); + if (!name) + return -ENOMEM; + + r = message_start_transient_unit_new(bus, name, &m); + if (r < 0) + return r; + r = sd_bus_message_append(m, "s", "ExecStart"); if (r < 0) return r; @@ -107,46 +230,69 @@ static int start_transient_service( if (r < 0) return r; - r = sd_bus_message_close_container(m); + return message_start_transient_unit_send(bus, m, error, &reply); +} + +static int start_transient_scope( + sd_bus *bus, + char **argv, + sd_bus_error *error) { + + _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL; + _cleanup_free_ char *name = NULL; + int r; + + if (arg_unit) + name = unit_name_mangle_with_suffix(arg_unit, ".scope"); + else + asprintf(&name, "run-%lu.scope", (unsigned long) getpid()); + if (!name) + return -ENOMEM; + + r = message_start_transient_unit_new(bus, name, &m); if (r < 0) return r; - r = sd_bus_message_close_container(m); + r = sd_bus_message_append(m, "sv", "PIDs", "au", 1, (uint32_t) getpid()); + if (r < 0) + return r; + + r = message_start_transient_unit_send(bus, m, error, &reply); if (r < 0) return r; - return sd_bus_send_with_reply_and_block(bus, m, 0, error, &reply); + execvp(argv[0], argv); + log_error("Failed to execute: %m"); + return -errno; } int main(int argc, char* argv[]) { sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_bus_unref_ sd_bus *bus = NULL; - _cleanup_free_ char *name = NULL; int r; log_parse_environment(); log_open(); - if (argc < 2) { - log_error("Missing command line."); - r = -EINVAL; + r = parse_argv(argc, argv); + if (r <= 0) goto fail; - } - r = sd_bus_open_user(&bus); + if (arg_user) + r = sd_bus_open_user(&bus); + else + r = sd_bus_open_system(&bus); if (r < 0) { - log_error("Failed to create new bus: %s", strerror(-r)); - goto fail; - } - - if (asprintf(&name, "run-%lu.service", (unsigned long) getpid()) < 0) { - r = log_oom(); + log_error("Failed to create new bus connection: %s", strerror(-r)); goto fail; } - r = start_transient_service(bus, name, argv + 1, &error); + if (arg_scope) + r = start_transient_scope(bus, argv + optind, &error); + else + r = start_transient_service(bus, argv + optind, &error); if (r < 0) { - log_error("Failed start transient service: %s", error.message); + log_error("Failed start transient unit: %s", error.message); sd_bus_error_free(&error); goto fail; } diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index 5816b7d4d6..0e5da23ecd 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -1679,6 +1679,23 @@ int cg_attach_with_mask(CGroupControllerMask mask, const char *path, pid_t pid) return r; } +int cg_attach_many_with_mask(CGroupControllerMask mask, const char *path, Set* pids) { + Iterator i; + void *pidp; + int r = 0; + + SET_FOREACH(pidp, pids, i) { + pid_t pid = PTR_TO_LONG(pidp); + int k; + + k = cg_attach_with_mask(mask, path, pid); + if (k < 0) + r = k; + } + + return r; +} + int cg_migrate_with_mask(CGroupControllerMask mask, const char *from, const char *to) { CGroupControllerMask bit = 1; const char *n; diff --git a/src/shared/cgroup-util.h b/src/shared/cgroup-util.h index 9883d941c2..c781aabb22 100644 --- a/src/shared/cgroup-util.h +++ b/src/shared/cgroup-util.h @@ -127,6 +127,7 @@ int cg_slice_to_path(const char *unit, char **ret); int cg_create_with_mask(CGroupControllerMask mask, const char *path); int cg_attach_with_mask(CGroupControllerMask mask, const char *path, pid_t pid); +int cg_attach_many_with_mask(CGroupControllerMask mask, const char *path, Set* pids); int cg_migrate_with_mask(CGroupControllerMask mask, const char *from, const char *to); int cg_trim_with_mask(CGroupControllerMask mask, const char *path, bool delete_root); diff --git a/src/shared/unit-name.c b/src/shared/unit-name.c index bf1ab794a8..f2c30a6e4f 100644 --- a/src/shared/unit-name.c +++ b/src/shared/unit-name.c @@ -44,7 +44,8 @@ static const char* const unit_type_table[_UNIT_TYPE_MAX] = { [UNIT_TIMER] = "timer", [UNIT_SWAP] = "swap", [UNIT_PATH] = "path", - [UNIT_SLICE] = "slice" + [UNIT_SLICE] = "slice", + [UNIT_SCOPE] = "scope" }; DEFINE_STRING_TABLE_LOOKUP(unit_type, UnitType); diff --git a/src/shared/unit-name.h b/src/shared/unit-name.h index 922d75232d..88f2b83443 100644 --- a/src/shared/unit-name.h +++ b/src/shared/unit-name.h @@ -42,6 +42,7 @@ enum UnitType { UNIT_SWAP, UNIT_PATH, UNIT_SLICE, + UNIT_SCOPE, _UNIT_TYPE_MAX, _UNIT_TYPE_INVALID = -1 }; -- cgit v1.2.1 From 9f2e86af0600e99cff00d1c92f9bb8d38f29896a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 1 Jul 2013 00:40:56 +0200 Subject: core: allow setting of the description string for transient units --- src/core/dbus-scope.c | 4 ++-- src/core/dbus-service.c | 4 ++-- src/core/dbus-unit.c | 33 ++++++++++++++++++++++++++++++ src/run/run.c | 53 +++++++++++++++++++++++++++++++++++-------------- 4 files changed, 75 insertions(+), 19 deletions(-) diff --git a/src/core/dbus-scope.c b/src/core/dbus-scope.c index 1497b76761..604d147945 100644 --- a/src/core/dbus-scope.c +++ b/src/core/dbus-scope.c @@ -76,7 +76,7 @@ DBusHandlerResult bus_scope_message_handler(Unit *u, DBusConnection *c, DBusMess return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps); } -static int bus_scope_set_transient_properties( +static int bus_scope_set_transient_property( Scope *s, const char *name, DBusMessageIter *i, @@ -146,7 +146,7 @@ int bus_scope_set_property( if (u->load_state == UNIT_STUB) { /* While we are created we still accept PIDs */ - r = bus_scope_set_transient_properties(s, name, i, mode, error); + r = bus_scope_set_transient_property(s, name, i, mode, error); if (r != 0) return r; } diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c index e5e95a1ab9..3bedda6c01 100644 --- a/src/core/dbus-service.c +++ b/src/core/dbus-service.c @@ -165,7 +165,7 @@ DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *connectio return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps); } -static int bus_service_set_transient_properties( +static int bus_service_set_transient_property( Service *s, const char *name, DBusMessageIter *i, @@ -304,7 +304,7 @@ int bus_service_set_property( if (u->transient && u->load_state == UNIT_STUB) { /* This is a transient unit, let's load a little more */ - r = bus_service_set_transient_properties(s, name, i, mode, error); + r = bus_service_set_transient_property(s, name, i, mode, error); if (r != 0) return r; } diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index f518505750..36c3abdb97 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -764,6 +764,37 @@ oom: return DBUS_HANDLER_RESULT_NEED_MEMORY; } +static int bus_unit_set_transient_property( + Unit *u, + const char *name, + DBusMessageIter *i, + UnitSetPropertiesMode mode, + DBusError *error) { + + int r; + + assert(u); + assert(name); + assert(i); + + if (streq(name, "Description")) { + const char *description; + + if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(i, &description); + + r = unit_set_description(u, description); + if (r < 0) + return r; + + return 1; + } + + return 0; +} + int bus_unit_set_properties( Unit *u, DBusMessageIter *iter, @@ -823,6 +854,8 @@ int bus_unit_set_properties( dbus_message_iter_recurse(&sub2, &sub3); r = UNIT_VTABLE(u)->bus_set_property(u, name, &sub3, for_real ? mode : UNIT_CHECK, error); + if (r == 0 && u->transient && u->load_state == UNIT_STUB) + r = bus_unit_set_transient_property(u, name, &sub3, for_real ? mode : UNIT_CHECK, error); if (r < 0) return r; if (r == 0) { diff --git a/src/run/run.c b/src/run/run.c index b45116870c..98c3af058f 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -32,6 +32,7 @@ static bool arg_scope = false; static bool arg_user = false; static const char *arg_unit = NULL; +static const char *arg_description = NULL; static int help(void) { @@ -41,7 +42,8 @@ static int help(void) { " --version Show package version\n" " --user Run as user unit\n" " --scope Run this as scope rather than service\n" - " --unit=UNIT Run under the specified unit name\n", + " --unit=UNIT Run under the specified unit name\n" + " --description=TEXT Description for unit\n", program_invocation_short_name); return 0; @@ -53,16 +55,18 @@ static int parse_argv(int argc, char *argv[]) { ARG_VERSION = 0x100, ARG_USER, ARG_SCOPE, - ARG_UNIT + ARG_UNIT, + ARG_DESCRIPTION }; static const struct option options[] = { - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, ARG_VERSION }, - { "user", no_argument, NULL, ARG_USER }, - { "scope", no_argument, NULL, ARG_SCOPE }, - { "unit", required_argument, NULL, ARG_UNIT }, - { NULL, 0, NULL, 0 } + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "user", no_argument, NULL, ARG_USER }, + { "scope", no_argument, NULL, ARG_SCOPE }, + { "unit", required_argument, NULL, ARG_UNIT }, + { "description", required_argument, NULL, ARG_DESCRIPTION }, + { NULL, 0, NULL, 0 }, }; int c; @@ -95,6 +99,10 @@ static int parse_argv(int argc, char *argv[]) { arg_unit = optarg; break; + case ARG_DESCRIPTION: + arg_description = optarg; + break; + case '?': return -EINVAL; @@ -135,7 +143,7 @@ static int message_start_transient_unit_new(sd_bus *bus, const char *name, sd_bu if (r < 0) return r; - r = sd_bus_message_open_container(m, 'r', "sv"); + r = sd_bus_message_append(m, "(sv)", "Description", "s", arg_description); if (r < 0) return r; @@ -148,10 +156,6 @@ static int message_start_transient_unit_new(sd_bus *bus, const char *name, sd_bu static int message_start_transient_unit_send(sd_bus *bus, sd_bus_message *m, sd_bus_error *error, sd_bus_message **reply) { int r; - r = sd_bus_message_close_container(m); - if (r < 0) - return r; - r = sd_bus_message_close_container(m); if (r < 0) return r; @@ -180,6 +184,10 @@ static int start_transient_service( if (r < 0) return r; + r = sd_bus_message_open_container(m, 'r', "sv"); + if (r < 0) + return r; + r = sd_bus_message_append(m, "s", "ExecStart"); if (r < 0) return r; @@ -230,6 +238,10 @@ static int start_transient_service( if (r < 0) return r; + r = sd_bus_message_close_container(m); + if (r < 0) + return r; + return message_start_transient_unit_send(bus, m, error, &reply); } @@ -253,7 +265,7 @@ static int start_transient_scope( if (r < 0) return r; - r = sd_bus_message_append(m, "sv", "PIDs", "au", 1, (uint32_t) getpid()); + r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, (uint32_t) getpid()); if (r < 0) return r; @@ -269,6 +281,7 @@ static int start_transient_scope( int main(int argc, char* argv[]) { sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_bus_unref_ sd_bus *bus = NULL; + _cleanup_free_ char *description = NULL; int r; log_parse_environment(); @@ -278,6 +291,16 @@ int main(int argc, char* argv[]) { if (r <= 0) goto fail; + if (!arg_description) { + description = strv_join(argv + optind, " "); + if (!description) { + r = log_oom(); + goto fail; + } + + arg_description = description; + } + if (arg_user) r = sd_bus_open_user(&bus); else @@ -292,7 +315,7 @@ int main(int argc, char* argv[]) { else r = start_transient_service(bus, argv + optind, &error); if (r < 0) { - log_error("Failed start transient unit: %s", error.message); + log_error("Failed start transient unit: %s", error.message ? error.message : strerror(-r)); sd_bus_error_free(&error); goto fail; } -- cgit v1.2.1 From d7550a6752be85f98408a86b7ae23a033e9b2983 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 1 Jul 2013 02:45:02 +0200 Subject: core: move ControlGroup and Slice properties out of the dbus "Unit" interface Slice/ControlGroup only really makes sense for unit types which actually have cgroups attached to them, hence move them out of the generic Unit interface and into the specific unit type interfaces. These fields will continue to be part of Unit though, simply because things are a log easier that way. However, regardless how this looks internally we should keep things clean and independent of the specific implementation of the inside. --- src/core/dbus-mount.c | 2 ++ src/core/dbus-scope.c | 2 ++ src/core/dbus-service.c | 2 ++ src/core/dbus-slice.c | 2 ++ src/core/dbus-socket.c | 6 ++++-- src/core/dbus-swap.c | 2 ++ src/core/dbus-unit.c | 7 +++++-- src/core/dbus-unit.h | 7 +++++-- 8 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/core/dbus-mount.c b/src/core/dbus-mount.c index ef55fcb173..72e187063c 100644 --- a/src/core/dbus-mount.c +++ b/src/core/dbus-mount.c @@ -36,6 +36,7 @@ " \n" \ " \n" \ " \n" \ + BUS_UNIT_CGROUP_INTERFACE \ BUS_EXEC_COMMAND_INTERFACE("ExecMount") \ BUS_EXEC_COMMAND_INTERFACE("ExecUnmount") \ BUS_EXEC_COMMAND_INTERFACE("ExecRemount") \ @@ -158,6 +159,7 @@ DBusHandlerResult bus_mount_message_handler(Unit *u, DBusConnection *c, DBusMess const BusBoundProperties bps[] = { { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Mount", bus_unit_cgroup_properties, u }, { "org.freedesktop.systemd1.Mount", bus_mount_properties, m }, { "org.freedesktop.systemd1.Mount", bus_exec_context_properties, &m->exec_context }, { "org.freedesktop.systemd1.Mount", bus_kill_context_properties, &m->kill_context }, diff --git a/src/core/dbus-scope.c b/src/core/dbus-scope.c index 604d147945..30b9c00335 100644 --- a/src/core/dbus-scope.c +++ b/src/core/dbus-scope.c @@ -30,6 +30,7 @@ #define BUS_SCOPE_INTERFACE \ " \n" \ + BUS_UNIT_CGROUP_INTERFACE \ " \n" \ BUS_KILL_CONTEXT_INTERFACE \ BUS_CGROUP_CONTEXT_INTERFACE \ @@ -65,6 +66,7 @@ DBusHandlerResult bus_scope_message_handler(Unit *u, DBusConnection *c, DBusMess const BusBoundProperties bps[] = { { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Scope", bus_unit_cgroup_properties, u }, { "org.freedesktop.systemd1.Scope", bus_scope_properties, s }, { "org.freedesktop.systemd1.Scope", bus_cgroup_context_properties, &s->cgroup_context }, { "org.freedesktop.systemd1.Scope", bus_kill_context_properties, &s->kill_context }, diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c index 3bedda6c01..c2e02209be 100644 --- a/src/core/dbus-service.c +++ b/src/core/dbus-service.c @@ -46,6 +46,7 @@ " \n" \ " \n" \ " \n" \ + BUS_UNIT_CGROUP_INTERFACE \ BUS_EXEC_COMMAND_INTERFACE("ExecStartPre") \ BUS_EXEC_COMMAND_INTERFACE("ExecStart") \ BUS_EXEC_COMMAND_INTERFACE("ExecStartPost") \ @@ -152,6 +153,7 @@ DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *connectio const BusBoundProperties bps[] = { { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Service", bus_unit_cgroup_properties, u }, { "org.freedesktop.systemd1.Service", bus_service_properties, s }, { "org.freedesktop.systemd1.Service", bus_exec_context_properties, &s->exec_context }, { "org.freedesktop.systemd1.Service", bus_kill_context_properties, &s->kill_context }, diff --git a/src/core/dbus-slice.c b/src/core/dbus-slice.c index 3b677792fd..dac9fbdf5f 100644 --- a/src/core/dbus-slice.c +++ b/src/core/dbus-slice.c @@ -29,6 +29,7 @@ #define BUS_SLICE_INTERFACE \ " \n" \ + BUS_UNIT_CGROUP_INTERFACE \ BUS_CGROUP_CONTEXT_INTERFACE \ " \n" @@ -53,6 +54,7 @@ DBusHandlerResult bus_slice_message_handler(Unit *u, DBusConnection *c, DBusMess const BusBoundProperties bps[] = { { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Slice", bus_unit_cgroup_properties, u }, { "org.freedesktop.systemd1.Slice", bus_cgroup_context_properties, &s->cgroup_context }, {} }; diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c index a431fa1921..da317edb86 100644 --- a/src/core/dbus-socket.c +++ b/src/core/dbus-socket.c @@ -34,6 +34,7 @@ " \n" \ " \n" \ " \n" \ + BUS_UNIT_CGROUP_INTERFACE \ BUS_EXEC_COMMAND_INTERFACE("ExecStartPre") \ BUS_EXEC_COMMAND_INTERFACE("ExecStartPost") \ BUS_EXEC_COMMAND_INTERFACE("ExecStopPre") \ @@ -196,18 +197,19 @@ static const BusProperty bus_socket_properties[] = { { "SmackLabel", bus_property_append_string, "s", offsetof(Socket, smack), true }, { "SmackLabelIPIn", bus_property_append_string, "s", offsetof(Socket, smack_ip_in), true }, { "SmackLabelIPOut",bus_property_append_string, "s", offsetof(Socket, smack_ip_out), true }, - { NULL, } + {} }; DBusHandlerResult bus_socket_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { Socket *s = SOCKET(u); const BusBoundProperties bps[] = { { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Socket", bus_unit_cgroup_properties, u }, { "org.freedesktop.systemd1.Socket", bus_socket_properties, s }, { "org.freedesktop.systemd1.Socket", bus_exec_context_properties, &s->exec_context }, { "org.freedesktop.systemd1.Socket", bus_kill_context_properties, &s->kill_context }, { "org.freedesktop.systemd1.Socket", bus_cgroup_context_properties, &s->cgroup_context }, - { NULL, } + {} }; SELINUX_UNIT_ACCESS_CHECK(u, c, message, "status"); diff --git a/src/core/dbus-swap.c b/src/core/dbus-swap.c index d854e0fb5e..86fcf16eaf 100644 --- a/src/core/dbus-swap.c +++ b/src/core/dbus-swap.c @@ -35,6 +35,7 @@ " \n" \ " \n" \ " \n" \ + BUS_UNIT_CGROUP_INTERFACE \ BUS_EXEC_COMMAND_INTERFACE("ExecActivate") \ BUS_EXEC_COMMAND_INTERFACE("ExecDeactivate") \ BUS_EXEC_CONTEXT_INTERFACE \ @@ -105,6 +106,7 @@ DBusHandlerResult bus_swap_message_handler(Unit *u, DBusConnection *c, DBusMessa Swap *s = SWAP(u); const BusBoundProperties bps[] = { { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Swap", bus_unit_cgroup_properties, u }, { "org.freedesktop.systemd1.Swap", bus_swap_properties, s }, { "org.freedesktop.systemd1.Swap", bus_exec_context_properties, &s->exec_context }, { "org.freedesktop.systemd1.Swap", bus_kill_context_properties, &s->kill_context }, diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index 36c3abdb97..6273e46274 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -878,7 +878,6 @@ const BusProperty bus_unit_properties[] = { { "Id", bus_property_append_string, "s", offsetof(Unit, id), true }, { "Names", bus_unit_append_names, "as", 0 }, { "Following", bus_unit_append_following, "s", 0 }, - { "Slice", bus_unit_append_slice, "s", 0 }, { "Requires", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRES]), true }, { "RequiresOverridable", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRES_OVERRIDABLE]), true }, { "Requisite", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUISITE]), true }, @@ -937,7 +936,11 @@ const BusProperty bus_unit_properties[] = { { "ConditionTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, condition_timestamp.monotonic) }, { "ConditionResult", bus_property_append_bool, "b", offsetof(Unit, condition_result) }, { "LoadError", bus_unit_append_load_error, "(ss)", 0 }, - { "ControlGroup", bus_property_append_string, "s", offsetof(Unit, cgroup_path), true }, { "Transient", bus_property_append_bool, "b", offsetof(Unit, transient) }, { NULL, } }; + +const BusProperty bus_unit_cgroup_properties[] = { + { "Slice", bus_unit_append_slice, "s", 0 }, + { "ControlGroup", bus_property_append_string, "s", offsetof(Unit, cgroup_path), true }, +}; diff --git a/src/core/dbus-unit.h b/src/core/dbus-unit.h index 18f7c4f088..d3f7ec621e 100644 --- a/src/core/dbus-unit.h +++ b/src/core/dbus-unit.h @@ -68,7 +68,6 @@ " \n" \ " \n" \ " \n" \ - " \n" \ " \n" \ " \n" \ " \n" \ @@ -127,15 +126,19 @@ " \n" \ " \n" \ " \n" \ - " \n" \ " \n" \ " \n" +#define BUS_UNIT_CGROUP_INTERFACE \ + " \n" \ + " \n" + #define BUS_UNIT_INTERFACES_LIST \ BUS_GENERIC_INTERFACES_LIST \ "org.freedesktop.systemd1.Unit\0" extern const BusProperty bus_unit_properties[]; +extern const BusProperty bus_unit_cgroup_properties[]; void bus_unit_send_change_signal(Unit *u); void bus_unit_send_removed_signal(Unit *u); -- cgit v1.2.1 From adb3a45d9a1cebdec30406cc2c04503fc5e735be Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 1 Jul 2013 02:47:11 +0200 Subject: scope: properly implement passive validity checking of PIDs field when creating transient scopes --- src/core/dbus-scope.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/core/dbus-scope.c b/src/core/dbus-scope.c index 30b9c00335..bddf8f4753 100644 --- a/src/core/dbus-scope.c +++ b/src/core/dbus-scope.c @@ -93,6 +93,7 @@ static int bus_scope_set_transient_property( if (streq(name, "PIDs")) { DBusMessageIter sub; + unsigned n; if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_ARRAY || dbus_message_iter_get_element_type(i) != DBUS_TYPE_UINT32) @@ -111,14 +112,17 @@ static int bus_scope_set_transient_property( if (pid <= 1) return -EINVAL; - r = set_put(s->pids, LONG_TO_PTR(pid)); - if (r < 0 && r != -EEXIST) - return r; + if (mode != UNIT_CHECK) { + r = set_put(s->pids, LONG_TO_PTR(pid)); + if (r < 0 && r != -EEXIST) + return r; + } dbus_message_iter_next(&sub); + n++; } - if (set_size(s->pids) <= 0) + if (n <= 0) return -EINVAL; return 1; -- cgit v1.2.1 From d28e9236e79e2d0a49aba472f86f7551ce9ca2f1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 1 Jul 2013 02:52:17 +0200 Subject: core: parse Slice= from the unit type specific unit file section Since not all unit types know Slice= it belongs in the unit type specific unit file section. --- TODO | 8 ++++---- src/core/load-fragment-gperf.gperf.m4 | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/TODO b/TODO index 279446e6e0..e8afa5f3df 100644 --- a/TODO +++ b/TODO @@ -36,6 +36,8 @@ Features: * split up BlockIOWeight= and BlockIODeviceWeight= +* introduce high-level settings for RT budget, swapiness + * how to reset dynamically changed attributes sanely? * when reloading configuration, apply new cgroup configuration @@ -48,10 +50,8 @@ Features: * split out CreateMachine into systemd-machined -* introduce new Scope unit type then make logind's session and machine - registration use this to set up cgroups - -* should Slice= be part of [Unit] or of [Service]? +* make logind's session and machine + registration use Slices to set up cgroups * journald: make sure ratelimit is actually really per-service with the new cgroup changes diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index aa07de0517..2325d6aa9a 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -83,7 +83,8 @@ $1.KillMode, config_parse_kill_mode, 0, $1.KillSignal, config_parse_kill_signal, 0, offsetof($1, kill_context.kill_signal)' )m4_dnl m4_define(`CGROUP_CONTEXT_CONFIG_ITEMS', -`$1.CPUAccounting, config_parse_bool, 0, offsetof($1, cgroup_context.cpu_accounting) +`$1.Slice, config_parse_unit_slice, 0, 0 +$1.CPUAccounting, config_parse_bool, 0, offsetof($1, cgroup_context.cpu_accounting) $1.CPUShares, config_parse_cpu_shares, 0, offsetof($1, cgroup_context) $1.MemoryAccounting, config_parse_bool, 0, offsetof($1, cgroup_context.memory_accounting) $1.MemoryLimit, config_parse_memory_limit, 0, offsetof($1, cgroup_context) @@ -124,7 +125,6 @@ Unit.OnFailureIsolate, config_parse_bool, 0, Unit.IgnoreOnIsolate, config_parse_bool, 0, offsetof(Unit, ignore_on_isolate) Unit.IgnoreOnSnapshot, config_parse_bool, 0, offsetof(Unit, ignore_on_snapshot) Unit.JobTimeoutSec, config_parse_sec, 0, offsetof(Unit, job_timeout) -Unit.Slice, config_parse_unit_slice, 0, 0 Unit.ConditionPathExists, config_parse_unit_condition_path, CONDITION_PATH_EXISTS, 0 Unit.ConditionPathExistsGlob, config_parse_unit_condition_path, CONDITION_PATH_EXISTS_GLOB, 0 Unit.ConditionPathIsDirectory, config_parse_unit_condition_path, CONDITION_PATH_IS_DIRECTORY, 0 -- cgit v1.2.1 From c221420be8744bb0f8b8a8145efc1f247f1aa801 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 1 Jul 2013 03:02:42 +0200 Subject: core: add support to run transient units in arbitrary slices --- src/core/dbus-unit.c | 19 +++++++++++++++++++ src/run/run.c | 24 ++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index 6273e46274..ad6d5a6038 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -790,6 +790,25 @@ static int bus_unit_set_transient_property( return r; return 1; + + } else if (streq(name, "Slice") && unit_get_cgroup_context(u)) { + const char *s; + Unit *slice; + + if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(i, &s); + + r = manager_load_unit(u->manager, s, NULL, error, &slice); + if (r < 0) + return r; + + if (slice->type != UNIT_SLICE) + return -EINVAL; + + unit_ref_set(&u->slice, slice); + return 1; } return 0; diff --git a/src/run/run.c b/src/run/run.c index 98c3af058f..e5a62d9e35 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -33,6 +33,7 @@ static bool arg_scope = false; static bool arg_user = false; static const char *arg_unit = NULL; static const char *arg_description = NULL; +static const char *arg_slice = NULL; static int help(void) { @@ -43,7 +44,8 @@ static int help(void) { " --user Run as user unit\n" " --scope Run this as scope rather than service\n" " --unit=UNIT Run under the specified unit name\n" - " --description=TEXT Description for unit\n", + " --description=TEXT Description for unit\n" + " --slice=SLICE Run in the specified slice\n", program_invocation_short_name); return 0; @@ -56,7 +58,8 @@ static int parse_argv(int argc, char *argv[]) { ARG_USER, ARG_SCOPE, ARG_UNIT, - ARG_DESCRIPTION + ARG_DESCRIPTION, + ARG_SLICE }; static const struct option options[] = { @@ -66,6 +69,7 @@ static int parse_argv(int argc, char *argv[]) { { "scope", no_argument, NULL, ARG_SCOPE }, { "unit", required_argument, NULL, ARG_UNIT }, { "description", required_argument, NULL, ARG_DESCRIPTION }, + { "slice", required_argument, NULL, ARG_SLICE }, { NULL, 0, NULL, 0 }, }; @@ -103,6 +107,10 @@ static int parse_argv(int argc, char *argv[]) { arg_description = optarg; break; + case ARG_SLICE: + arg_slice = optarg; + break; + case '?': return -EINVAL; @@ -147,6 +155,18 @@ static int message_start_transient_unit_new(sd_bus *bus, const char *name, sd_bu if (r < 0) return r; + if (!isempty(arg_slice)) { + _cleanup_free_ char *slice; + + slice = unit_name_mangle_with_suffix(arg_slice, ".slice"); + if (!slice) + return -ENOMEM; + + r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice); + if (r < 0) + return r; + } + *ret = m; m = NULL; -- cgit v1.2.1 From 3cf7b686e6b29f78de0af5929602cae4482f6d49 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 1 Jul 2013 19:39:50 +0200 Subject: hwdb: remove support for (not fully implemented) conditional properties --- src/libudev/libudev-hwdb.c | 6 +++++- src/udev/udevadm-hwdb.c | 18 ++++-------------- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/libudev/libudev-hwdb.c b/src/libudev/libudev-hwdb.c index a56ad753e4..5645a11437 100644 --- a/src/libudev/libudev-hwdb.c +++ b/src/libudev/libudev-hwdb.c @@ -140,9 +140,13 @@ static const struct trie_node_f *node_lookup_f(struct udev_hwdb *hwdb, const str } static int hwdb_add_property(struct udev_hwdb *hwdb, const char *key, const char *value) { - /* TODO: add sub-matches (+) against DMI data */ + /* + * Silently ignore all properties which do not start with a + * space; future extensions might use additional prefixes. + */ if (key[0] != ' ') return 0; + if (udev_list_entry_add(&hwdb->properties_list, key+1, value) == NULL) return -ENOMEM; return 0; diff --git a/src/udev/udevadm-hwdb.c b/src/udev/udevadm-hwdb.c index 3e849aaed6..10b490ee2b 100644 --- a/src/udev/udevadm-hwdb.c +++ b/src/udev/udevadm-hwdb.c @@ -406,14 +406,12 @@ static int import_file(struct trie *trie, const char *filename) { FILE *f; char line[LINE_MAX]; char match[LINE_MAX]; - char cond[LINE_MAX]; f = fopen(filename, "re"); if (f == NULL) return -errno; match[0] = '\0'; - cond[0] = '\0'; while (fgets(line, sizeof(line), f)) { size_t len; @@ -423,7 +421,6 @@ static int import_file(struct trie *trie, const char *filename) { /* new line, new record */ if (line[0] == '\n') { match[0] = '\0'; - cond[0] = '\0'; continue; } @@ -436,20 +433,10 @@ static int import_file(struct trie *trie, const char *filename) { /* start of new record */ if (match[0] == '\0') { strcpy(match, line); - cond[0] = '\0'; continue; } - if (line[0] == '+') { - strcpy(cond, line); - continue; - } - - /* TODO: support +; skip the entire record until we support it */ - if (cond[0] != '\0') - continue; - - /* value lines */ + /* value line */ if (line[0] == ' ') { char *value; @@ -459,7 +446,10 @@ static int import_file(struct trie *trie, const char *filename) { value[0] = '\0'; value++; trie_insert(trie, trie->root, match, line, value); + continue; } + + log_error("Error parsing line '%s' in '%s\n", line, filename); } fclose(f); return 0; -- cgit v1.2.1 From d9b17672ebf335292228fb193a842f410560d7a5 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 1 Jul 2013 19:41:19 +0200 Subject: hwdb: import data --- hwdb/20-OUI.hwdb | 907 +++++++++- hwdb/20-pci-vendor-model.hwdb | 3821 ++++++++++++++++++++++++++++++++++++++--- hwdb/20-usb-vendor-model.hwdb | 6 + 3 files changed, 4509 insertions(+), 225 deletions(-) diff --git a/hwdb/20-OUI.hwdb b/hwdb/20-OUI.hwdb index 72795c6a6d..90c0116ffd 100644 --- a/hwdb/20-OUI.hwdb +++ b/hwdb/20-OUI.hwdb @@ -2468,7 +2468,7 @@ OUI:0050C2340* ID_OUI_FROM_DATABASE=Virtu OUI:0050C2341* - ID_OUI_FROM_DATABASE=Novx Systems Canada Inc. + ID_OUI_FROM_DATABASE=Novx Systems OUI:0050C2342* ID_OUI_FROM_DATABASE=St. Michael Strategies @@ -3665,7 +3665,7 @@ OUI:0050C24CF* ID_OUI_FROM_DATABASE=Ziehl-Abegg AG OUI:0050C24D0* - ID_OUI_FROM_DATABASE=Radford Control Systems + ID_OUI_FROM_DATABASE=RCS Energy Management Ltd OUI:0050C24D1* ID_OUI_FROM_DATABASE=SLICAN sp. z o.o. @@ -12916,6 +12916,177 @@ OUI:40D8550EF* OUI:40D8550F0* ID_OUI_FROM_DATABASE=Redwood Systems +OUI:40D8550F1* + ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG + +OUI:40D8550F2* + ID_OUI_FROM_DATABASE=SigmaPhi Electronics + +OUI:40D8550F3* + ID_OUI_FROM_DATABASE=ECON Systems Inc. + +OUI:40D8550F4* + ID_OUI_FROM_DATABASE=MB Connect Line GmbH + +OUI:40D8550F5* + ID_OUI_FROM_DATABASE=CST Group + +OUI:40D8550F7* + ID_OUI_FROM_DATABASE=Comline Elektronik Elektrotechnik GmbH + +OUI:40D8550F8* + ID_OUI_FROM_DATABASE=Better Place + +OUI:40D8550F9* + ID_OUI_FROM_DATABASE=Invisua Lighting BV + +OUI:40D8550FA* + ID_OUI_FROM_DATABASE=Marmitek BV + +OUI:40D8550FB* + ID_OUI_FROM_DATABASE=InfoMac Sp. z o. o. Sp. k. + +OUI:40D8550FC* + ID_OUI_FROM_DATABASE=eumig industrie-tv GmbH + +OUI:40D8550FD* + ID_OUI_FROM_DATABASE=MONOGRAM technologies ltd + +OUI:40D8550FE* + ID_OUI_FROM_DATABASE=Cytech Technology Pte Ltd + +OUI:40D8550FF* + ID_OUI_FROM_DATABASE=YUYAMA MFG.CO.,LTD. + +OUI:40D855100* + ID_OUI_FROM_DATABASE=TASK SISTEMAS DE COMPUTACAO S.A. + +OUI:40D855101* + ID_OUI_FROM_DATABASE=e.p.g. Elettronica Srl + +OUI:40D855102* + ID_OUI_FROM_DATABASE=Power Electronics + +OUI:40D855103* + ID_OUI_FROM_DATABASE=Peek Traffic Corporation + +OUI:40D855104* + ID_OUI_FROM_DATABASE=IMPLE SISTEMAS ELETRONICOS EMBARCADOS LTDA + +OUI:40D855105* + ID_OUI_FROM_DATABASE=Tieline Research Pty Ltd + +OUI:40D855106* + ID_OUI_FROM_DATABASE=Orbital A/S + +OUI:40D855107* + ID_OUI_FROM_DATABASE=Smith Meter, Inc + +OUI:40D855108* + ID_OUI_FROM_DATABASE=ALPHA DESIGN CO.,LTD. + +OUI:40D855109* + ID_OUI_FROM_DATABASE=Rosslare Enterprises Limited + +OUI:40D85510A* + ID_OUI_FROM_DATABASE=DAVIS DERBY LIMITED + +OUI:40D85510B* + ID_OUI_FROM_DATABASE=So-Cool Corporation. + +OUI:40D85510C* + ID_OUI_FROM_DATABASE=Contrans TI sp. z o.o. + +OUI:40D85510D* + ID_OUI_FROM_DATABASE=Rite-Tech Industrial CO., Ltd. + +OUI:40D85510E* + ID_OUI_FROM_DATABASE=HKS-Prozesstechnik GmbH + +OUI:40D85510F* + ID_OUI_FROM_DATABASE=CAVALRY STORAGE INC + +OUI:40D855110* + ID_OUI_FROM_DATABASE=Aplex Technology Inc. + +OUI:40D855111* + ID_OUI_FROM_DATABASE=Grupo Epelsa S.L. + +OUI:40D855112* + ID_OUI_FROM_DATABASE=Halliburton - Sperry Drilling Service + +OUI:40D855113* + ID_OUI_FROM_DATABASE=Testbook Ltd + +OUI:40D855114* + ID_OUI_FROM_DATABASE=GENERAL DYNAMICS C4 SYSTEMS + +OUI:40D855115* + ID_OUI_FROM_DATABASE=MESA Electronic GmbH + +OUI:40D855116* + ID_OUI_FROM_DATABASE=Uniscan LLC + +OUI:40D855117* + ID_OUI_FROM_DATABASE=RCS Energy Management Limited + +OUI:40D855118* + ID_OUI_FROM_DATABASE=University of Nebraska -- Lincoln + +OUI:40D855119* + ID_OUI_FROM_DATABASE=OOO Group of Industrial Technologies + +OUI:40D85511A* + ID_OUI_FROM_DATABASE=Sicon srl + +OUI:40D85511B* + ID_OUI_FROM_DATABASE=nanoTRONIC GmbH + +OUI:40D85511C* + ID_OUI_FROM_DATABASE=DEUTA-WERKE GmbH + +OUI:40D85511D* + ID_OUI_FROM_DATABASE=ACD Elektronik GmBH + +OUI:40D85511E* + ID_OUI_FROM_DATABASE=CEMSI, Inc. + +OUI:40D85511F* + ID_OUI_FROM_DATABASE=KOMPAN Pawel Sokolowski + +OUI:40D855120* + ID_OUI_FROM_DATABASE=ObjectFab GmbH + +OUI:40D855121* + ID_OUI_FROM_DATABASE=shanghai Anjian Information technology co. , ltd. + +OUI:40D855122* + ID_OUI_FROM_DATABASE=ATX Networks Ltd. + +OUI:40D855123* + ID_OUI_FROM_DATABASE=ZAO NPC Kompjuternie Technologii + +OUI:40D855124* + ID_OUI_FROM_DATABASE=Debug s.r.l. + +OUI:40D855125* + ID_OUI_FROM_DATABASE=Scandyna A/S + +OUI:40D855126* + ID_OUI_FROM_DATABASE=TTI LTD + +OUI:40D855127* + ID_OUI_FROM_DATABASE=LIGHTSTAR + +OUI:40D855128* + ID_OUI_FROM_DATABASE=Akse srl + +OUI:40D855129* + ID_OUI_FROM_DATABASE=DSP DESIGN + +OUI:40D85512A* + ID_OUI_FROM_DATABASE=Jadpod Communication Company Limited + OUI:000000* ID_OUI_FROM_DATABASE=XEROX CORPORATION @@ -17663,7 +17834,7 @@ OUI:000630* ID_OUI_FROM_DATABASE=Adtranz Sweden OUI:000631* - ID_OUI_FROM_DATABASE=Optical Solutions, Inc. + ID_OUI_FROM_DATABASE=Calix OUI:000632* ID_OUI_FROM_DATABASE=Mesco Engineering GmbH @@ -20783,7 +20954,7 @@ OUI:000A5C* ID_OUI_FROM_DATABASE=Carel s.p.a. OUI:000A5D* - ID_OUI_FROM_DATABASE=PUC Founder (MSC) Berhad + ID_OUI_FROM_DATABASE=FingerTec Worldwide Sdn Bhd OUI:000A5E* ID_OUI_FROM_DATABASE=3COM Corporation @@ -22502,7 +22673,7 @@ OUI:000C9C* ID_OUI_FROM_DATABASE=Chongho information & communications OUI:000C9D* - ID_OUI_FROM_DATABASE=AirWalk Communications, Inc. + ID_OUI_FROM_DATABASE=UbeeAirWalk, Inc. OUI:000C9E* ID_OUI_FROM_DATABASE=MemoryLink Corp. @@ -23687,7 +23858,7 @@ OUI:000E2E* ID_OUI_FROM_DATABASE=Edimax Technology Co., Ltd. OUI:000E2F* - ID_OUI_FROM_DATABASE=Disetronic Medical Systems AG + ID_OUI_FROM_DATABASE=Roche Diagnostics GmbH OUI:000E30* ID_OUI_FROM_DATABASE=AERAS Networks, Inc. @@ -24458,7 +24629,7 @@ OUI:000F31* ID_OUI_FROM_DATABASE=Allied Vision Technologies Canada Inc OUI:000F32* - ID_OUI_FROM_DATABASE=Lootom Optoelectronic Technology (Wuxi) Co Ltd + ID_OUI_FROM_DATABASE=Lootom Telcovideo Network Wuxi Co Ltd OUI:000F33* ID_OUI_FROM_DATABASE=DUALi Inc. @@ -24794,7 +24965,7 @@ OUI:000FA1* ID_OUI_FROM_DATABASE=Gigabit Systems Inc. OUI:000FA2* - ID_OUI_FROM_DATABASE=Digital Path Networks + ID_OUI_FROM_DATABASE=2xWireless OUI:000FA3* ID_OUI_FROM_DATABASE=Alpha Networks Inc. @@ -25817,7 +25988,7 @@ OUI:0010F7* ID_OUI_FROM_DATABASE=IRIICHI TECHNOLOGIES Inc. OUI:0010F8* - ID_OUI_FROM_DATABASE=Niikke Techno System Co. Ltd + ID_OUI_FROM_DATABASE=TEXIO TECHNOLOGY CORPORATION OUI:0010F9* ID_OUI_FROM_DATABASE=UNIQUE SYSTEMS, INC. @@ -26846,7 +27017,7 @@ OUI:00124E* ID_OUI_FROM_DATABASE=XAC AUTOMATION CORP. OUI:00124F* - ID_OUI_FROM_DATABASE=Tyco Thermal Controls LLC. + ID_OUI_FROM_DATABASE=Pentair Thermal Management OUI:001250* ID_OUI_FROM_DATABASE=Tokyo Aircaft Instrument Co., Ltd. @@ -38660,7 +38831,7 @@ OUI:0021B4* ID_OUI_FROM_DATABASE=APRO MEDIA CO., LTD OUI:0021B5* - ID_OUI_FROM_DATABASE=Vyro Games Limited + ID_OUI_FROM_DATABASE=Galvanic Ltd OUI:0021B6* ID_OUI_FROM_DATABASE=Triacta Power Technologies Inc. @@ -47069,7 +47240,7 @@ OUI:009079* ID_OUI_FROM_DATABASE=ClearOne, Inc. OUI:00907A* - ID_OUI_FROM_DATABASE=Polycom, Inc. + ID_OUI_FROM_DATABASE=Spectralink, Inc OUI:00907B* ID_OUI_FROM_DATABASE=E-TECH, INC. @@ -50372,7 +50543,7 @@ OUI:00E06B* ID_OUI_FROM_DATABASE=W&G SPECIAL PRODUCTS OUI:00E06C* - ID_OUI_FROM_DATABASE=AEP Systems International Ltd + ID_OUI_FROM_DATABASE=Ultra Electronics Limited (AEP Networks) OUI:00E06D* ID_OUI_FROM_DATABASE=COMPUWARE CORPORATION @@ -50914,6 +51085,9 @@ OUI:04180F* OUI:0418D6* ID_OUI_FROM_DATABASE=Ubiquiti Networks +OUI:041B94* + ID_OUI_FROM_DATABASE=Host Mobility AB + OUI:041BBA* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd @@ -50947,6 +51121,9 @@ OUI:0432F4* OUI:043604* ID_OUI_FROM_DATABASE=Gyeyoung I&T +OUI:043D98* + ID_OUI_FROM_DATABASE=ChongQing QingJia Electronics CO.,LTD + OUI:044665* ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. @@ -51013,6 +51190,9 @@ OUI:047D7B* OUI:0481AE* ID_OUI_FROM_DATABASE=Clack Corporation +OUI:04848A* + ID_OUI_FROM_DATABASE=7INOVA TECHNOLOGY LIMITED + OUI:04888C* ID_OUI_FROM_DATABASE=Eifelwerk Butler Systeme GmbH @@ -51085,6 +51265,9 @@ OUI:04CE14* OUI:04CF25* ID_OUI_FROM_DATABASE=MANYCOLORS, INC. +OUI:04D437* + ID_OUI_FROM_DATABASE=ZNV + OUI:04D783* ID_OUI_FROM_DATABASE=Y&H E&C Co.,LTD. @@ -51643,6 +51826,9 @@ OUI:082AD0* OUI:082E5F* ID_OUI_FROM_DATABASE=Hewlett Packard +OUI:083571* + ID_OUI_FROM_DATABASE=CASwell INC. + OUI:08373D* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd @@ -51730,9 +51916,15 @@ OUI:08863B* OUI:088DC8* ID_OUI_FROM_DATABASE=Ryowa Electronics Co.,Ltd +OUI:088E4F* + ID_OUI_FROM_DATABASE=SF Software Solutions + OUI:088F2C* ID_OUI_FROM_DATABASE=Hills Sound Vision & Lighting +OUI:0896D7* + ID_OUI_FROM_DATABASE=AVM GmbH + OUI:089E01* ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC. @@ -51763,6 +51955,9 @@ OUI:08B7EC* OUI:08BBCC* ID_OUI_FROM_DATABASE=AK-NORD EDV VERTRIEBSGES. mbH +OUI:08BD43* + ID_OUI_FROM_DATABASE=NETGEAR INC., + OUI:08BE09* ID_OUI_FROM_DATABASE=Astrol Electronic AG @@ -51802,6 +51997,9 @@ OUI:08EBED* OUI:08EDB9* ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. +OUI:08EF3B* + ID_OUI_FROM_DATABASE=MCS Logic Inc. + OUI:08F1B7* ID_OUI_FROM_DATABASE=Towerstream Corpration @@ -51952,6 +52150,9 @@ OUI:0C8D98* OUI:0C924E* ID_OUI_FROM_DATABASE=Rice Lake Weighing Systems +OUI:0C9301* + ID_OUI_FROM_DATABASE=PT. Prasimax Inovasi Teknologi + OUI:0C93FB* ID_OUI_FROM_DATABASE=BNS Solutions @@ -52150,6 +52351,9 @@ OUI:101DC0* OUI:101F74* ID_OUI_FROM_DATABASE=Hewlett-Packard Company +OUI:102279* + ID_OUI_FROM_DATABASE=ZeroDesktop, Inc. + OUI:102831* ID_OUI_FROM_DATABASE=Morion Inc. @@ -52162,6 +52366,9 @@ OUI:102EAF* OUI:103711* ID_OUI_FROM_DATABASE=Simlink AS +OUI:103B59* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:103DEA* ID_OUI_FROM_DATABASE=HFC Technology (Beijing) Ltd. Co. @@ -52214,7 +52421,7 @@ OUI:1064E2* ID_OUI_FROM_DATABASE=ADFweb.com s.r.l. OUI:1065A3* - ID_OUI_FROM_DATABASE=Panamax Inc. + ID_OUI_FROM_DATABASE=Core Brands LLC OUI:1065CF* ID_OUI_FROM_DATABASE=IQSIM @@ -52375,6 +52582,9 @@ OUI:1407E0* OUI:140C76* ID_OUI_FROM_DATABASE=FREEBOX SAS +OUI:140D4F* + ID_OUI_FROM_DATABASE=Flextronics International + OUI:14109F* ID_OUI_FROM_DATABASE=Apple Inc @@ -52585,6 +52795,9 @@ OUI:180C77* OUI:180CAC* ID_OUI_FROM_DATABASE=CANON INC. +OUI:18104E* + ID_OUI_FROM_DATABASE=CEDINT-UPM + OUI:181420* ID_OUI_FROM_DATABASE=TEB SAS @@ -52675,6 +52888,9 @@ OUI:185933* OUI:185AE8* ID_OUI_FROM_DATABASE=Zenotech.Co.,Ltd +OUI:18622C* + ID_OUI_FROM_DATABASE=SAGEMCOM SAS + OUI:1866E3* ID_OUI_FROM_DATABASE=Veros Systems, Inc. @@ -52735,6 +52951,9 @@ OUI:189EFC* OUI:18A905* ID_OUI_FROM_DATABASE=Hewlett-Packard Company +OUI:18A99B* + ID_OUI_FROM_DATABASE=Dell Inc PCBA Test + OUI:18ABF5* ID_OUI_FROM_DATABASE=Ultra Electronics - Electrics @@ -52744,6 +52963,9 @@ OUI:18AD4D* OUI:18AEBB* ID_OUI_FROM_DATABASE=Siemens Convergence Creators GmbH&Co.KG +OUI:18AF8F* + ID_OUI_FROM_DATABASE=Apple + OUI:18AF9F* ID_OUI_FROM_DATABASE=DIGITRONIC Automationsanlagen GmbH @@ -52873,6 +53095,9 @@ OUI:1C3DE7* OUI:1C3E84* ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. +OUI:1C4158* + ID_OUI_FROM_DATABASE=Gemalto M2M GmbH + OUI:1C43EC* ID_OUI_FROM_DATABASE=JAPAN CIRCUIT CO.,LTD @@ -52936,6 +53161,9 @@ OUI:1C7508* OUI:1C76CA* ID_OUI_FROM_DATABASE=Terasic Technologies Inc. +OUI:1C7B21* + ID_OUI_FROM_DATABASE=Sony Mobile Communications AB + OUI:1C7C11* ID_OUI_FROM_DATABASE=EID @@ -52954,6 +53182,9 @@ OUI:1C83B0* OUI:1C8464* ID_OUI_FROM_DATABASE=FORMOSA WIRELESS COMMUNICATION CORP. +OUI:1C86AD* + ID_OUI_FROM_DATABASE=MCT CO., LTD. + OUI:1C8E8E* ID_OUI_FROM_DATABASE=DB Communication & Systems Co., ltd. @@ -52975,12 +53206,21 @@ OUI:1C959F* OUI:1C973D* ID_OUI_FROM_DATABASE=PRICOM Design +OUI:1C994C* + ID_OUI_FROM_DATABASE=Murata Manufactuaring Co.,Ltd. + +OUI:1CA770* + ID_OUI_FROM_DATABASE=SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LT + OUI:1CAA07* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. OUI:1CABA7* ID_OUI_FROM_DATABASE=Apple, Inc. +OUI:1CAF05* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:1CAFF7* ID_OUI_FROM_DATABASE=D-LINK INTERNATIONAL PTE LIMITED @@ -53062,6 +53302,9 @@ OUI:2005E8* OUI:200A5E* ID_OUI_FROM_DATABASE=Xiangshan Giant Eagle Technology Developing co.,LTD +OUI:200BC7* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + OUI:20107A* ID_OUI_FROM_DATABASE=Gemtek Technology Co., Ltd. @@ -53131,6 +53374,9 @@ OUI:204E7F* OUI:205476* ID_OUI_FROM_DATABASE=Sony Mobile Communications AB +OUI:205721* + ID_OUI_FROM_DATABASE=Salix Technology CO., Ltd. + OUI:2059A0* ID_OUI_FROM_DATABASE=Paragon Technologies Inc. @@ -53227,6 +53473,12 @@ OUI:20C8B3* OUI:20C9D0* ID_OUI_FROM_DATABASE=Apple Inc +OUI:20CD39* + ID_OUI_FROM_DATABASE=Texas Instruments, Inc + +OUI:20CEC4* + ID_OUI_FROM_DATABASE=Peraso Technologies + OUI:20CF30* ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. @@ -53428,6 +53680,9 @@ OUI:24BE05* OUI:24C0B3* ID_OUI_FROM_DATABASE=RSF +OUI:24C696* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:24C86E* ID_OUI_FROM_DATABASE=Chaney Instrument Co. @@ -53473,6 +53728,9 @@ OUI:24EB65* OUI:24EC99* ID_OUI_FROM_DATABASE=Askey Computer Corp +OUI:24ECD6* + ID_OUI_FROM_DATABASE=CSG Science & Technology Co.,Ltd.Hefei + OUI:24EE3A* ID_OUI_FROM_DATABASE=Chengdu Yingji Electronic Hi-tech Co Ltd @@ -53482,6 +53740,9 @@ OUI:24F0FF* OUI:24F2DD* ID_OUI_FROM_DATABASE=Radiant Zemax LLC +OUI:24F5AA* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,LTD + OUI:24FD52* ID_OUI_FROM_DATABASE=Liteon Technology Corporation @@ -53521,6 +53782,9 @@ OUI:2818FD* OUI:2826A6* ID_OUI_FROM_DATABASE=PBR electronics GmbH +OUI:28285D* + ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation + OUI:2829D9* ID_OUI_FROM_DATABASE=GlobalBeiMing technology (Beijing)Co. Ltd @@ -53578,6 +53842,9 @@ OUI:286AB8* OUI:286ABA* ID_OUI_FROM_DATABASE=Apple, Inc. +OUI:286D97* + ID_OUI_FROM_DATABASE=SAMJIN Co., Ltd. + OUI:286ED4* ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD @@ -53626,6 +53893,12 @@ OUI:28A186* OUI:28A192* ID_OUI_FROM_DATABASE=GERP Solution +OUI:28A1EB* + ID_OUI_FROM_DATABASE=ETEK TECHNOLOGY (SHENZHEN) CO.,LTD + +OUI:28A241* + ID_OUI_FROM_DATABASE=exlar corp + OUI:28A574* ID_OUI_FROM_DATABASE=Miller Electric Mfg. Co. @@ -53644,12 +53917,18 @@ OUI:28B3AB* OUI:28BA18* ID_OUI_FROM_DATABASE=NextNav, LLC +OUI:28BAB5* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:28BE9B* ID_OUI_FROM_DATABASE=Technicolor USA Inc. OUI:28C0DA* ID_OUI_FROM_DATABASE=Juniper Networks +OUI:28C671* + ID_OUI_FROM_DATABASE=Yota Devices OY + OUI:28C68E* ID_OUI_FROM_DATABASE=NETGEAR INC., @@ -53692,6 +53971,9 @@ OUI:28D244* OUI:28D576* ID_OUI_FROM_DATABASE=Premier Wireless, Inc. +OUI:28D93E* + ID_OUI_FROM_DATABASE=Telecor Inc. + OUI:28D997* ID_OUI_FROM_DATABASE=Yuduan Mobile Co., Ltd. @@ -53848,6 +54130,9 @@ OUI:2C768A* OUI:2C7B5A* ID_OUI_FROM_DATABASE=Milper Ltd +OUI:2C7B84* + ID_OUI_FROM_DATABASE=OOO Petr Telegin + OUI:2C7ECF* ID_OUI_FROM_DATABASE=Onzo Ltd @@ -53911,12 +54196,18 @@ OUI:2CBE97* OUI:2CC260* ID_OUI_FROM_DATABASE=Ravello Systems +OUI:2CCC15* + ID_OUI_FROM_DATABASE=Nokia Corporation + OUI:2CCD27* ID_OUI_FROM_DATABASE=Precor Inc OUI:2CCD43* ID_OUI_FROM_DATABASE=Summit Technology Group +OUI:2CCD69* + ID_OUI_FROM_DATABASE=Aqavi.com + OUI:2CD05A* ID_OUI_FROM_DATABASE=Liteon Technology Corporation @@ -53938,6 +54229,9 @@ OUI:2CE2A8* OUI:2CE412* ID_OUI_FROM_DATABASE=SAGEMCOM SAS +OUI:2CE6CC* + ID_OUI_FROM_DATABASE=Ruckus Wireless + OUI:2CE871* ID_OUI_FROM_DATABASE=Alert Metalguard ApS @@ -54010,6 +54304,9 @@ OUI:303955* OUI:3039F2* ID_OUI_FROM_DATABASE=ADB Broadband Italia +OUI:303A64* + ID_OUI_FROM_DATABASE=Intel Corporate + OUI:303D08* ID_OUI_FROM_DATABASE=GLINTT TES S.A. @@ -54046,6 +54343,12 @@ OUI:3057AC* OUI:305D38* ID_OUI_FROM_DATABASE=Beissbarth +OUI:306023* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +OUI:306112* + ID_OUI_FROM_DATABASE=PAV GmbH + OUI:306118* ID_OUI_FROM_DATABASE=Paradom Inc. @@ -54067,6 +54370,9 @@ OUI:306E5C* OUI:3071B2* ID_OUI_FROM_DATABASE=Hangzhou Prevail Optoelectronic Equipment Co.,LTD. +OUI:30766F* + ID_OUI_FROM_DATABASE=LG Electronics + OUI:30786B* ID_OUI_FROM_DATABASE=TIANJIN Golden Pentagon Electronics Co., Ltd. @@ -54163,6 +54469,9 @@ OUI:3407FB* OUI:340804* ID_OUI_FROM_DATABASE=D-Link Corporation +OUI:3413E8* + ID_OUI_FROM_DATABASE=Intel Corporate + OUI:34159E* ID_OUI_FROM_DATABASE=Apple, Inc @@ -54283,6 +54592,9 @@ OUI:34A843* OUI:34A84E* ID_OUI_FROM_DATABASE=Cisco +OUI:34AA8B* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:34AA99* ID_OUI_FROM_DATABASE=Alcatel-Lucent @@ -54466,9 +54778,15 @@ OUI:38521A* OUI:38580C* ID_OUI_FROM_DATABASE=Panaccess Systems GmbH +OUI:3859F8* + ID_OUI_FROM_DATABASE=MindMade sp. z o.o. + OUI:3859F9* ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. +OUI:385AA8* + ID_OUI_FROM_DATABASE=Beijing Zhongdun Security Technology Development Co. + OUI:385FC3* ID_OUI_FROM_DATABASE=Yu Jeong System, Co.Ltd @@ -54574,6 +54892,9 @@ OUI:38E98C* OUI:38EAA7* ID_OUI_FROM_DATABASE=Hewlett Packard +OUI:38EC11* + ID_OUI_FROM_DATABASE=Novatek Microelectronics Corp. + OUI:38ECE4* ID_OUI_FROM_DATABASE=Samsung Electronics @@ -54622,6 +54943,9 @@ OUI:3C1915* OUI:3C197D* ID_OUI_FROM_DATABASE=Ericsson AB +OUI:3C1A57* + ID_OUI_FROM_DATABASE=Cardiopulmonary Corp + OUI:3C1A79* ID_OUI_FROM_DATABASE=Huayuan Technology CO.,LTD @@ -54652,6 +54976,9 @@ OUI:3C39C3* OUI:3C3A73* ID_OUI_FROM_DATABASE=Avaya, Inc +OUI:3C404F* + ID_OUI_FROM_DATABASE=Guangdong Pisen Electronics Co. Ltd. + OUI:3C438E* ID_OUI_FROM_DATABASE=Motorola Mobility, LLC. @@ -54676,6 +55003,9 @@ OUI:3C5A37* OUI:3C5F01* ID_OUI_FROM_DATABASE=Synerchip Co., Ltd. +OUI:3C6104* + ID_OUI_FROM_DATABASE=Juniper Networks + OUI:3C6200* ID_OUI_FROM_DATABASE=Samsung electronics CO., LTD @@ -55129,6 +55459,9 @@ OUI:4425BB* OUI:442A60* ID_OUI_FROM_DATABASE=Apple, Inc. +OUI:442AFF* + ID_OUI_FROM_DATABASE=E3 Technology, Inc. + OUI:442B03* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. @@ -55207,6 +55540,9 @@ OUI:446132* OUI:44619C* ID_OUI_FROM_DATABASE=FONsystem co. ltd. +OUI:446755* + ID_OUI_FROM_DATABASE=Orbit Irrigation + OUI:4468AB* ID_OUI_FROM_DATABASE=JUIN COMPANY, LIMITED @@ -55216,6 +55552,9 @@ OUI:446C24* OUI:446D57* ID_OUI_FROM_DATABASE=Liteon Technology Corporation +OUI:44700B* + ID_OUI_FROM_DATABASE=IFFU + OUI:447C7F* ID_OUI_FROM_DATABASE=Innolight Technology Corporation @@ -55402,6 +55741,9 @@ OUI:4861A3* OUI:486B91* ID_OUI_FROM_DATABASE=Fleetwood Group Inc. +OUI:486E73* + ID_OUI_FROM_DATABASE=Pica8, Inc. + OUI:486FD2* ID_OUI_FROM_DATABASE=StorSimple Inc @@ -55456,6 +55798,9 @@ OUI:48C8B6* OUI:48CB6E* ID_OUI_FROM_DATABASE=Cello Electronics (UK) Ltd +OUI:48D224* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + OUI:48D54C* ID_OUI_FROM_DATABASE=Jeda Networks @@ -55534,6 +55879,9 @@ OUI:4C0FC7* OUI:4C1480* ID_OUI_FROM_DATABASE=NOREGON SYSTEMS, INC +OUI:4C14A3* + ID_OUI_FROM_DATABASE=TCL Technoly Electronics (Huizhou) Co., Ltd. + OUI:4C17EB* ID_OUI_FROM_DATABASE=SAGEMCOM @@ -55546,6 +55894,9 @@ OUI:4C1A95* OUI:4C1FCC* ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD +OUI:4C21D0* + ID_OUI_FROM_DATABASE=Sony Mobile Communications AB + OUI:4C2258* ID_OUI_FROM_DATABASE=cozybit, Inc. @@ -55708,12 +56059,18 @@ OUI:4CC94F* OUI:4CCA53* ID_OUI_FROM_DATABASE=Skyera, Inc. +OUI:4CCBF5* + ID_OUI_FROM_DATABASE=zte corporation + OUI:4CCC34* ID_OUI_FROM_DATABASE=Motorola Solutions Inc. OUI:4CD637* ID_OUI_FROM_DATABASE=Qsono Electronics Co., Ltd +OUI:4CDF3D* + ID_OUI_FROM_DATABASE=TEAM ENGINEERS ADVANCE TECHNOLOGIES INDIA PVT LTD + OUI:4CE676* ID_OUI_FROM_DATABASE=Buffalo Inc. @@ -55780,6 +56137,9 @@ OUI:503275* OUI:503955* ID_OUI_FROM_DATABASE=Cisco SPVTG +OUI:503CC4* + ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd. + OUI:503DE5* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. @@ -55831,6 +56191,9 @@ OUI:5070E5* OUI:50724D* ID_OUI_FROM_DATABASE=BEG Brueck Electronic GmbH +OUI:507691* + ID_OUI_FROM_DATABASE=Tekpea, Inc. + OUI:5076A6* ID_OUI_FROM_DATABASE=Ecil Informatica Ind. Com. Ltda @@ -55954,6 +56317,9 @@ OUI:540496* OUI:5404A6* ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. +OUI:540536* + ID_OUI_FROM_DATABASE=Vivago Oy + OUI:54055F* ID_OUI_FROM_DATABASE=Alcatel Lucent @@ -55963,6 +56329,9 @@ OUI:54112F* OUI:54115F* ID_OUI_FROM_DATABASE=Atamo Pty Ltd +OUI:541B5D* + ID_OUI_FROM_DATABASE=Techno-Innov + OUI:541DFB* ID_OUI_FROM_DATABASE=Freestyle Energy Ltd @@ -55975,6 +56344,9 @@ OUI:542018* OUI:542160* ID_OUI_FROM_DATABASE=Resolution Products +OUI:5422F8* + ID_OUI_FROM_DATABASE=zte corporation + OUI:542696* ID_OUI_FROM_DATABASE=Apple @@ -55999,6 +56371,9 @@ OUI:543D37* OUI:544249* ID_OUI_FROM_DATABASE=Sony Corporation +OUI:544408* + ID_OUI_FROM_DATABASE=Nokia Corporation + OUI:54466B* ID_OUI_FROM_DATABASE=Shenzhen CZTIC Electronic Technology Co., Ltd @@ -56077,6 +56452,9 @@ OUI:54A04F* OUI:54A51B* ID_OUI_FROM_DATABASE=Shenzhen Huawei Communication Technologies Co., Ltd +OUI:54A54B* + ID_OUI_FROM_DATABASE=NSC Communiaction Siberia Ltd + OUI:54A619* ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd @@ -56104,6 +56482,9 @@ OUI:54DF63* OUI:54E032* ID_OUI_FROM_DATABASE=Juniper Networks +OUI:54E3B0* + ID_OUI_FROM_DATABASE=JVL Industri Elektronik + OUI:54E63F* ID_OUI_FROM_DATABASE=ShenZhen LingKeWeiEr Technology Co., Ltd. @@ -56116,6 +56497,9 @@ OUI:54F5B6* OUI:54F666* ID_OUI_FROM_DATABASE=Berthold Technologies GmbH and Co.KG +OUI:54FB58* + ID_OUI_FROM_DATABASE=WISEWARE, Lda + OUI:54FDBF* ID_OUI_FROM_DATABASE=Scheidt & Bachmann GmbH @@ -56167,6 +56551,9 @@ OUI:583CC6* OUI:5842E4* ID_OUI_FROM_DATABASE=Sigma International General Medical Apparatus, LLC. +OUI:58468F* + ID_OUI_FROM_DATABASE=Koncar Electronics and Informatics + OUI:5846E1* ID_OUI_FROM_DATABASE=Baxter Healthcare @@ -56350,6 +56737,9 @@ OUI:58F98E* OUI:58FD20* ID_OUI_FROM_DATABASE=Bravida Sakerhet AB +OUI:5C026A* + ID_OUI_FROM_DATABASE=Applied Vision Corporation + OUI:5C076F* ID_OUI_FROM_DATABASE=Thought Creator @@ -56392,6 +56782,9 @@ OUI:5C2479* OUI:5C260A* ID_OUI_FROM_DATABASE=Dell Inc. +OUI:5C3327* + ID_OUI_FROM_DATABASE=Spazio Italia srl + OUI:5C335C* ID_OUI_FROM_DATABASE=Swissphone Telecom AG @@ -56659,6 +57052,9 @@ OUI:6052D0* OUI:605464* ID_OUI_FROM_DATABASE=Eyedro Green Solutions Inc. +OUI:605718* + ID_OUI_FROM_DATABASE=Intel Corporate + OUI:60601F* ID_OUI_FROM_DATABASE=SZ DJI TECHNOLOGY CO.,LTD @@ -56833,12 +57229,21 @@ OUI:60FE1E* OUI:60FEC5* ID_OUI_FROM_DATABASE=Apple +OUI:60FEF9* + ID_OUI_FROM_DATABASE=Thomas & Betts + OUI:6400F1* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. +OUI:6405BE* + ID_OUI_FROM_DATABASE=NEW LIGHT LED + OUI:64094C* ID_OUI_FROM_DATABASE=Beijing Superbee Wireless Technology Co.,Ltd +OUI:640B4A* + ID_OUI_FROM_DATABASE=Digital Telecom Technology Limited + OUI:640E36* ID_OUI_FROM_DATABASE=TAZTAG @@ -56869,6 +57274,9 @@ OUI:641E81* OUI:64200C* ID_OUI_FROM_DATABASE=Apple, Inc. +OUI:642184* + ID_OUI_FROM_DATABASE=Nippon Denki Kagaku Co.,LTD + OUI:642216* ID_OUI_FROM_DATABASE=Shandong Taixin Electronic co.,Ltd @@ -56909,7 +57317,7 @@ OUI:64517E* ID_OUI_FROM_DATABASE=LONG BEN (DONGGUAN) ELECTRONIC TECHNOLOGY CO.,LTD. OUI:645299* - ID_OUI_FROM_DATABASE=Chamberlain + ID_OUI_FROM_DATABASE=The Chamberlain Group, Inc OUI:64535D* ID_OUI_FROM_DATABASE=Frauscher Sensortechnik @@ -56956,6 +57364,9 @@ OUI:6469BC* OUI:646E6C* ID_OUI_FROM_DATABASE=Radio Datacom LLC +OUI:646EEA* + ID_OUI_FROM_DATABASE=Iskratel d.o.o. + OUI:647002* ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD. @@ -57082,6 +57493,9 @@ OUI:64D1A3* OUI:64D241* ID_OUI_FROM_DATABASE=Keith & Koep GmbH +OUI:64D4BD* + ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. + OUI:64D4DA* ID_OUI_FROM_DATABASE=Intel Corporate @@ -57166,6 +57580,9 @@ OUI:681AB2* OUI:681CA2* ID_OUI_FROM_DATABASE=Rosewill Inc. +OUI:681D64* + ID_OUI_FROM_DATABASE=Sunwave Communications Co., Ltd + OUI:681E8B* ID_OUI_FROM_DATABASE=InfoSight Corporation @@ -57490,6 +57907,9 @@ OUI:6C8CDB* OUI:6C8D65* ID_OUI_FROM_DATABASE=Wireless Glue Networks, Inc. +OUI:6C90B1* + ID_OUI_FROM_DATABASE=SanLogic Inc + OUI:6C92BF* ID_OUI_FROM_DATABASE=Inspur Electronic Information Industry Co.,Ltd. @@ -57529,12 +57949,18 @@ OUI:6CAD3F* OUI:6CADEF* ID_OUI_FROM_DATABASE=KZ Broadband Technologies, Ltd. +OUI:6CADF8* + ID_OUI_FROM_DATABASE=Azurewave Technologies, Inc. + OUI:6CAE8B* ID_OUI_FROM_DATABASE=IBM Corporation OUI:6CB311* ID_OUI_FROM_DATABASE=Shenzhen Lianrui Electronics Co.,Ltd +OUI:6CB350* + ID_OUI_FROM_DATABASE=Anhui comhigher tech co.,ltd + OUI:6CB7F4* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd @@ -57553,6 +57979,9 @@ OUI:6CD032* OUI:6CD146* ID_OUI_FROM_DATABASE=Smartek d.o.o. +OUI:6CD1B0* + ID_OUI_FROM_DATABASE=WING SING ELECTRONICS HONG KONG LIMITED + OUI:6CD68A* ID_OUI_FROM_DATABASE=LG Electronics Inc @@ -57586,6 +58015,9 @@ OUI:6CF373* OUI:6CF37F* ID_OUI_FROM_DATABASE=Aruba Networks +OUI:6CF97C* + ID_OUI_FROM_DATABASE=Nanoptix Inc. + OUI:6CFA58* ID_OUI_FROM_DATABASE=Avaya, Inc @@ -57676,6 +58108,9 @@ OUI:704AAE* OUI:704AE4* ID_OUI_FROM_DATABASE=Rinstrum Pty Ltd +OUI:704CED* + ID_OUI_FROM_DATABASE=TMRG, Inc. + OUI:7052C5* ID_OUI_FROM_DATABASE=Avaya, Inc. @@ -57721,6 +58156,9 @@ OUI:7072CF* OUI:7073CB* ID_OUI_FROM_DATABASE=Apple, Inc. +OUI:707630* + ID_OUI_FROM_DATABASE=Pace plc. + OUI:7076DD* ID_OUI_FROM_DATABASE=Oxyguard International A/S @@ -57760,6 +58198,12 @@ OUI:709A0B* OUI:709BA5* ID_OUI_FROM_DATABASE=Shenzhen Y&D Electronics Co.,LTD. +OUI:709BFC* + ID_OUI_FROM_DATABASE=Bryton Inc. + +OUI:709E29* + ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc. + OUI:709E86* ID_OUI_FROM_DATABASE=X6D Limited @@ -57772,6 +58216,9 @@ OUI:70A41C* OUI:70A66A* ID_OUI_FROM_DATABASE=Prox Dynamics AS +OUI:70A8E3* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + OUI:70AAB2* ID_OUI_FROM_DATABASE=Research In Motion @@ -57832,12 +58279,18 @@ OUI:70E139* OUI:70E24C* ID_OUI_FROM_DATABASE=SAE IT-systems GmbH & Co. KG +OUI:70E284* + ID_OUI_FROM_DATABASE=Wistron InfoComm(Zhongshan) Corporation + OUI:70E843* ID_OUI_FROM_DATABASE=Beijing C&W Optical Communication Technology Co.,Ltd. OUI:70EE50* ID_OUI_FROM_DATABASE=Netatmo +OUI:70F176* + ID_OUI_FROM_DATABASE=Data Modul AG + OUI:70F1A1* ID_OUI_FROM_DATABASE=Liteon Technology Corporation @@ -57931,6 +58384,9 @@ OUI:7463DF* OUI:7465D1* ID_OUI_FROM_DATABASE=Atlinks +OUI:746630* + ID_OUI_FROM_DATABASE=T:mi Ytti + OUI:746A89* ID_OUI_FROM_DATABASE=Rezolt Corporation @@ -58246,6 +58702,9 @@ OUI:78998F* OUI:789ED0* ID_OUI_FROM_DATABASE=Samsung Electronics +OUI:789F4C* + ID_OUI_FROM_DATABASE=HOERBIGER Elektronik GmbH + OUI:789F87* ID_OUI_FROM_DATABASE=Siemens AG I IA PP PRM @@ -58321,6 +58780,9 @@ OUI:78CA04* OUI:78CA39* ID_OUI_FROM_DATABASE=Apple, Inc. +OUI:78CB33* + ID_OUI_FROM_DATABASE=DHC Software Co.,Ltd + OUI:78CD8E* ID_OUI_FROM_DATABASE=SMC Networks Inc @@ -58363,6 +58825,9 @@ OUI:78E400* OUI:78E7D1* ID_OUI_FROM_DATABASE=Hewlett-Packard Company +OUI:78E8B6* + ID_OUI_FROM_DATABASE=zte corporation + OUI:78EC22* ID_OUI_FROM_DATABASE=Shanghai Qihui Telecom Technology Co., LTD @@ -58384,6 +58849,9 @@ OUI:78F7D0* OUI:78FE3D* ID_OUI_FROM_DATABASE=Juniper Networks +OUI:78FE41* + ID_OUI_FROM_DATABASE=Socus networks + OUI:78FF57* ID_OUI_FROM_DATABASE=Intel Corporate @@ -58423,6 +58891,9 @@ OUI:7C1476* OUI:7C160D* ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG +OUI:7C1AFC* + ID_OUI_FROM_DATABASE=Dalian Co-Edifice Video Technology Co., Ltd + OUI:7C1E52* ID_OUI_FROM_DATABASE=Microsoft @@ -58486,6 +58957,9 @@ OUI:7C6097* OUI:7C6193* ID_OUI_FROM_DATABASE=HTC Corporation +OUI:7C69F6* + ID_OUI_FROM_DATABASE=Cisco + OUI:7C6ADB* ID_OUI_FROM_DATABASE=SafeTone Technology Co.,Ltd @@ -58507,6 +58981,9 @@ OUI:7C6D62* OUI:7C6F06* ID_OUI_FROM_DATABASE=Caterpillar Trimble Control Technologies +OUI:7C6FF8* + ID_OUI_FROM_DATABASE=ShenZhen ACTO Digital Video Technology Co.,Ltd. + OUI:7C7673* ID_OUI_FROM_DATABASE=ENMAS GmbH @@ -58522,12 +58999,18 @@ OUI:7C7D41* OUI:7C822D* ID_OUI_FROM_DATABASE=Nortec +OUI:7C8306* + ID_OUI_FROM_DATABASE=Glen Dimplex Nordic as + OUI:7C8EE4* ID_OUI_FROM_DATABASE=Texas Instruments OUI:7C94B2* ID_OUI_FROM_DATABASE=Philips Healthcare PCCI +OUI:7C95F3* + ID_OUI_FROM_DATABASE=Cisco + OUI:7C9A9B* ID_OUI_FROM_DATABASE=VSE valencia smart energy @@ -58558,6 +59041,9 @@ OUI:7CB232* OUI:7CB542* ID_OUI_FROM_DATABASE=ACES Technology +OUI:7CB77B* + ID_OUI_FROM_DATABASE=Paradigm Electronics Inc + OUI:7CBB6F* ID_OUI_FROM_DATABASE=Cosco Electronics Co., Ltd. @@ -58612,6 +59098,9 @@ OUI:7CDD90* OUI:7CE044* ID_OUI_FROM_DATABASE=NEON Inc +OUI:7CE56B* + ID_OUI_FROM_DATABASE=ESEN Optoelectronics Technology Co.,Ltd. + OUI:7CE9D3* ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. @@ -58651,6 +59140,9 @@ OUI:80000B* OUI:800010* ID_OUI_FROM_DATABASE=ATT BELL LABORATORIES +OUI:8005DF* + ID_OUI_FROM_DATABASE=Montage Technology Group Limited + OUI:8007A2* ID_OUI_FROM_DATABASE=Esson Technology Inc. @@ -58906,6 +59398,9 @@ OUI:842141* OUI:84248D* ID_OUI_FROM_DATABASE=Motorola Solutions Inc +OUI:84253F* + ID_OUI_FROM_DATABASE=Silex Technology, Inc + OUI:8425DB* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd @@ -58963,6 +59458,9 @@ OUI:845181* OUI:845787* ID_OUI_FROM_DATABASE=DVR C&C Co., Ltd. +OUI:845C93* + ID_OUI_FROM_DATABASE=Chabrier Services + OUI:845DD7* ID_OUI_FROM_DATABASE=Shenzhen Netcom Electronics Co.,Ltd @@ -59101,6 +59599,9 @@ OUI:880905* OUI:881036* ID_OUI_FROM_DATABASE=Panodic(ShenZhen) Electronics Limted +OUI:88124E* + ID_OUI_FROM_DATABASE=Qualcomm Atheros + OUI:88142B* ID_OUI_FROM_DATABASE=Protonic Holland @@ -59140,6 +59641,12 @@ OUI:88329B* OUI:883314* ID_OUI_FROM_DATABASE=Texas Instruments +OUI:88354C* + ID_OUI_FROM_DATABASE=Transics + +OUI:883612* + ID_OUI_FROM_DATABASE=SRC Computers, LLC + OUI:8841C1* ID_OUI_FROM_DATABASE=ORBISAT DA AMAZONIA IND E AEROL SA @@ -59296,6 +59803,9 @@ OUI:88F490* OUI:88FD15* ID_OUI_FROM_DATABASE=LINEEYE CO., LTD +OUI:8C006D* + ID_OUI_FROM_DATABASE=Apple + OUI:8C04FF* ID_OUI_FROM_DATABASE=Technicolor USA Inc. @@ -59329,6 +59839,9 @@ OUI:8C278A* OUI:8C2DAA* ID_OUI_FROM_DATABASE=Apple Inc +OUI:8C2F39* + ID_OUI_FROM_DATABASE=IBA Dosimetry GmbH + OUI:8C3330* ID_OUI_FROM_DATABASE=EmFirst Co., Ltd. @@ -59344,6 +59857,9 @@ OUI:8C4435* OUI:8C4AEE* ID_OUI_FROM_DATABASE=GIGA TMS INC +OUI:8C4B59* + ID_OUI_FROM_DATABASE=3D Imaging & Simulations Corp + OUI:8C4CDC* ID_OUI_FROM_DATABASE=PLANEX COMMUNICATIONS INC. @@ -59602,12 +60118,18 @@ OUI:903D5A* OUI:903D6B* ID_OUI_FROM_DATABASE=Zicon Technology Corp. +OUI:903EAB* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + OUI:9046B7* ID_OUI_FROM_DATABASE=Vadaro Pte Ltd OUI:904716* ID_OUI_FROM_DATABASE=RORZE CORPORATION +OUI:9049FA* + ID_OUI_FROM_DATABASE=Intel Corporation + OUI:904CE5* ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. @@ -59656,6 +60178,15 @@ OUI:906EBB* OUI:907025* ID_OUI_FROM_DATABASE=Garea Microsys Co.,Ltd. +OUI:907240* + ID_OUI_FROM_DATABASE=Apple + +OUI:907A0A* + ID_OUI_FROM_DATABASE=Gebr. Bode GmbH & Co KG + +OUI:907A28* + ID_OUI_FROM_DATABASE=Beijing Morncloud Information And Technology Co. Ltd. + OUI:907AF1* ID_OUI_FROM_DATABASE=SNUPI Technologies @@ -59713,6 +60244,9 @@ OUI:90B11C* OUI:90B134* ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. +OUI:90B21F* + ID_OUI_FROM_DATABASE=Apple + OUI:90B8D0* ID_OUI_FROM_DATABASE=Joyent, Inc. @@ -59827,6 +60361,9 @@ OUI:94319B* OUI:9433DD* ID_OUI_FROM_DATABASE=Taco Electronic Solutions, Inc. +OUI:94350A* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:9436E0* ID_OUI_FROM_DATABASE=Sichuan Bihong Broadcast & Television New Technologies Co.,Ltd @@ -59875,6 +60412,9 @@ OUI:9471AC* OUI:94756E* ID_OUI_FROM_DATABASE=QinetiQ North America +OUI:947C3E* + ID_OUI_FROM_DATABASE=Polewall Norge AS + OUI:9481A4* ID_OUI_FROM_DATABASE=Azuray Technologies @@ -59926,6 +60466,9 @@ OUI:94B8C5* OUI:94BA31* ID_OUI_FROM_DATABASE=Visiontec da Amazônia Ltda. +OUI:94BF1E* + ID_OUI_FROM_DATABASE=eflow Inc. / Smart Device Planning and Development Division + OUI:94C4E9* ID_OUI_FROM_DATABASE=PowerLayer Microsystems HongKong Limited @@ -60109,6 +60652,9 @@ OUI:985945* OUI:985C93* ID_OUI_FROM_DATABASE=SBG Systems SAS +OUI:985D46* + ID_OUI_FROM_DATABASE=PeopleNet Communication + OUI:985E1B* ID_OUI_FROM_DATABASE=ConversDigital Co., Ltd. @@ -60124,6 +60670,9 @@ OUI:986DC8* OUI:9873C4* ID_OUI_FROM_DATABASE=Sage Electronic Engineering LLC +OUI:9876B6* + ID_OUI_FROM_DATABASE=Adafruit + OUI:988217* ID_OUI_FROM_DATABASE=Disruptive Ltd @@ -60142,6 +60691,9 @@ OUI:988BAD* OUI:988E34* ID_OUI_FROM_DATABASE=ZHEJIANG BOXSAM ELECTRONIC CO.,LTD +OUI:988E4A* + ID_OUI_FROM_DATABASE=NOXUS(BEIJING) TECHNOLOGY CO.,LTD + OUI:988EDD* ID_OUI_FROM_DATABASE=TE Connectivity Limerick @@ -60175,6 +60727,12 @@ OUI:98BC99* OUI:98C845* ID_OUI_FROM_DATABASE=PacketAccess +OUI:98CDB4* + ID_OUI_FROM_DATABASE=Virident Systems, Inc. + +OUI:98D331* + ID_OUI_FROM_DATABASE=Shenzhen Bolutek Technology Co.,Ltd. + OUI:98D686* ID_OUI_FROM_DATABASE=Chyi Lee industry Co., ltd. @@ -60202,6 +60760,9 @@ OUI:98EC65* OUI:98F537* ID_OUI_FROM_DATABASE=zte corporation +OUI:98F8C1* + ID_OUI_FROM_DATABASE=IDT Technology Limited + OUI:98F8DB* ID_OUI_FROM_DATABASE=Marini Impianti Industriali s.r.l. @@ -60250,6 +60811,9 @@ OUI:9C207B* OUI:9C220E* ID_OUI_FROM_DATABASE=TASCAN Service GmbH +OUI:9C2840* + ID_OUI_FROM_DATABASE=Discovery Technology,LTD.. + OUI:9C28BF* ID_OUI_FROM_DATABASE=Continental Automotive Czech Republic s.r.o. @@ -60472,6 +61036,9 @@ OUI:A00BBA* OUI:A00CA1* ID_OUI_FROM_DATABASE=SKTB SKiT +OUI:A01290* + ID_OUI_FROM_DATABASE=Avaya, Inc + OUI:A0133B* ID_OUI_FROM_DATABASE=Copyright © HiTi Digital, Inc. @@ -60523,6 +61090,9 @@ OUI:A041A7* OUI:A0423F* ID_OUI_FROM_DATABASE=Tyan Computer Corp +OUI:A0481C* + ID_OUI_FROM_DATABASE=Hewlett Packard + OUI:A04CC1* ID_OUI_FROM_DATABASE=Helixtech Corp. @@ -60553,6 +61123,9 @@ OUI:A05DE7* OUI:A05E6B* ID_OUI_FROM_DATABASE=MELPER Co., Ltd. +OUI:A067BE* + ID_OUI_FROM_DATABASE=Sicon s.r.l. + OUI:A06986* ID_OUI_FROM_DATABASE=Wellav Technologies Ltd @@ -60631,6 +61204,9 @@ OUI:A0A130* OUI:A0A763* ID_OUI_FROM_DATABASE=Polytron Vertrieb GmbH +OUI:A0A8CD* + ID_OUI_FROM_DATABASE=Intel Corporate + OUI:A0AAFD* ID_OUI_FROM_DATABASE=EraThink Technologies Corp. @@ -60658,6 +61234,12 @@ OUI:A0BFA5* OUI:A0C3DE* ID_OUI_FROM_DATABASE=Triton Electronic Systems Ltd. +OUI:A0C6EC* + ID_OUI_FROM_DATABASE=ShenZhen ANYK Technology Co.,LTD + +OUI:A0CEC8* + ID_OUI_FROM_DATABASE=CE LINK LIMITED + OUI:A0CF5B* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. @@ -60748,9 +61330,15 @@ OUI:A41F72* OUI:A4218A* ID_OUI_FROM_DATABASE=Nortel Networks +OUI:A42305* + ID_OUI_FROM_DATABASE=Open Networking Laboratory + OUI:A424B3* ID_OUI_FROM_DATABASE=FlatFrog Laboratories AB +OUI:A42940* + ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd + OUI:A429B7* ID_OUI_FROM_DATABASE=bluesky @@ -60826,6 +61414,9 @@ OUI:A47C1F* OUI:A4856B* ID_OUI_FROM_DATABASE=Q Electronics Ltd +OUI:A4895B* + ID_OUI_FROM_DATABASE=ARK INFOSOLUTIONS PVT LTD + OUI:A49005* ID_OUI_FROM_DATABASE=CHINA GREATWALL COMPUTER SHENZHEN CO.,LTD @@ -60892,12 +61483,18 @@ OUI:A4BADB* OUI:A4BE61* ID_OUI_FROM_DATABASE=EutroVision System, Inc. +OUI:A4C0C7* + ID_OUI_FROM_DATABASE=ShenZhen Hitom Communication Technology Co..LTD + OUI:A4C0E1* ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. OUI:A4C2AB* ID_OUI_FROM_DATABASE=Hangzhou LEAD-IT Information & Technology Co.,Ltd +OUI:A4C361* + ID_OUI_FROM_DATABASE=Apple + OUI:A4D094* ID_OUI_FROM_DATABASE=Erwin Peters Systemtechnik GmbH @@ -60958,6 +61555,9 @@ OUI:A4EF52* OUI:A4F3C1* ID_OUI_FROM_DATABASE=Open Source Robotics Foundation, Inc. +OUI:A4F522* + ID_OUI_FROM_DATABASE=CHOFU SEISAKUSHO CO.,LTD + OUI:A4F7D0* ID_OUI_FROM_DATABASE=LAN Accessories Co., Ltd. @@ -61069,6 +61669,9 @@ OUI:A88792* OUI:A887ED* ID_OUI_FROM_DATABASE=ARC Wireless LLC +OUI:A88808* + ID_OUI_FROM_DATABASE=Apple + OUI:A88CEE* ID_OUI_FROM_DATABASE=MicroMade Galka i Drozdz sp.j. @@ -61105,6 +61708,9 @@ OUI:A8B0AE* OUI:A8B1D4* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. +OUI:A8BBCF* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:A8BD1A* ID_OUI_FROM_DATABASE=Honey Bee (Hong Kong) Limited @@ -61114,6 +61720,9 @@ OUI:A8C222* OUI:A8CB95* ID_OUI_FROM_DATABASE=EAST BEST CO., LTD. +OUI:A8CCC5* + ID_OUI_FROM_DATABASE=Saab AB (publ) + OUI:A8CE90* ID_OUI_FROM_DATABASE=CVC @@ -61207,6 +61816,9 @@ OUI:AC199F* OUI:AC20AA* ID_OUI_FROM_DATABASE=DMATEK Co., Ltd. +OUI:AC220B* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + OUI:AC2FA8* ID_OUI_FROM_DATABASE=Humannix Co.,Ltd. @@ -61303,6 +61915,9 @@ OUI:AC7A42* OUI:AC7BA1* ID_OUI_FROM_DATABASE=Intel Corporate +OUI:AC7F3E* + ID_OUI_FROM_DATABASE=Apple + OUI:AC80D6* ID_OUI_FROM_DATABASE=Hexatronic AB @@ -61381,6 +61996,9 @@ OUI:ACC935* OUI:ACCA54* ID_OUI_FROM_DATABASE=Telldus Technologies AB +OUI:ACCA8E* + ID_OUI_FROM_DATABASE=ODA Technologies + OUI:ACCABA* ID_OUI_FROM_DATABASE=Midokura Co., Ltd. @@ -61402,6 +62020,9 @@ OUI:ACD180* OUI:ACD364* ID_OUI_FROM_DATABASE=ABB SPA, ABB SACE DIV. +OUI:ACD657* + ID_OUI_FROM_DATABASE=Shaanxi Guolian Digital TV Technology Co., Ltd. + OUI:ACD9D6* ID_OUI_FROM_DATABASE=tci GmbH @@ -61414,6 +62035,9 @@ OUI:ACE215* OUI:ACE348* ID_OUI_FROM_DATABASE=MadgeTech, Inc +OUI:ACE42E* + ID_OUI_FROM_DATABASE=SK hynix + OUI:ACE64B* ID_OUI_FROM_DATABASE=Shenzhen Baojia Battery Technology Co., Ltd. @@ -61450,6 +62074,9 @@ OUI:ACF7F3* OUI:ACF97E* ID_OUI_FROM_DATABASE=ELESYS INC. +OUI:B00594* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + OUI:B01203* ID_OUI_FROM_DATABASE=Dynamics Hong Kong Limited @@ -61564,6 +62191,9 @@ OUI:B09AE2* OUI:B09BD4* ID_OUI_FROM_DATABASE=GNH Software India Private Limited +OUI:B09FBA* + ID_OUI_FROM_DATABASE=Apple + OUI:B0A10A* ID_OUI_FROM_DATABASE=Pivotal Systems Corporation @@ -61618,6 +62248,9 @@ OUI:B0C8AD* OUI:B0C95B* ID_OUI_FROM_DATABASE=Beijing Symtech CO.,LTD +OUI:B0CE18* + ID_OUI_FROM_DATABASE=Zhejiang shenghui lighting co.,Ltd + OUI:B0CF4D* ID_OUI_FROM_DATABASE=MI-Zone Technology Ireland @@ -61957,6 +62590,9 @@ OUI:B83E59* OUI:B8415F* ID_OUI_FROM_DATABASE=ASP AG +OUI:B847C6* + ID_OUI_FROM_DATABASE=SanJet Technology Corp. + OUI:B85510* ID_OUI_FROM_DATABASE=Zioncom Electronics (Shenzhen) Ltd. @@ -61969,6 +62605,9 @@ OUI:B85AF7* OUI:B85AFE* ID_OUI_FROM_DATABASE=Handaer Communication Technology (Beijing) Co., Ltd +OUI:B85E7B* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:B86091* ID_OUI_FROM_DATABASE=Onnet Technologies and Innovations LLC @@ -62014,6 +62653,9 @@ OUI:B8797E* OUI:B8871E* ID_OUI_FROM_DATABASE=Good Mind Industries Co., Ltd. +OUI:B887A8* + ID_OUI_FROM_DATABASE=Step Ahead Innovations Inc. + OUI:B888E3* ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD @@ -62134,6 +62776,9 @@ OUI:B8DAF1* OUI:B8DAF7* ID_OUI_FROM_DATABASE=Advanced Photonics, Inc. +OUI:B8DC87* + ID_OUI_FROM_DATABASE=IAI Corporation + OUI:B8E589* ID_OUI_FROM_DATABASE=Payter BV @@ -62143,6 +62788,9 @@ OUI:B8E625* OUI:B8E779* ID_OUI_FROM_DATABASE=9Solutions Oy +OUI:B8E856* + ID_OUI_FROM_DATABASE=Apple + OUI:B8E937* ID_OUI_FROM_DATABASE=Sonos, Inc. @@ -62161,6 +62809,9 @@ OUI:B8F6B1* OUI:B8F732* ID_OUI_FROM_DATABASE=Aryaka Networks Inc +OUI:B8F828* + ID_OUI_FROM_DATABASE=Changshu Gaoshida Optoelectronic Technology Co. Ltd. + OUI:B8F934* ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB @@ -62215,6 +62866,12 @@ OUI:BC2846* OUI:BC28D6* ID_OUI_FROM_DATABASE=Rowley Associates Limited +OUI:BC2B6B* + ID_OUI_FROM_DATABASE=Beijing Haier IC Design Co.,Ltd + +OUI:BC2BD7* + ID_OUI_FROM_DATABASE=Revogi Innovation Co., Ltd. + OUI:BC2C55* ID_OUI_FROM_DATABASE=Bear Flag Design, Inc. @@ -62317,9 +62974,15 @@ OUI:BC8556* OUI:BC8B55* ID_OUI_FROM_DATABASE=NPP ELIKS America Inc. DBA T&M Atlantic +OUI:BC8CCD* + ID_OUI_FROM_DATABASE=Samsung Electro Mechanics co.,LTD. + OUI:BC926B* ID_OUI_FROM_DATABASE=Apple +OUI:BC9680* + ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co.,Ltd + OUI:BC99BC* ID_OUI_FROM_DATABASE=FonSee Technology Inc. @@ -62488,6 +63151,9 @@ OUI:C05E79* OUI:C0626B* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. +OUI:C06394* + ID_OUI_FROM_DATABASE=Apple + OUI:C06599* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd @@ -62518,6 +63184,9 @@ OUI:C08ADE* OUI:C08B6F* ID_OUI_FROM_DATABASE=S I Sistemas Inteligentes Eletrônicos Ltda +OUI:C08C60* + ID_OUI_FROM_DATABASE=Cisco + OUI:C09132* ID_OUI_FROM_DATABASE=Patriot Memory @@ -62530,6 +63199,9 @@ OUI:C09C92* OUI:C09F42* ID_OUI_FROM_DATABASE=Apple Inc +OUI:C0A0BB* + ID_OUI_FROM_DATABASE=D-Link International + OUI:C0A0C7* ID_OUI_FROM_DATABASE=FAIRFIELD INDUSTRIES @@ -62545,6 +63217,9 @@ OUI:C0A26D* OUI:C0A364* ID_OUI_FROM_DATABASE=3D Systems Massachusetts +OUI:C0A39E* + ID_OUI_FROM_DATABASE=EarthCam, Inc. + OUI:C0AA68* ID_OUI_FROM_DATABASE=OSASI Technos Inc. @@ -62617,6 +63292,9 @@ OUI:C4017C* OUI:C401B1* ID_OUI_FROM_DATABASE=SeekTech INC +OUI:C40938* + ID_OUI_FROM_DATABASE=Fujian Star-net Communication Co., Ltd + OUI:C40ACB* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. @@ -62641,6 +63319,9 @@ OUI:C419EC* OUI:C41ECE* ID_OUI_FROM_DATABASE=HMI Sources Ltd. +OUI:C421C8* + ID_OUI_FROM_DATABASE=KYOCERA Corporation + OUI:C4237A* ID_OUI_FROM_DATABASE=WhizNets Inc. @@ -62708,7 +63389,7 @@ OUI:C458C2* ID_OUI_FROM_DATABASE=Shenzhen TATFOOK Technology Co., Ltd. OUI:C45976* - ID_OUI_FROM_DATABASE=Fugoo + ID_OUI_FROM_DATABASE=Fugoo Coorporation OUI:C45DD8* ID_OUI_FROM_DATABASE=HDMI Forum @@ -62716,6 +63397,9 @@ OUI:C45DD8* OUI:C46044* ID_OUI_FROM_DATABASE=Everex Electronics Limited +OUI:C462EA* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:C46354* ID_OUI_FROM_DATABASE=U-Raku, Inc. @@ -62860,6 +63544,9 @@ OUI:C80E77* OUI:C80E95* ID_OUI_FROM_DATABASE=OmniLync Inc. +OUI:C81479* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:C819F7* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd @@ -63025,6 +63712,9 @@ OUI:C8AF40* OUI:C8B373* ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC +OUI:C8B5B7* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:C8BBD3* ID_OUI_FROM_DATABASE=Embrane @@ -63094,6 +63784,9 @@ OUI:C8EEA6* OUI:C8EF2E* ID_OUI_FROM_DATABASE=Beijing Gefei Tech. Co., Ltd +OUI:C8F36B* + ID_OUI_FROM_DATABASE=Yamato Scale Co.,Ltd. + OUI:C8F386* ID_OUI_FROM_DATABASE=Shenzhen Xiaoniao Technology Co.,Ltd @@ -63160,6 +63853,9 @@ OUI:CC2218* OUI:CC262D* ID_OUI_FROM_DATABASE=Verifi, LLC +OUI:CC2A80* + ID_OUI_FROM_DATABASE=Micro-Biz intelligence solutions Co.,Ltd + OUI:CC2D8C* ID_OUI_FROM_DATABASE=LG ELECTRONICS INC @@ -63169,6 +63865,9 @@ OUI:CC33BB* OUI:CC34D7* ID_OUI_FROM_DATABASE=GEWISS S.P.A. +OUI:CC3540* + ID_OUI_FROM_DATABASE=Technicolor USA Inc. + OUI:CC3A61* ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO MECHANICS CO., LTD. @@ -63181,6 +63880,12 @@ OUI:CC3E5F* OUI:CC43E3* ID_OUI_FROM_DATABASE=Trump s.a. +OUI:CC4703* + ID_OUI_FROM_DATABASE=Intercon Systems Co., Ltd. + +OUI:CC4AE1* + ID_OUI_FROM_DATABASE=Fourtec -Fourier Technologies + OUI:CC4BFB* ID_OUI_FROM_DATABASE=Hellberg Safety AB @@ -63244,6 +63949,9 @@ OUI:CC785F* OUI:CC7A30* ID_OUI_FROM_DATABASE=CMAX Wireless Co., Ltd. +OUI:CC7B35* + ID_OUI_FROM_DATABASE=zte corporation + OUI:CC7D37* ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. @@ -63355,6 +64063,9 @@ OUI:CCEF48* OUI:CCF3A5* ID_OUI_FROM_DATABASE=Chi Mei Communication Systems, Inc +OUI:CCF407* + ID_OUI_FROM_DATABASE=EUKREA ELECTROMATIQUE SARL + OUI:CCF67A* ID_OUI_FROM_DATABASE=Ayecka Communication Systems LTD @@ -63400,6 +64111,9 @@ OUI:D01AA7* OUI:D01CBB* ID_OUI_FROM_DATABASE=Beijing Ctimes Digital Technology Co., Ltd. +OUI:D022BE* + ID_OUI_FROM_DATABASE=Samsung Electro Mechanics co.,LTD. + OUI:D023DB* ID_OUI_FROM_DATABASE=Apple, Inc. @@ -63463,6 +64177,9 @@ OUI:D067E5* OUI:D0699E* ID_OUI_FROM_DATABASE=LUMINEX Lighting Control Equipment +OUI:D0737F* + ID_OUI_FROM_DATABASE=Mini-Circuits + OUI:D0738E* ID_OUI_FROM_DATABASE=DONG OH PRECISION CO., LTD. @@ -63496,6 +64213,9 @@ OUI:D093F8* OUI:D09B05* ID_OUI_FROM_DATABASE=Emtronix +OUI:D09D0A* + ID_OUI_FROM_DATABASE=LINKCOM + OUI:D0A311* ID_OUI_FROM_DATABASE=Neuberger Gebäudeautomation GmbH @@ -63595,6 +64315,9 @@ OUI:D0F27F* OUI:D0F73B* ID_OUI_FROM_DATABASE=Helmut Mauell GmbH +OUI:D0FF50* + ID_OUI_FROM_DATABASE=Texas Instruments, Inc + OUI:D4000D* ID_OUI_FROM_DATABASE=Phoenix Broadband Technologies, LLC. @@ -63682,6 +64405,9 @@ OUI:D44B5E* OUI:D44C24* ID_OUI_FROM_DATABASE=Vuppalamritha Magnetic Components LTD +OUI:D44C9C* + ID_OUI_FROM_DATABASE=Shenzhen YOOBAO Technology Co.Ltd + OUI:D44CA7* ID_OUI_FROM_DATABASE=Informtekhnika & Communication, LLC @@ -63943,6 +64669,9 @@ OUI:D82986* OUI:D82A7E* ID_OUI_FROM_DATABASE=Nokia Corporation +OUI:D82D9B* + ID_OUI_FROM_DATABASE=Shenzhen G.Credit Communication Technology Co., Ltd + OUI:D82DE1* ID_OUI_FROM_DATABASE=Tricascade Inc. @@ -63961,6 +64690,9 @@ OUI:D842AC* OUI:D84606* ID_OUI_FROM_DATABASE=Silicon Valley Global Marketing +OUI:D8490B* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + OUI:D84B2A* ID_OUI_FROM_DATABASE=Cognitas Technologies, Inc. @@ -63985,6 +64717,9 @@ OUI:D866C6* OUI:D867D9* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. +OUI:D86960* + ID_OUI_FROM_DATABASE=Steinsvik + OUI:D86BF7* ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. @@ -64009,6 +64744,9 @@ OUI:D87988* OUI:D88A3B* ID_OUI_FROM_DATABASE=UNIT-EM +OUI:D890E8* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:D8952F* ID_OUI_FROM_DATABASE=Texas Instruments @@ -64156,6 +64894,9 @@ OUI:DC16A2* OUI:DC175A* ID_OUI_FROM_DATABASE=Hitachi High-Technologies Corporation +OUI:DC1792* + ID_OUI_FROM_DATABASE=Captivate Network + OUI:DC1D9F* ID_OUI_FROM_DATABASE=U & B tech @@ -64222,6 +64963,9 @@ OUI:DC5726* OUI:DC647C* ID_OUI_FROM_DATABASE=C.R.S. iiMotion GmbH +OUI:DC6F00* + ID_OUI_FROM_DATABASE=Livescribe, Inc. + OUI:DC6F08* ID_OUI_FROM_DATABASE=Bay Storage Technology @@ -64249,6 +64993,9 @@ OUI:DC9FA4* OUI:DC9FDB* ID_OUI_FROM_DATABASE=Ubiquiti Networks, Inc. +OUI:DCA5F4* + ID_OUI_FROM_DATABASE=Cisco + OUI:DCA6BD* ID_OUI_FROM_DATABASE=Beijing Lanbo Technology Co., Ltd. @@ -64264,6 +65011,9 @@ OUI:DCA971* OUI:DCA989* ID_OUI_FROM_DATABASE=MACANDC +OUI:DCAE04* + ID_OUI_FROM_DATABASE=CELOXICA Ltd + OUI:DCB058* ID_OUI_FROM_DATABASE=Burkert Werke GmbH @@ -64279,6 +65029,9 @@ OUI:DCC0DB* OUI:DCC101* ID_OUI_FROM_DATABASE=SOLiD Technologies, Inc. +OUI:DCC422* + ID_OUI_FROM_DATABASE=Systembase Limited + OUI:DCCBA8* ID_OUI_FROM_DATABASE=Explora Technologies Inc @@ -64315,6 +65068,9 @@ OUI:DCE71C* OUI:DCF05D* ID_OUI_FROM_DATABASE=Letta Teknoloji +OUI:DCF755* + ID_OUI_FROM_DATABASE=SITRONIK + OUI:DCF858* ID_OUI_FROM_DATABASE=Lorent Networks, Inc. @@ -64387,6 +65143,9 @@ OUI:E039D7* OUI:E03C5B* ID_OUI_FROM_DATABASE=SHENZHEN JIAXINJIE ELECTRON CO.,LTD +OUI:E03E4A* + ID_OUI_FROM_DATABASE=Cavanagh Group International + OUI:E03E7D* ID_OUI_FROM_DATABASE=data-complex GmbH @@ -64465,6 +65224,9 @@ OUI:E09D31* OUI:E09DB8* ID_OUI_FROM_DATABASE=PLANEX COMMUNICATIONS INC. +OUI:E0A198* + ID_OUI_FROM_DATABASE=NOJA Power Switchgear Pty Ltd + OUI:E0A1D7* ID_OUI_FROM_DATABASE=SFR @@ -64486,6 +65248,9 @@ OUI:E0AE5E* OUI:E0AEED* ID_OUI_FROM_DATABASE=LOENK +OUI:E0B2F1* + ID_OUI_FROM_DATABASE=FN-LINK TECHNOLOGY LIMITED + OUI:E0B7B1* ID_OUI_FROM_DATABASE=Pace plc @@ -64537,6 +65302,9 @@ OUI:E0CF2D* OUI:E0D10A* ID_OUI_FROM_DATABASE=Katoudenkikougyousyo co ltd +OUI:E0D1E6* + ID_OUI_FROM_DATABASE=Aliph dba Jawbone + OUI:E0D7BA* ID_OUI_FROM_DATABASE=Texas Instruments @@ -64588,6 +65356,9 @@ OUI:E0F847* OUI:E0F9BE* ID_OUI_FROM_DATABASE=Cloudena Corp. +OUI:E0FAEC* + ID_OUI_FROM_DATABASE=Platan sp. z o.o. sp. k. + OUI:E4115B* ID_OUI_FROM_DATABASE=Hewlett Packard @@ -64615,6 +65386,9 @@ OUI:E42AD3* OUI:E42C56* ID_OUI_FROM_DATABASE=Lilee Systems, Ltd. +OUI:E42D02* + ID_OUI_FROM_DATABASE=TCT Mobile Limited + OUI:E42F26* ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Tech.Co.,Ltd. @@ -64639,6 +65413,9 @@ OUI:E438F2* OUI:E43FA2* ID_OUI_FROM_DATABASE=Wuxi DSP Technologies Inc. +OUI:E440E2* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:E441E6* ID_OUI_FROM_DATABASE=Ottec Technology GmbH @@ -64714,6 +65491,9 @@ OUI:E49069* OUI:E492E7* ID_OUI_FROM_DATABASE=Gridlink Tech. Co.,Ltd. +OUI:E492FB* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:E496AE* ID_OUI_FROM_DATABASE=ALTOGRAPHICS Inc. @@ -64873,6 +65653,9 @@ OUI:E84E06* OUI:E84ECE* ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. +OUI:E8516E* + ID_OUI_FROM_DATABASE=TSMART Inc. + OUI:E8519D* ID_OUI_FROM_DATABASE=Yeonhab Precision Co.,LTD @@ -64975,6 +65758,9 @@ OUI:E8B748* OUI:E8BA70* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. +OUI:E8BB3D* + ID_OUI_FROM_DATABASE=Sino Prime-Tech Limited + OUI:E8BE81* ID_OUI_FROM_DATABASE=SAGEMCOM @@ -65035,6 +65821,9 @@ OUI:E8E776* OUI:E8E875* ID_OUI_FROM_DATABASE=iS5 Communications Inc. +OUI:E8EADA* + ID_OUI_FROM_DATABASE=Denkovi Assembly Electroncs LTD + OUI:E8F1B0* ID_OUI_FROM_DATABASE=SAGEMCOM SAS @@ -65056,6 +65845,12 @@ OUI:EC172F* OUI:EC1A59* ID_OUI_FROM_DATABASE=Belkin International Inc. +OUI:EC219F* + ID_OUI_FROM_DATABASE=VidaBox LLC + +OUI:EC2257* + ID_OUI_FROM_DATABASE=JiangSu NanJing University Electronic Information Technology Co.,Ltd + OUI:EC233D* ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd @@ -65074,6 +65869,9 @@ OUI:EC3586* OUI:EC3BF0* ID_OUI_FROM_DATABASE=NovelSat +OUI:EC3E09* + ID_OUI_FROM_DATABASE=PERFORMANCE DESIGNED PRODUCTS, LLC + OUI:EC3F05* ID_OUI_FROM_DATABASE=Institute 706, The Second Academy China Aerospace Science & Industry Corp @@ -65218,6 +66016,9 @@ OUI:ECDE3D* OUI:ECE09B* ID_OUI_FROM_DATABASE=Samsung electronics CO., LTD +OUI:ECE1A9* + ID_OUI_FROM_DATABASE=Cisco + OUI:ECE555* ID_OUI_FROM_DATABASE=Hirschmann Automation @@ -65242,6 +66043,9 @@ OUI:ECF00E* OUI:ECF236* ID_OUI_FROM_DATABASE=NEOMONTANA ELECTRONICS +OUI:ECF35B* + ID_OUI_FROM_DATABASE=Nokia Corporation + OUI:ECFAAA* ID_OUI_FROM_DATABASE=The IMS Company @@ -65305,6 +66109,9 @@ OUI:F02A61* OUI:F02FD8* ID_OUI_FROM_DATABASE=Bi2-Vision +OUI:F037A1* + ID_OUI_FROM_DATABASE=Huike Electronics (SHENZHEN) CO., LTD. + OUI:F03A55* ID_OUI_FROM_DATABASE=Omega Elektronik AS @@ -65353,6 +66160,9 @@ OUI:F06853* OUI:F06BCA* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +OUI:F0728C* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:F073AE* ID_OUI_FROM_DATABASE=PEAK-System Technik @@ -65374,12 +66184,21 @@ OUI:F07F0C* OUI:F081AF* ID_OUI_FROM_DATABASE=IRZ AUTOMATION TECHNOLOGIES LTD +OUI:F0842F* + ID_OUI_FROM_DATABASE=ADB Broadband Italia + OUI:F084C9* ID_OUI_FROM_DATABASE=zte corporation OUI:F08BFE* ID_OUI_FROM_DATABASE=COSTEL.,CO.LTD +OUI:F08EDB* + ID_OUI_FROM_DATABASE=VeloCloud Networks + +OUI:F0921C* + ID_OUI_FROM_DATABASE=Hewlett Packard + OUI:F0933A* ID_OUI_FROM_DATABASE=NxtConect @@ -65482,6 +66301,9 @@ OUI:F0F002* OUI:F0F260* ID_OUI_FROM_DATABASE=Mobitec AB +OUI:F0F5AE* + ID_OUI_FROM_DATABASE=Adaptrum Inc. + OUI:F0F644* ID_OUI_FROM_DATABASE=Whitesky Science & Technology Co.,Ltd. @@ -65530,6 +66352,12 @@ OUI:F41F0B* OUI:F41FC2* ID_OUI_FROM_DATABASE=Cisco +OUI:F42012* + ID_OUI_FROM_DATABASE=Cuciniale GmbH + +OUI:F42896* + ID_OUI_FROM_DATABASE=SPECTO PAINEIS ELETRONICOS LTDA + OUI:F436E1* ID_OUI_FROM_DATABASE=Abilis Systems SARL @@ -65584,6 +66412,9 @@ OUI:F455E0* OUI:F45842* ID_OUI_FROM_DATABASE=Boxx TV Ltd +OUI:F45F69* + ID_OUI_FROM_DATABASE=Matsufu Electronics distribution Company + OUI:F45FD4* ID_OUI_FROM_DATABASE=Cisco SPVTG @@ -65608,6 +66439,9 @@ OUI:F473CA* OUI:F47626* ID_OUI_FROM_DATABASE=Viltechmeda UAB +OUI:F47A4E* + ID_OUI_FROM_DATABASE=Woojeon&Handan + OUI:F47ACC* ID_OUI_FROM_DATABASE=SolidFire, Inc. @@ -65641,6 +66475,9 @@ OUI:F499AC* OUI:F49F54* ID_OUI_FROM_DATABASE=Samsung Electronics +OUI:F4A294* + ID_OUI_FROM_DATABASE=EAGLE WORLD DEVELOPMENT CO., LIMITED + OUI:F4A52A* ID_OUI_FROM_DATABASE=Hawa Technologies Inc @@ -65662,6 +66499,9 @@ OUI:F4B72A* OUI:F4B7E2* ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. +OUI:F4BD7C* + ID_OUI_FROM_DATABASE=Chengdu jinshi communication Co., LTD + OUI:F4C6D7* ID_OUI_FROM_DATABASE=blackned GmbH @@ -65674,6 +66514,9 @@ OUI:F4C795* OUI:F4CAE5* ID_OUI_FROM_DATABASE=FREEBOX SA +OUI:F4CD90* + ID_OUI_FROM_DATABASE=Vispiron Rotec GmbH + OUI:F4CE46* ID_OUI_FROM_DATABASE=Hewlett-Packard Company @@ -65740,6 +66583,9 @@ OUI:F80F84* OUI:F81037* ID_OUI_FROM_DATABASE=Atopia Systems, LP +OUI:F81654* + ID_OUI_FROM_DATABASE=Intel Corporate + OUI:F81A67* ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD. @@ -65794,6 +66640,12 @@ OUI:F8472D* OUI:F84897* ID_OUI_FROM_DATABASE=Hitachi, Ltd. +OUI:F84ABF* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +OUI:F84F57* + ID_OUI_FROM_DATABASE=Cisco + OUI:F85063* ID_OUI_FROM_DATABASE=Verathon @@ -65803,6 +66655,9 @@ OUI:F8516D* OUI:F852DF* ID_OUI_FROM_DATABASE=VNL Europe AB +OUI:F85BC9* + ID_OUI_FROM_DATABASE=M-Cube Spa + OUI:F85F2A* ID_OUI_FROM_DATABASE=Nokia Corporation @@ -65863,6 +66718,9 @@ OUI:F89955* OUI:F89D0D* ID_OUI_FROM_DATABASE=Control Technology Inc. +OUI:F89FB8* + ID_OUI_FROM_DATABASE=YAZAKI Energy System Corporation + OUI:F8A03D* ID_OUI_FROM_DATABASE=Dinstar Technologies Co., Ltd. @@ -65875,6 +66733,9 @@ OUI:F8AA8A* OUI:F8AC6D* ID_OUI_FROM_DATABASE=Deltenna Ltd +OUI:F8B156* + ID_OUI_FROM_DATABASE=Dell Inc PCBA Test + OUI:F8B599* ID_OUI_FROM_DATABASE=Guangzhou CHNAVS Digital Technology Co.,Ltd @@ -65948,7 +66809,10 @@ OUI:F8F014* ID_OUI_FROM_DATABASE=RackWare Inc. OUI:F8F082* - ID_OUI_FROM_DATABASE=NAG LLC + ID_OUI_FROM_DATABASE=Orion Networks International, Inc + +OUI:F8F1B6* + ID_OUI_FROM_DATABASE=Motorola Mobility LLC OUI:F8F25A* ID_OUI_FROM_DATABASE=G-Lab GmbH @@ -65968,9 +66832,15 @@ OUI:F8FE5C* OUI:F8FEA8* ID_OUI_FROM_DATABASE=Technico Japan Corporation +OUI:F8FF5F* + ID_OUI_FROM_DATABASE=Shenzhen Communication Technology Co.,Ltd + OUI:FC0012* ID_OUI_FROM_DATABASE=Toshiba Samsung Storage Technolgoy Korea Corporation +OUI:FC019E* + ID_OUI_FROM_DATABASE=VIEVU + OUI:FC01CD* ID_OUI_FROM_DATABASE=FUNDACION TEKNIKER @@ -66025,6 +66895,9 @@ OUI:FC3598* OUI:FC35E6* ID_OUI_FROM_DATABASE=Visteon corp +OUI:FC3FAB* + ID_OUI_FROM_DATABASE=Henan Lanxin Technology Co., Ltd + OUI:FC4463* ID_OUI_FROM_DATABASE=Universal Audio diff --git a/hwdb/20-pci-vendor-model.hwdb b/hwdb/20-pci-vendor-model.hwdb index a8dcc31776..99e0f61449 100644 --- a/hwdb/20-pci-vendor-model.hwdb +++ b/hwdb/20-pci-vendor-model.hwdb @@ -926,12 +926,45 @@ pci:v00001000d0000005C* pci:v00001000d0000005D* ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3108 [Invader] +pci:v00001000d0000005Dsv00001028sd00001F41* + ID_MODEL_FROM_DATABASE=PERC H830 Adapter + +pci:v00001000d0000005Dsv00001028sd00001F42* + ID_MODEL_FROM_DATABASE=PERC H730P Adapter + +pci:v00001000d0000005Dsv00001028sd00001F43* + ID_MODEL_FROM_DATABASE=PERC H730 Adapter + +pci:v00001000d0000005Dsv00001028sd00001F47* + ID_MODEL_FROM_DATABASE=PERC H730P Mini + +pci:v00001000d0000005Dsv00001028sd00001F48* + ID_MODEL_FROM_DATABASE=PERC H730P Mini (for blades) + +pci:v00001000d0000005Dsv00001028sd00001F49* + ID_MODEL_FROM_DATABASE=PERC H730 Mini + +pci:v00001000d0000005Dsv00001028sd00001F4A* + ID_MODEL_FROM_DATABASE=PERC H730 Mini (for blades) + pci:v00001000d0000005E* ID_MODEL_FROM_DATABASE=SAS1066 PCI-X Fusion-MPT SAS pci:v00001000d0000005F* ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3008 [Fury] +pci:v00001000d0000005Fsv00001028sd00001F44* + ID_MODEL_FROM_DATABASE=PERC H330 Adapter + +pci:v00001000d0000005Fsv00001028sd00001F4B* + ID_MODEL_FROM_DATABASE=PERC H330 Mini + +pci:v00001000d0000005Fsv00001028sd00001F4C* + ID_MODEL_FROM_DATABASE=PERC H330 Mini (for blades) + +pci:v00001000d0000005Fsv00001028sd00001F4D* + ID_MODEL_FROM_DATABASE=PERC H330 Embedded (for monolithic) + pci:v00001000d00000060* ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 @@ -1604,11 +1637,53 @@ pci:v00001002d00001306* pci:v00001002d00001307* ID_MODEL_FROM_DATABASE=Kaveri +pci:v00001002d00001309* + ID_MODEL_FROM_DATABASE=Kaveri + +pci:v00001002d0000130A* + ID_MODEL_FROM_DATABASE=Kaveri + +pci:v00001002d0000130B* + ID_MODEL_FROM_DATABASE=Kaveri + +pci:v00001002d0000130C* + ID_MODEL_FROM_DATABASE=Kaveri + +pci:v00001002d0000130D* + ID_MODEL_FROM_DATABASE=Kaveri + +pci:v00001002d0000130E* + ID_MODEL_FROM_DATABASE=Kaveri + +pci:v00001002d0000130F* + ID_MODEL_FROM_DATABASE=Kaveri + +pci:v00001002d00001310* + ID_MODEL_FROM_DATABASE=Kaveri + +pci:v00001002d00001311* + ID_MODEL_FROM_DATABASE=Kaveri + +pci:v00001002d00001313* + ID_MODEL_FROM_DATABASE=Kaveri + pci:v00001002d00001314* - ID_MODEL_FROM_DATABASE=Wrestler HDMI Audio [Radeon HD 6250/6310] + ID_MODEL_FROM_DATABASE=Wrestler HDMI Audio pci:v00001002d00001314sv0000174Bsd00001001* - ID_MODEL_FROM_DATABASE=Sapphire PURE Fusion Mini + ID_MODEL_FROM_DATABASE=PURE Fusion Mini + +pci:v00001002d00001315* + ID_MODEL_FROM_DATABASE=Kaveri + +pci:v00001002d00001316* + ID_MODEL_FROM_DATABASE=Kaveri + +pci:v00001002d0000131B* + ID_MODEL_FROM_DATABASE=Kaveri + +pci:v00001002d0000131C* + ID_MODEL_FROM_DATABASE=Kaveri pci:v00001002d00001714* ID_MODEL_FROM_DATABASE=BeaverCreek HDMI Audio [Radeon HD 6500D and 6400G-6600G series] @@ -1677,19 +1752,19 @@ pci:v00001002d00004150sv00001002sd00004722* ID_MODEL_FROM_DATABASE=All-in-Wonder 2006 AGP Edition pci:v00001002d00004150sv00001458sd00004024* - ID_MODEL_FROM_DATABASE=Giga-Byte GV-R96128D (Primary) + ID_MODEL_FROM_DATABASE=GV-R96128D pci:v00001002d00004150sv0000148Csd00002064* - ID_MODEL_FROM_DATABASE=PowerColor R96A-C3N + ID_MODEL_FROM_DATABASE=R96A-C3N pci:v00001002d00004150sv0000148Csd00002066* - ID_MODEL_FROM_DATABASE=PowerColor R96A-C3N + ID_MODEL_FROM_DATABASE=R96A-C3N pci:v00001002d00004150sv0000174Bsd00007C19* - ID_MODEL_FROM_DATABASE=Sapphire Atlantis Radeon 9600 Pro + ID_MODEL_FROM_DATABASE=Atlantis Radeon 9600 Pro pci:v00001002d00004150sv0000174Bsd00007C29* - ID_MODEL_FROM_DATABASE=GC-R9600PRO [Sapphire] (Primary) + ID_MODEL_FROM_DATABASE=GC-R9600PRO pci:v00001002d00004150sv000017EEsd00002002* ID_MODEL_FROM_DATABASE=Radeon 9600 256Mb Primary @@ -1722,7 +1797,7 @@ pci:v00001002d00004152sv00001462sd00009510* ID_MODEL_FROM_DATABASE=RX9600XT (MS-8951) pci:v00001002d00004152sv0000174Bsd00007C29* - ID_MODEL_FROM_DATABASE=Sapphire Radeon 9600XT + ID_MODEL_FROM_DATABASE=Radeon 9600XT pci:v00001002d00004152sv00001787sd00004002* ID_MODEL_FROM_DATABASE=Radeon 9600 XT @@ -1770,13 +1845,13 @@ pci:v00001002d00004170sv00001002sd00004723* ID_MODEL_FROM_DATABASE=All-in-Wonder 2006 AGP Edition (Secondary) pci:v00001002d00004170sv00001458sd00004025* - ID_MODEL_FROM_DATABASE=Giga-Byte GV-R96128D (Secondary) + ID_MODEL_FROM_DATABASE=GV-R96128D (Secondary) pci:v00001002d00004170sv0000148Csd00002067* - ID_MODEL_FROM_DATABASE=PowerColor R96A-C3N (Secondary) + ID_MODEL_FROM_DATABASE=R96A-C3N (Secondary) pci:v00001002d00004170sv0000174Bsd00007C28* - ID_MODEL_FROM_DATABASE=GC-R9600PRO [Sapphire] (Secondary) + ID_MODEL_FROM_DATABASE=GC-R9600PRO (Secondary) pci:v00001002d00004170sv000017EEsd00002003* ID_MODEL_FROM_DATABASE=Radeon 9600 256Mb (Secondary) @@ -1806,7 +1881,7 @@ pci:v00001002d00004172sv00001043sd0000C01B* ID_MODEL_FROM_DATABASE=A9600XT/TD (Secondary) pci:v00001002d00004172sv0000174Bsd00007C28* - ID_MODEL_FROM_DATABASE=Sapphire Radeon 9600XT (Secondary) + ID_MODEL_FROM_DATABASE=Radeon 9600XT (Secondary) pci:v00001002d00004172sv00001787sd00004003* ID_MODEL_FROM_DATABASE=Radeon 9600 XT (Secondary) @@ -2148,7 +2223,7 @@ pci:v00001002d00004385sv000015D9sd0000A811* ID_MODEL_FROM_DATABASE=H8DGU pci:v00001002d00004385sv0000174Bsd00001001* - ID_MODEL_FROM_DATABASE=Sapphire PURE Fusion Mini + ID_MODEL_FROM_DATABASE=PURE Fusion Mini pci:v00001002d00004385sv000017F2sd00005000* ID_MODEL_FROM_DATABASE=KI690-AM2 Motherboard @@ -2307,7 +2382,7 @@ pci:v00001002d00004391sv00001043sd00008443* ID_MODEL_FROM_DATABASE=M5A88-V EVO pci:v00001002d00004391sv0000174Bsd00001001* - ID_MODEL_FROM_DATABASE=Sapphire PURE Fusion Mini + ID_MODEL_FROM_DATABASE=PURE Fusion Mini pci:v00001002d00004392* ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [Non-RAID5 mode] @@ -2340,7 +2415,7 @@ pci:v00001002d00004396sv000015D9sd0000A811* ID_MODEL_FROM_DATABASE=H8DGU pci:v00001002d00004396sv0000174Bsd00001001* - ID_MODEL_FROM_DATABASE=Sapphire PURE Fusion Mini + ID_MODEL_FROM_DATABASE=PURE Fusion Mini pci:v00001002d00004397* ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI0 Controller @@ -2361,7 +2436,7 @@ pci:v00001002d00004397sv000015D9sd0000A811* ID_MODEL_FROM_DATABASE=H8DGU pci:v00001002d00004397sv0000174Bsd00001001* - ID_MODEL_FROM_DATABASE=Sapphire PURE Fusion Mini + ID_MODEL_FROM_DATABASE=PURE Fusion Mini pci:v00001002d00004398* ID_MODEL_FROM_DATABASE=SB7x0 USB OHCI1 Controller @@ -2388,7 +2463,7 @@ pci:v00001002d00004399sv00001043sd00008443* ID_MODEL_FROM_DATABASE=M5A88-V EVO pci:v00001002d00004399sv0000174Bsd00001001* - ID_MODEL_FROM_DATABASE=Sapphire PURE Fusion Mini + ID_MODEL_FROM_DATABASE=PURE Fusion Mini pci:v00001002d0000439C* ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 IDE Controller @@ -2415,7 +2490,7 @@ pci:v00001002d0000439Dsv00001043sd00008443* ID_MODEL_FROM_DATABASE=M5A88-V EVO pci:v00001002d0000439Dsv0000174Bsd00001001* - ID_MODEL_FROM_DATABASE=Sapphire PURE Fusion Mini + ID_MODEL_FROM_DATABASE=PURE Fusion Mini pci:v00001002d000043A0* ID_MODEL_FROM_DATABASE=SB700/SB800/SB900 PCI to PCI bridge (PCIE port 0) @@ -2691,7 +2766,7 @@ pci:v00001002d00004966sv00001681sd00000040* ID_MODEL_FROM_DATABASE=RV250 If [3D prophet 9000] pci:v00001002d00004966sv0000174Bsd00007176* - ID_MODEL_FROM_DATABASE=RV250 If [Sapphire Radeon 9000 Pro] + ID_MODEL_FROM_DATABASE=Radeon 9000 Pro pci:v00001002d00004966sv0000174Bsd00007192* ID_MODEL_FROM_DATABASE=RV250 If [Radeon 9000 "Atlantis"] @@ -3171,7 +3246,7 @@ pci:v00001002d0000514Csv00001681sd00000010* ID_MODEL_FROM_DATABASE=Radeon 8500 [3D Prophet 8500 128Mb] pci:v00001002d0000514Csv0000174Bsd00007149* - ID_MODEL_FROM_DATABASE=Radeon R200 QL [Sapphire Radeon 8500 LE] + ID_MODEL_FROM_DATABASE=Radeon 8500 LE pci:v00001002d0000514Csv00001787sd00000F08* ID_MODEL_FROM_DATABASE=Radeon R200 QL [PowerMagic Radeon 8500] @@ -3207,7 +3282,7 @@ pci:v00001002d00005157sv0000174Bsd00007146* ID_MODEL_FROM_DATABASE=RV200 QW [Radeon 7500 LE] pci:v00001002d00005157sv0000174Bsd00007147* - ID_MODEL_FROM_DATABASE=RV200 QW [Sapphire Radeon 7500LE] + ID_MODEL_FROM_DATABASE=Radeon 7500 LE pci:v00001002d00005157sv0000174Bsd00007161* ID_MODEL_FROM_DATABASE=Radeon RV200 QW [Radeon 7500 LE] @@ -3276,10 +3351,10 @@ pci:v00001002d00005159sv0000174Bsd00000280* ID_MODEL_FROM_DATABASE=Radeon RV100 QY [Radeon 7000/VE] pci:v00001002d00005159sv0000174Bsd00007112* - ID_MODEL_FROM_DATABASE=RV100 QY [Sapphire Radeon VE 7000] + ID_MODEL_FROM_DATABASE=Radeon VE 7000 pci:v00001002d00005159sv0000174Bsd00007C28* - ID_MODEL_FROM_DATABASE=Sapphire Radeon VE 7000 DDR + ID_MODEL_FROM_DATABASE=Radeon VE 7000 DDR pci:v00001002d00005159sv00001787sd00000202* ID_MODEL_FROM_DATABASE=RV100 QY [Excalibur Radeon 7000] @@ -3579,10 +3654,10 @@ pci:v00001002d00005941* ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200] (Secondary) pci:v00001002d00005941sv00001458sd00004019* - ID_MODEL_FROM_DATABASE=Gigabyte Radeon 9200 + ID_MODEL_FROM_DATABASE=Radeon 9200 pci:v00001002d00005941sv0000174Bsd00007C12* - ID_MODEL_FROM_DATABASE=Sapphire Radeon 9200 + ID_MODEL_FROM_DATABASE=Radeon 9200 pci:v00001002d00005941sv000017AFsd0000200D* ID_MODEL_FROM_DATABASE=Excalibur Radeon 9200 @@ -3669,10 +3744,10 @@ pci:v00001002d00005961sv000012ABsd00005961* ID_MODEL_FROM_DATABASE=YUAN SMARTVGA Radeon 9200 pci:v00001002d00005961sv00001458sd00004018* - ID_MODEL_FROM_DATABASE=Gigabyte Radeon 9200 + ID_MODEL_FROM_DATABASE=Radeon 9200 pci:v00001002d00005961sv0000174Bsd00007C13* - ID_MODEL_FROM_DATABASE=Sapphire Radeon 9200 + ID_MODEL_FROM_DATABASE=Radeon 9200 pci:v00001002d00005961sv000017AFsd0000200C* ID_MODEL_FROM_DATABASE=Excalibur Radeon 9200 @@ -3696,7 +3771,7 @@ pci:v00001002d00005964sv00001002sd00005964* ID_MODEL_FROM_DATABASE=Radeon 9200 SE, 64-bit 128MB DDR, 200/166MHz pci:v00001002d00005964sv00001043sd0000C006* - ID_MODEL_FROM_DATABASE=ASUS Radeon 9200 SE / TD / 128M + ID_MODEL_FROM_DATABASE=Radeon 9200 SE / TD / 128M pci:v00001002d00005964sv00001458sd00004018* ID_MODEL_FROM_DATABASE=Radeon 9200 SE @@ -3711,7 +3786,7 @@ pci:v00001002d00005964sv0000148Csd00002073* ID_MODEL_FROM_DATABASE=CN-AG92E pci:v00001002d00005964sv0000174Bsd00007C13* - ID_MODEL_FROM_DATABASE=Sapphire Radeon 9200 SE + ID_MODEL_FROM_DATABASE=Radeon 9200 SE pci:v00001002d00005964sv00001787sd00005964* ID_MODEL_FROM_DATABASE=Excalibur 9200SE VIVO 128M @@ -3741,7 +3816,7 @@ pci:v00001002d00005975* ID_MODEL_FROM_DATABASE=RS482M [Mobility Radeon Xpress 200] pci:v00001002d00005978* - ID_MODEL_FROM_DATABASE=RD790 PCI to PCI bridge (external gfx0 port A) + ID_MODEL_FROM_DATABASE=RX780/RD790 PCI to PCI bridge (external gfx0 port A) pci:v00001002d00005978sv00001849sd00005957* ID_MODEL_FROM_DATABASE=A770CrossFire Motherboard @@ -3753,13 +3828,13 @@ pci:v00001002d0000597A* ID_MODEL_FROM_DATABASE=RD790 PCI to PCI bridge (PCI express gpp port A) pci:v00001002d0000597B* - ID_MODEL_FROM_DATABASE=RD790 PCI to PCI bridge (PCI express gpp port B) + ID_MODEL_FROM_DATABASE=RX780/RD790 PCI to PCI bridge (PCI express gpp port B) pci:v00001002d0000597C* ID_MODEL_FROM_DATABASE=RD790 PCI to PCI bridge (PCI express gpp port C) pci:v00001002d0000597D* - ID_MODEL_FROM_DATABASE=RD790 PCI to PCI bridge (PCI express gpp port D) + ID_MODEL_FROM_DATABASE=RX780/RD790 PCI to PCI bridge (PCI express gpp port D) pci:v00001002d0000597E* ID_MODEL_FROM_DATABASE=RD790 PCI to PCI bridge (PCI express gpp port E) @@ -3927,7 +4002,7 @@ pci:v00001002d00005B70sv00001462sd00000403* ID_MODEL_FROM_DATABASE=Radeon X300 SE 128MB DDR pci:v00001002d00005B70sv0000174Bsd00000501* - ID_MODEL_FROM_DATABASE=Sapphire Radeon X300 SE + ID_MODEL_FROM_DATABASE=Radeon X300 SE pci:v00001002d00005B70sv0000196Dsd00001087* ID_MODEL_FROM_DATABASE=Radeon X300 SE HyperMemory @@ -3969,7 +4044,7 @@ pci:v00001002d00005D44sv0000147Bsd00006190* ID_MODEL_FROM_DATABASE=R9200SE-DT (Secondary) pci:v00001002d00005D44sv0000174Bsd00007C12* - ID_MODEL_FROM_DATABASE=Sapphire Radeon 9200 SE (Secondary) + ID_MODEL_FROM_DATABASE=Radeon 9200 SE (Secondary) pci:v00001002d00005D44sv00001787sd00005965* ID_MODEL_FROM_DATABASE=Excalibur 9200SE VIVO 128M (Secondary) @@ -4013,9 +4088,6 @@ pci:v00001002d00005D52* pci:v00001002d00005D52sv00001002sd00000B12* ID_MODEL_FROM_DATABASE=PowerColor X850XT PCIe (Primary) -pci:v00001002d00005D52sv00001002sd00000B13* - ID_MODEL_FROM_DATABASE=PowerColor X850XT PCIe (Secondary) - pci:v00001002d00005D57* ID_MODEL_FROM_DATABASE=R423 [Radeon X800 XT] @@ -4028,6 +4100,9 @@ pci:v00001002d00005D6F* pci:v00001002d00005D72* ID_MODEL_FROM_DATABASE=R480 [Radeon X850 XT] (Secondary) +pci:v00001002d00005D72sv00001002sd00000B13* + ID_MODEL_FROM_DATABASE=PowerColor X850XT PCIe (Secondary) + pci:v00001002d00005D77* ID_MODEL_FROM_DATABASE=R423 [Radeon X800 XT] (Secondary) @@ -4050,7 +4125,7 @@ pci:v00001002d00005E4D* ID_MODEL_FROM_DATABASE=RV410 [Radeon X700] pci:v00001002d00005E4Dsv0000148Csd00002116* - ID_MODEL_FROM_DATABASE=PowerColor Bravo X700 + ID_MODEL_FROM_DATABASE=Bravo X700 pci:v00001002d00005E4F* ID_MODEL_FROM_DATABASE=RV410 [Radeon X700] @@ -4065,7 +4140,7 @@ pci:v00001002d00005E6D* ID_MODEL_FROM_DATABASE=RV410 [Radeon X700] (Secondary) pci:v00001002d00005E6Dsv0000148Csd00002117* - ID_MODEL_FROM_DATABASE=PowerColor Bravo X700 + ID_MODEL_FROM_DATABASE=Bravo X700 (Secondary) pci:v00001002d00005F57* ID_MODEL_FROM_DATABASE=R423 [Radeon X800 XT] @@ -4092,7 +4167,7 @@ pci:v00001002d00006610* ID_MODEL_FROM_DATABASE=Oland [Radeon HD 8600 Series] pci:v00001002d00006611* - ID_MODEL_FROM_DATABASE=Oland [Radeon HD 8500 Series] + ID_MODEL_FROM_DATABASE=Oland [Radeon HD 8570] pci:v00001002d00006613* ID_MODEL_FROM_DATABASE=Oland [Radeon HD 8500 Series] @@ -4110,7 +4185,7 @@ pci:v00001002d00006631* ID_MODEL_FROM_DATABASE=Oland pci:v00001002d00006640* - ID_MODEL_FROM_DATABASE=Saturn XT + ID_MODEL_FROM_DATABASE=Saturn [Radeon HD 8950] pci:v00001002d00006641* ID_MODEL_FROM_DATABASE=Saturn PRO @@ -4148,17 +4223,26 @@ pci:v00001002d0000665Csv0000174Bsd0000E253* pci:v00001002d0000665Csv00001787sd00002329* ID_MODEL_FROM_DATABASE=Radeon HD 7790 TurboDuo +pci:v00001002d0000665D* + ID_MODEL_FROM_DATABASE=Bonaire + pci:v00001002d00006660* - ID_MODEL_FROM_DATABASE=Sun XT [Radeon HD 8600M Series] + ID_MODEL_FROM_DATABASE=Sun XT [Radeon HD 8670A] pci:v00001002d00006663* ID_MODEL_FROM_DATABASE=Sun PRO [Radeon HD 8500M Series] +pci:v00001002d00006664* + ID_MODEL_FROM_DATABASE=Sun [Radeon R5 M200 Series] + +pci:v00001002d00006665* + ID_MODEL_FROM_DATABASE=Sun [Radeon R5 M200 Series] + pci:v00001002d00006667* - ID_MODEL_FROM_DATABASE=Sun + ID_MODEL_FROM_DATABASE=Sun [Radeon R5 M200 Series] pci:v00001002d0000666F* - ID_MODEL_FROM_DATABASE=Sun LE + ID_MODEL_FROM_DATABASE=Sun [Radeon HD 8500M] pci:v00001002d00006670* ID_MODEL_FROM_DATABASE=Hainan @@ -4250,21 +4334,474 @@ pci:v00001002d0000673Esv0000148Csd00007720* pci:v00001002d00006740* ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] +pci:v00001002d00006740sv00001019sd0000238C* + ID_MODEL_FROM_DATABASE=Radeon HD 6730M + +pci:v00001002d00006740sv00001019sd0000238E* + ID_MODEL_FROM_DATABASE=Radeon HD 6730M + +pci:v00001002d00006740sv00001019sd00002391* + ID_MODEL_FROM_DATABASE=Radeon HD 6730M + +pci:v00001002d00006740sv00001019sd00002392* + ID_MODEL_FROM_DATABASE=Radeon HD 6770M + pci:v00001002d00006740sv00001028sd000004A3* ID_MODEL_FROM_DATABASE=Precision M4600 +pci:v00001002d00006740sv00001028sd0000053E* + ID_MODEL_FROM_DATABASE=FirePro M5950 + +pci:v00001002d00006740sv0000103Csd00001630* + ID_MODEL_FROM_DATABASE=FirePro M5950 + +pci:v00001002d00006740sv0000103Csd00001631* + ID_MODEL_FROM_DATABASE=FirePro M5950 + +pci:v00001002d00006740sv0000103Csd0000164B* + ID_MODEL_FROM_DATABASE=Radeon HD 6730M + +pci:v00001002d00006740sv0000103Csd0000164E* + ID_MODEL_FROM_DATABASE=Radeon HD 6730M + +pci:v00001002d00006740sv0000103Csd00001657* + ID_MODEL_FROM_DATABASE=Radeon HD 6770M + +pci:v00001002d00006740sv0000103Csd00001658* + ID_MODEL_FROM_DATABASE=Radeon HD 6770M + +pci:v00001002d00006740sv0000103Csd0000165A* + ID_MODEL_FROM_DATABASE=Radeon HD 6770M + +pci:v00001002d00006740sv0000103Csd0000165B* + ID_MODEL_FROM_DATABASE=Radeon HD 6770M + +pci:v00001002d00006740sv0000103Csd00001688* + ID_MODEL_FROM_DATABASE=Radeon HD 6770M + +pci:v00001002d00006740sv0000103Csd00001689* + ID_MODEL_FROM_DATABASE=Radeon HD 6770M + +pci:v00001002d00006740sv0000103Csd0000168A* + ID_MODEL_FROM_DATABASE=Radeon HD 6770M + +pci:v00001002d00006740sv0000103Csd0000185E* + ID_MODEL_FROM_DATABASE=Radeon HD 7690M XT + +pci:v00001002d00006740sv0000103Csd00003388* + ID_MODEL_FROM_DATABASE=Radeon HD 6770M + +pci:v00001002d00006740sv0000103Csd00003389* + ID_MODEL_FROM_DATABASE=Radeon HD 6770M + +pci:v00001002d00006740sv0000103Csd00003582* + ID_MODEL_FROM_DATABASE=Radeon HD 6770M + +pci:v00001002d00006740sv0000103Csd0000366C* + ID_MODEL_FROM_DATABASE=Radeon HD 6730M + +pci:v00001002d00006740sv00001043sd00001D02* + ID_MODEL_FROM_DATABASE=Radeon HD 6730M + +pci:v00001002d00006740sv00001043sd00001D12* + ID_MODEL_FROM_DATABASE=Radeon HD 6730M + +pci:v00001002d00006740sv0000104Dsd00009084* + ID_MODEL_FROM_DATABASE=Radeon HD 6730M + +pci:v00001002d00006740sv0000104Dsd00009085* + ID_MODEL_FROM_DATABASE=Radeon HD 6730M + +pci:v00001002d00006740sv0000144Dsd0000B074* + ID_MODEL_FROM_DATABASE=Radeon HD 6730M + +pci:v00001002d00006740sv0000144Dsd0000B077* + ID_MODEL_FROM_DATABASE=Radeon HD 6730M + +pci:v00001002d00006740sv0000144Dsd0000B084* + ID_MODEL_FROM_DATABASE=Radeon HD 6730M + +pci:v00001002d00006740sv0000144Dsd0000B088* + ID_MODEL_FROM_DATABASE=Radeon HD 6730M + +pci:v00001002d00006740sv000017AAsd00003982* + ID_MODEL_FROM_DATABASE=Radeon HD 6730M + pci:v00001002d00006741* - ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6600M/6700M/7600M Series] + ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] + +pci:v00001002d00006741sv00001019sd0000238E* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001019sd0000238F* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd00000379* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd0000037B* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd0000037E* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd00000382* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd00000384* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd00000385* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd00000386* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd00000387* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd00000388* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd00000442* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd00000451* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd00000489* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd0000048B* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd0000048C* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd0000050A* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd0000050B* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd0000050C* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd0000050E* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd0000050F* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd00000513* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd00000514* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd00000515* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd00000516* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd0000051E* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd0000051F* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd00000520* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd00000521* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd0000052A* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd00000555* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd00000556* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd0000055D* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd0000055E* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd0000056D* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd0000059A* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd0000059B* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd0000059E* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd0000059F* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd00000600* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd00000605* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd00000606* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001025sd00000619* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001028sd000004C1* + ID_MODEL_FROM_DATABASE=Radeon HD 6630M + +pci:v00001002d00006741sv00001028sd000004C5* + ID_MODEL_FROM_DATABASE=Radeon HD 6630M + +pci:v00001002d00006741sv00001028sd000004CD* + ID_MODEL_FROM_DATABASE=Radeon HD 6630M + +pci:v00001002d00006741sv00001028sd000004D7* + ID_MODEL_FROM_DATABASE=Radeon HD 6630M + +pci:v00001002d00006741sv00001028sd000004D9* + ID_MODEL_FROM_DATABASE=Radeon HD 6630M + +pci:v00001002d00006741sv00001028sd0000052D* + ID_MODEL_FROM_DATABASE=Radeon HD 6630M + +pci:v00001002d00006741sv0000103Csd00001617* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv0000103Csd00001646* + ID_MODEL_FROM_DATABASE=Radeon HD 6750M + +pci:v00001002d00006741sv0000103Csd00001647* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv0000103Csd0000164B* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv0000103Csd0000164E* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv0000103Csd00001688* + ID_MODEL_FROM_DATABASE=Radeon HD 6750M + +pci:v00001002d00006741sv0000103Csd00001689* + ID_MODEL_FROM_DATABASE=Radeon HD 6750M + +pci:v00001002d00006741sv0000103Csd0000168A* + ID_MODEL_FROM_DATABASE=Radeon HD 6750M + +pci:v00001002d00006741sv0000103Csd00001860* + ID_MODEL_FROM_DATABASE=Radeon HD 7690M + +pci:v00001002d00006741sv0000103Csd00003385* + ID_MODEL_FROM_DATABASE=Radeon HD 6630M + +pci:v00001002d00006741sv0000103Csd00003560* + ID_MODEL_FROM_DATABASE=Radeon HD 6750M + +pci:v00001002d00006741sv0000103Csd0000358D* + ID_MODEL_FROM_DATABASE=Radeon HD 6750M + +pci:v00001002d00006741sv0000103Csd00003590* + ID_MODEL_FROM_DATABASE=Radeon HD 6750M + +pci:v00001002d00006741sv0000103Csd00003593* + ID_MODEL_FROM_DATABASE=Radeon HD 6750M + +pci:v00001002d00006741sv0000103Csd0000366C* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001043sd00001CD2* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001043sd00002121* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001043sd00002122* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001043sd00002123* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001043sd00002125* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006741sv00001043sd00002127* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006741sv0000104Dsd0000907B* + ID_MODEL_FROM_DATABASE=Radeon HD 6630M + +pci:v00001002d00006741sv0000104Dsd00009080* + ID_MODEL_FROM_DATABASE=Radeon HD 6630M + +pci:v00001002d00006741sv0000104Dsd00009081* + ID_MODEL_FROM_DATABASE=Radeon HD 6630M pci:v00001002d00006741sv0000106Bsd000000E2* ID_MODEL_FROM_DATABASE=MacBookPro8,2 [Core i7, 15", Late 2011] +pci:v00001002d00006741sv00001179sd0000FD63* + ID_MODEL_FROM_DATABASE=Radeon HD 6630M + +pci:v00001002d00006741sv00001179sd0000FD65* + ID_MODEL_FROM_DATABASE=Radeon HD 6630M + +pci:v00001002d00006741sv0000144Dsd0000C093* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv0000144Dsd0000C0AC* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv0000144Dsd0000C0B3* + ID_MODEL_FROM_DATABASE=Radeon HD 6750M + +pci:v00001002d00006741sv0000144Dsd0000C539* + ID_MODEL_FROM_DATABASE=Radeon HD 6630M + +pci:v00001002d00006741sv0000144Dsd0000C609* + ID_MODEL_FROM_DATABASE=Radeon HD 6630M + +pci:v00001002d00006741sv0000152Dsd00000914* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv000017AAsd000021E1* + ID_MODEL_FROM_DATABASE=Radeon HD 6630M + +pci:v00001002d00006741sv000017AAsd00003970* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv000017AAsd00003976* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + +pci:v00001002d00006741sv00001854sd00000907* + ID_MODEL_FROM_DATABASE=Radeon HD 6650M + pci:v00001002d00006742* ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] +pci:v00001002d00006742sv00001002sd00006570* + ID_MODEL_FROM_DATABASE=Turks [Radeon HD 6570] + +pci:v00001002d00006742sv00001019sd00002393* + ID_MODEL_FROM_DATABASE=Radeon HD 6610M + pci:v00001002d00006742sv00001043sd00001D82* ID_MODEL_FROM_DATABASE=K53SK Laptop Radeon HD 7610M +pci:v00001002d00006742sv00001179sd0000FB22* + ID_MODEL_FROM_DATABASE=Radeon HD 7610M + +pci:v00001002d00006742sv00001179sd0000FB23* + ID_MODEL_FROM_DATABASE=Radeon HD 7610M + +pci:v00001002d00006742sv00001179sd0000FB27* + ID_MODEL_FROM_DATABASE=Radeon HD 7610M + +pci:v00001002d00006742sv00001179sd0000FB2A* + ID_MODEL_FROM_DATABASE=Radeon HD 7610M + +pci:v00001002d00006742sv00001179sd0000FB2C* + ID_MODEL_FROM_DATABASE=Radeon HD 7610M + +pci:v00001002d00006742sv00001179sd0000FB30* + ID_MODEL_FROM_DATABASE=Radeon HD 7610M + +pci:v00001002d00006742sv00001179sd0000FB31* + ID_MODEL_FROM_DATABASE=Radeon HD 7610M + +pci:v00001002d00006742sv00001179sd0000FB32* + ID_MODEL_FROM_DATABASE=Radeon HD 7610M + +pci:v00001002d00006742sv00001179sd0000FB38* + ID_MODEL_FROM_DATABASE=Radeon HD 7610M + +pci:v00001002d00006742sv00001179sd0000FB39* + ID_MODEL_FROM_DATABASE=Radeon HD 7610M + +pci:v00001002d00006742sv00001179sd0000FB3A* + ID_MODEL_FROM_DATABASE=Radeon HD 7610M + +pci:v00001002d00006742sv00001179sd0000FB3B* + ID_MODEL_FROM_DATABASE=Radeon HD 7610M + +pci:v00001002d00006742sv00001179sd0000FB40* + ID_MODEL_FROM_DATABASE=Radeon HD 7610M + +pci:v00001002d00006742sv00001179sd0000FB41* + ID_MODEL_FROM_DATABASE=Radeon HD 7610M + +pci:v00001002d00006742sv00001179sd0000FB47* + ID_MODEL_FROM_DATABASE=Radeon HD 7610M + +pci:v00001002d00006742sv00001179sd0000FB48* + ID_MODEL_FROM_DATABASE=Radeon HD 7610M + +pci:v00001002d00006742sv00001179sd0000FB49* + ID_MODEL_FROM_DATABASE=Radeon HD 7610M + +pci:v00001002d00006742sv00001179sd0000FB51* + ID_MODEL_FROM_DATABASE=Radeon HD 7610M + +pci:v00001002d00006742sv00001179sd0000FB52* + ID_MODEL_FROM_DATABASE=Radeon HD 7610M + +pci:v00001002d00006742sv00001179sd0000FB53* + ID_MODEL_FROM_DATABASE=Radeon HD 7610M + +pci:v00001002d00006742sv00001179sd0000FB56* + ID_MODEL_FROM_DATABASE=Radeon HD 7610M + +pci:v00001002d00006742sv00001179sd0000FB81* + ID_MODEL_FROM_DATABASE=Radeon HD 7610M + +pci:v00001002d00006742sv00001179sd0000FB82* + ID_MODEL_FROM_DATABASE=Radeon HD 7610M + +pci:v00001002d00006742sv00001179sd0000FB83* + ID_MODEL_FROM_DATABASE=Radeon HD 7610M + +pci:v00001002d00006742sv00001179sd0000FC56* + ID_MODEL_FROM_DATABASE=Radeon HD 7610M + +pci:v00001002d00006742sv00001179sd0000FCD4* + ID_MODEL_FROM_DATABASE=Radeon HD 7610M + +pci:v00001002d00006742sv00001179sd0000FCEE* + ID_MODEL_FROM_DATABASE=Radeon HD 7610M + +pci:v00001002d00006742sv00001458sd00006570* + ID_MODEL_FROM_DATABASE=Turks [Radeon HD 6570] + +pci:v00001002d00006742sv00001462sd00006570* + ID_MODEL_FROM_DATABASE=Turks [Radeon HD 6570] + +pci:v00001002d00006742sv0000148Csd00006570* + ID_MODEL_FROM_DATABASE=Turks [Radeon HD 6570] + +pci:v00001002d00006742sv00001682sd00006570* + ID_MODEL_FROM_DATABASE=Turks [Radeon HD 6570] + +pci:v00001002d00006742sv0000174Bsd00006570* + ID_MODEL_FROM_DATABASE=Turks [Radeon HD 6570] + +pci:v00001002d00006742sv00001787sd00006570* + ID_MODEL_FROM_DATABASE=Turks [Radeon HD 6570] + +pci:v00001002d00006742sv000017AFsd00006570* + ID_MODEL_FROM_DATABASE=Turks [Radeon HD 6570] + pci:v00001002d00006742sv00008086sd00002111* ID_MODEL_FROM_DATABASE=Radeon HD 6625M @@ -4278,38 +4815,155 @@ pci:v00001002d0000674A* ID_MODEL_FROM_DATABASE=Turks GL [FirePro V3900] pci:v00001002d00006750* - ID_MODEL_FROM_DATABASE=Onega [Radeon HD 6650A / 7650A] + ID_MODEL_FROM_DATABASE=Onega [Radeon HD 6650A/7650A] + +pci:v00001002d00006750sv00001462sd00002670* + ID_MODEL_FROM_DATABASE=Radeon HD 6670A + +pci:v00001002d00006750sv000017AAsd00003079* + ID_MODEL_FROM_DATABASE=Radeon HD 7650A + +pci:v00001002d00006750sv000017AAsd0000307A* + ID_MODEL_FROM_DATABASE=Radeon HD 6650A + +pci:v00001002d00006750sv000017AAsd00003087* + ID_MODEL_FROM_DATABASE=Radeon HD 7650A + +pci:v00001002d00006750sv000017AAsd00003618* + ID_MODEL_FROM_DATABASE=Radeon HD 6650A + +pci:v00001002d00006750sv000017AAsd00003623* + ID_MODEL_FROM_DATABASE=Radeon HD 6650A + +pci:v00001002d00006750sv000017AAsd00003627* + ID_MODEL_FROM_DATABASE=Radeon HD 6650A pci:v00001002d00006751* - ID_MODEL_FROM_DATABASE=Turks XT [Radeon HD 7670A] + ID_MODEL_FROM_DATABASE=Turks [Radeon HD 7650A/7670A] + +pci:v00001002d00006751sv00001028sd00000548* + ID_MODEL_FROM_DATABASE=Radeon HD 7650A + +pci:v00001002d00006751sv00001462sd00002671* + ID_MODEL_FROM_DATABASE=Radeon HD 7670A + +pci:v00001002d00006751sv00001462sd00002672* + ID_MODEL_FROM_DATABASE=Radeon HD 7670A + +pci:v00001002d00006751sv00001462sd00002680* + ID_MODEL_FROM_DATABASE=Radeon HD 7650A + +pci:v00001002d00006751sv00001462sd00002681* + ID_MODEL_FROM_DATABASE=Radeon HD 7650A + +pci:v00001002d00006751sv000017AAsd00003087* + ID_MODEL_FROM_DATABASE=Radeon HD 7650A pci:v00001002d00006758* - ID_MODEL_FROM_DATABASE=Turks XT [Radeon HD 6670] + ID_MODEL_FROM_DATABASE=Turks XT [Radeon HD 6670/7670] + +pci:v00001002d00006758sv00001028sd00000B0E* + ID_MODEL_FROM_DATABASE=Radeon HD 6670 + +pci:v00001002d00006758sv0000103Csd00006882* + ID_MODEL_FROM_DATABASE=Radeon HD 6670 + +pci:v00001002d00006758sv00001462sd0000250A* + ID_MODEL_FROM_DATABASE=Radeon HD 7670 + +pci:v00001002d00006758sv0000148Csd00007670* + ID_MODEL_FROM_DATABASE=Radeon HD 7670 + +pci:v00001002d00006758sv00001545sd00007670* + ID_MODEL_FROM_DATABASE=Radeon HD 7670 + +pci:v00001002d00006758sv00001682sd00003300* + ID_MODEL_FROM_DATABASE=Radeon HD 7670 + +pci:v00001002d00006758sv0000174Bsd00007670* + ID_MODEL_FROM_DATABASE=Radeon HD 7670 + +pci:v00001002d00006758sv0000174Bsd0000E181* + ID_MODEL_FROM_DATABASE=Radeon HD 6670 pci:v00001002d00006759* - ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570] + ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570] + +pci:v00001002d00006759sv0000103Csd00003130* + ID_MODEL_FROM_DATABASE=Radeon HD 6570 + +pci:v00001002d00006759sv00001462sd00002500* + ID_MODEL_FROM_DATABASE=Radeon HD 6570 + +pci:v00001002d00006759sv00001462sd00002509* + ID_MODEL_FROM_DATABASE=Radeon HD 7570 pci:v00001002d00006759sv0000148Csd00007570* ID_MODEL_FROM_DATABASE=Radeon HD 7570 +pci:v00001002d00006759sv00001642sd00003A67* + ID_MODEL_FROM_DATABASE=Radeon HD 6570 + +pci:v00001002d00006759sv00001682sd00003280* + ID_MODEL_FROM_DATABASE=Radeon HD 7570 + pci:v00001002d00006759sv0000174Bsd00007570* ID_MODEL_FROM_DATABASE=Radeon HD 7570 +pci:v00001002d00006759sv0000174Bsd0000E142* + ID_MODEL_FROM_DATABASE=Radeon HD 6570 + +pci:v00001002d00006759sv0000174Bsd0000E181* + ID_MODEL_FROM_DATABASE=Radeon HD 6570 + +pci:v00001002d00006759sv00001B0Asd0000908F* + ID_MODEL_FROM_DATABASE=Radeon HD 6570 + +pci:v00001002d00006759sv00001B0Asd00009090* + ID_MODEL_FROM_DATABASE=Radeon HD 6570 + +pci:v00001002d00006759sv00001B0Asd00009091* + ID_MODEL_FROM_DATABASE=Radeon HD 6570 + +pci:v00001002d00006759sv00001B0Asd00009092* + ID_MODEL_FROM_DATABASE=Radeon HD 6570 + +pci:v00001002d00006759sv00001B0Asd0000909E* + ID_MODEL_FROM_DATABASE=Radeon HD 6570 + +pci:v00001002d00006759sv00001B0Asd000090B5* + ID_MODEL_FROM_DATABASE=Radeon HD 7570 + +pci:v00001002d00006759sv00001B0Asd000090B6* + ID_MODEL_FROM_DATABASE=Radeon HD 7570 + pci:v00001002d0000675D* ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 7570] pci:v00001002d0000675F* - ID_MODEL_FROM_DATABASE=Turks LE [Radeon HD 5570/6510/7510] + ID_MODEL_FROM_DATABASE=Turks LE [Radeon HD 5570/6510/7510/8510] pci:v00001002d0000675Fsv0000148Csd00006510* ID_MODEL_FROM_DATABASE=Radeon HD 6510 +pci:v00001002d0000675Fsv0000148Csd00006530* + ID_MODEL_FROM_DATABASE=Radeon HD 6530 + +pci:v00001002d0000675Fsv0000148Csd00007510* + ID_MODEL_FROM_DATABASE=Radeon HD 7510 + +pci:v00001002d0000675Fsv00001545sd00007570* + ID_MODEL_FROM_DATABASE=Radeon HD 7570 + pci:v00001002d0000675Fsv0000174Bsd00006510* ID_MODEL_FROM_DATABASE=Radeon HD 6510 pci:v00001002d0000675Fsv0000174Bsd00007510* ID_MODEL_FROM_DATABASE=Radeon HD 7510 +pci:v00001002d0000675Fsv0000174Bsd00008510* + ID_MODEL_FROM_DATABASE=Radeon HD 8510 + pci:v00001002d0000675Fsv00001787sd00002012* ID_MODEL_FROM_DATABASE=Radeon HD 5570 2GB GDDR3 @@ -4319,11 +4973,497 @@ pci:v00001002d0000675Fsv00001787sd00002314* pci:v00001002d00006760* ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] +pci:v00001002d00006760sv00001002sd00000124* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001002sd00000134* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001019sd0000238B* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001019sd0000238E* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001019sd00002390* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001019sd00009985* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001028sd000004C1* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001028sd000004C3* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001028sd000004CA* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001028sd000004CB* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + pci:v00001002d00006760sv00001028sd000004CC* ID_MODEL_FROM_DATABASE=Vostro 3350 +pci:v00001002d00006760sv00001028sd000004D1* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001028sd000004D3* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001028sd000004D7* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001028sd00000502* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001028sd00000503* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001028sd00000506* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001028sd00000507* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001028sd00000514* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001028sd0000051C* + ID_MODEL_FROM_DATABASE=Radeon HD 6450M + +pci:v00001002d00006760sv00001028sd0000051D* + ID_MODEL_FROM_DATABASE=Radeon HD 6450M + +pci:v00001002d00006760sv0000103Csd0000161A* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd0000161B* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd0000161E* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd0000161F* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd00001622* + ID_MODEL_FROM_DATABASE=Radeon HD 6450M + +pci:v00001002d00006760sv0000103Csd00001623* + ID_MODEL_FROM_DATABASE=Radeon HD 6450M + +pci:v00001002d00006760sv0000103Csd0000164A* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd0000164D* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd00001651* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd00001656* + ID_MODEL_FROM_DATABASE=Radeon HD 6490M + +pci:v00001002d00006760sv0000103Csd00001658* + ID_MODEL_FROM_DATABASE=Radeon HD 6490M + +pci:v00001002d00006760sv0000103Csd00001659* + ID_MODEL_FROM_DATABASE=Radeon HD 6490M + +pci:v00001002d00006760sv0000103Csd0000165B* + ID_MODEL_FROM_DATABASE=Radeon HD 6490M + +pci:v00001002d00006760sv0000103Csd0000165D* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd0000165F* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd00001661* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd00001663* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd00001665* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd00001667* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd00001669* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd0000166B* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd0000166C* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd0000166E* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd00001670* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd00001672* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd0000167A* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd0000167B* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd0000167D* + ID_MODEL_FROM_DATABASE=Radeon HD 6490M + +pci:v00001002d00006760sv0000103Csd0000167F* + ID_MODEL_FROM_DATABASE=Radeon HD 6490M + +pci:v00001002d00006760sv0000103Csd0000168C* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd0000168F* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd00001694* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd00001696* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd00001698* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd0000169A* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd0000169C* + ID_MODEL_FROM_DATABASE=Radeon HD 6490M + +pci:v00001002d00006760sv0000103Csd00001855* + ID_MODEL_FROM_DATABASE=Radeon HD 7450M + +pci:v00001002d00006760sv0000103Csd00001859* + ID_MODEL_FROM_DATABASE=Radeon HD 7450M + +pci:v00001002d00006760sv0000103Csd0000185C* + ID_MODEL_FROM_DATABASE=Radeon HD 7450M + +pci:v00001002d00006760sv0000103Csd0000185D* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv0000103Csd0000185F* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv0000103Csd00001863* + ID_MODEL_FROM_DATABASE=Radeon HD 7450M + +pci:v00001002d00006760sv0000103Csd0000355C* + ID_MODEL_FROM_DATABASE=Radeon HD 6490M + +pci:v00001002d00006760sv0000103Csd0000355F* + ID_MODEL_FROM_DATABASE=Radeon HD 6490M + +pci:v00001002d00006760sv0000103Csd00003563* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd00003565* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd00003567* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd00003569* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd00003581* + ID_MODEL_FROM_DATABASE=Radeon HD 6490M + +pci:v00001002d00006760sv0000103Csd00003584* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd0000358C* + ID_MODEL_FROM_DATABASE=Radeon HD 6490M + +pci:v00001002d00006760sv0000103Csd0000358F* + ID_MODEL_FROM_DATABASE=Radeon HD 6490M + +pci:v00001002d00006760sv0000103Csd00003592* + ID_MODEL_FROM_DATABASE=Radeon HD 6490M + +pci:v00001002d00006760sv0000103Csd00003596* + ID_MODEL_FROM_DATABASE=Radeon HD 6490M + +pci:v00001002d00006760sv0000103Csd0000366B* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000103Csd00003671* + ID_MODEL_FROM_DATABASE=FirePro M3900 + +pci:v00001002d00006760sv0000103Csd00003673* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001043sd0000100A* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001043sd0000100C* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001043sd0000101B* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001043sd0000101C* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001043sd0000102A* + ID_MODEL_FROM_DATABASE=Radeon HD 7450M + +pci:v00001002d00006760sv00001043sd0000102C* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001043sd0000104B* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001043sd0000105D* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001043sd0000106B* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001043sd0000106D* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001043sd0000107D* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001043sd00001CB2* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001043sd00001D22* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001043sd00001D32* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001043sd00002001* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001043sd00002002* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001043sd00002107* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001043sd00002108* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001043sd00002109* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + pci:v00001002d00006760sv00001043sd000084A0* - ID_MODEL_FROM_DATABASE=Seymour XT [Radeon HD 6470M] + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001043sd000084E9* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001043sd00008515* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001043sd00008517* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001043sd0000855A* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv0000104Dsd0000907B* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000104Dsd00009081* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000104Dsd00009084* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000104Dsd00009085* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001179sd00000001* + ID_MODEL_FROM_DATABASE=Radeon HD 6450M + +pci:v00001002d00006760sv00001179sd00000003* + ID_MODEL_FROM_DATABASE=Radeon HD 6450M + +pci:v00001002d00006760sv00001179sd00000004* + ID_MODEL_FROM_DATABASE=Radeon HD 6450M + +pci:v00001002d00006760sv00001179sd0000FB22* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001179sd0000FB23* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001179sd0000FB2C* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001179sd0000FB31* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001179sd0000FB32* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001179sd0000FB33* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001179sd0000FB38* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001179sd0000FB39* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001179sd0000FB3A* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001179sd0000FB40* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001179sd0000FB41* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001179sd0000FB42* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001179sd0000FB47* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001179sd0000FB48* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001179sd0000FB51* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001179sd0000FB52* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001179sd0000FB53* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001179sd0000FB81* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001179sd0000FB82* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001179sd0000FB83* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001179sd0000FC51* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001179sd0000FC52* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001179sd0000FC56* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001179sd0000FCD3* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001179sd0000FCD4* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001179sd0000FCEE* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv00001179sd0000FDEE* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv0000144Dsd0000B074* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000144Dsd0000B084* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000144Dsd0000C095* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000144Dsd0000C0B3* + ID_MODEL_FROM_DATABASE=Radeon HD 6490M + +pci:v00001002d00006760sv0000144Dsd0000C538* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000144Dsd0000C581* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000144Dsd0000C589* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000144Dsd0000C609* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv0000144Dsd0000C625* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv0000144Dsd0000C636* + ID_MODEL_FROM_DATABASE=Radeon HD 7450M + +pci:v00001002d00006760sv00001462sd000010AC* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv0000152Dsd00000916* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv000017AAsd000021E5* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv000017AAsd00003900* + ID_MODEL_FROM_DATABASE=Radeon HD 7450M + +pci:v00001002d00006760sv000017AAsd00003902* + ID_MODEL_FROM_DATABASE=Radeon HD 7450M + +pci:v00001002d00006760sv000017AAsd00003969* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv000017AAsd00003970* + ID_MODEL_FROM_DATABASE=Radeon HD 7450M + +pci:v00001002d00006760sv000017AAsd00003976* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv000017AAsd0000397B* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv000017AAsd0000397D* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv000017AAsd00005101* + ID_MODEL_FROM_DATABASE=Radeon HD 7470M + +pci:v00001002d00006760sv000017AAsd00005102* + ID_MODEL_FROM_DATABASE=Radeon HD 7450M + +pci:v00001002d00006760sv000017AAsd00005103* + ID_MODEL_FROM_DATABASE=Radeon HD 7450M + +pci:v00001002d00006760sv000017AAsd00005106* + ID_MODEL_FROM_DATABASE=Radeon HD 7450M + +pci:v00001002d00006760sv00001854sd00000897* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001854sd00000900* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001854sd00000908* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M + +pci:v00001002d00006760sv00001854sd00002015* + ID_MODEL_FROM_DATABASE=Radeon HD 6470M pci:v00001002d00006761* ID_MODEL_FROM_DATABASE=Seymour LP [Radeon HD 6430M] @@ -4349,6 +5489,24 @@ pci:v00001002d00006768* pci:v00001002d00006770* ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450A/7450A] +pci:v00001002d00006770sv000017AAsd0000308D* + ID_MODEL_FROM_DATABASE=Radeon HD 7450A + +pci:v00001002d00006770sv000017AAsd00003623* + ID_MODEL_FROM_DATABASE=Radeon HD 6450A + +pci:v00001002d00006770sv000017AAsd00003627* + ID_MODEL_FROM_DATABASE=Radeon HD 6450A + +pci:v00001002d00006770sv000017AAsd00003629* + ID_MODEL_FROM_DATABASE=Radeon HD 6450A + +pci:v00001002d00006770sv000017AAsd0000363C* + ID_MODEL_FROM_DATABASE=Radeon HD 6450A + +pci:v00001002d00006770sv000017AAsd00003658* + ID_MODEL_FROM_DATABASE=Radeon HD 7470A + pci:v00001002d00006771* ID_MODEL_FROM_DATABASE=Caicos XTX [Radeon HD 8490] @@ -4356,26 +5514,134 @@ pci:v00001002d00006772* ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 7450A] pci:v00001002d00006778* - ID_MODEL_FROM_DATABASE=Caicos XT [Radeon HD 7470] + ID_MODEL_FROM_DATABASE=Caicos XT [Radeon HD 7470/8470] + +pci:v00001002d00006778sv00001019sd00000024* + ID_MODEL_FROM_DATABASE=Radeon HD 7470 + +pci:v00001002d00006778sv00001019sd00000027* + ID_MODEL_FROM_DATABASE=Radeon HD 8470 + +pci:v00001002d00006778sv00001028sd00002120* + ID_MODEL_FROM_DATABASE=Radeon HD 7470 + +pci:v00001002d00006778sv00001462sd0000B491* + ID_MODEL_FROM_DATABASE=Radeon HD 8470 + +pci:v00001002d00006778sv00001462sd0000B492* + ID_MODEL_FROM_DATABASE=Radeon HD 8470 pci:v00001002d00006778sv00001462sd0000B493* ID_MODEL_FROM_DATABASE=Radeon HD 8470 OEM +pci:v00001002d00006778sv00001642sd00003C65* + ID_MODEL_FROM_DATABASE=Radeon HD 8470 + +pci:v00001002d00006778sv00001642sd00003C75* + ID_MODEL_FROM_DATABASE=Radeon HD 8470 + +pci:v00001002d00006778sv0000174Bsd00008145* + ID_MODEL_FROM_DATABASE=Radeon HD 8470 + +pci:v00001002d00006778sv0000174Bsd0000E145* + ID_MODEL_FROM_DATABASE=Radeon HD 7470 + pci:v00001002d00006779* - ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450] + ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450] + +pci:v00001002d00006779sv00001019sd00000016* + ID_MODEL_FROM_DATABASE=Radeon HD 6450 + +pci:v00001002d00006779sv00001019sd00000017* + ID_MODEL_FROM_DATABASE=Radeon HD 6450 + +pci:v00001002d00006779sv00001019sd00000018* + ID_MODEL_FROM_DATABASE=Radeon HD 6450 + +pci:v00001002d00006779sv00001028sd00002120* + ID_MODEL_FROM_DATABASE=Radeon HD 6450 + +pci:v00001002d00006779sv0000103Csd00002128* + ID_MODEL_FROM_DATABASE=Radeon HD 6450 + +pci:v00001002d00006779sv0000103Csd00002AEE* + ID_MODEL_FROM_DATABASE=Radeon HD 7450A + +pci:v00001002d00006779sv00001462sd00002346* + ID_MODEL_FROM_DATABASE=Radeon HD 7450 + +pci:v00001002d00006779sv00001462sd00002490* + ID_MODEL_FROM_DATABASE=Radeon HD 6450 + +pci:v00001002d00006779sv00001462sd00002494* + ID_MODEL_FROM_DATABASE=Radeon HD 6450 + +pci:v00001002d00006779sv00001462sd00002496* + ID_MODEL_FROM_DATABASE=Radeon HD 7450 + +pci:v00001002d00006779sv0000148Csd00007450* + ID_MODEL_FROM_DATABASE=Radeon HD 7450 pci:v00001002d00006779sv0000148Csd00008450* ID_MODEL_FROM_DATABASE=Radeon HD 8450 OEM +pci:v00001002d00006779sv00001545sd00007470* + ID_MODEL_FROM_DATABASE=Radeon HD 7470 + +pci:v00001002d00006779sv00001642sd00003A65* + ID_MODEL_FROM_DATABASE=Radeon HD 6450 + +pci:v00001002d00006779sv00001642sd00003A66* + ID_MODEL_FROM_DATABASE=Radeon HD 7450 + +pci:v00001002d00006779sv00001642sd00003A75* + ID_MODEL_FROM_DATABASE=Radeon HD 6450 + +pci:v00001002d00006779sv00001642sd00003A76* + ID_MODEL_FROM_DATABASE=Radeon HD 7450 + +pci:v00001002d00006779sv00001682sd00003200* + ID_MODEL_FROM_DATABASE=Radeon HD 7450 + pci:v00001002d00006779sv0000174Bsd00007450* ID_MODEL_FROM_DATABASE=Radeon HD 7450 +pci:v00001002d00006779sv0000174Bsd0000E127* + ID_MODEL_FROM_DATABASE=Radeon HD 6450 + +pci:v00001002d00006779sv0000174Bsd0000E153* + ID_MODEL_FROM_DATABASE=Radeon HD 6450 + pci:v00001002d00006779sv0000174Bsd0000E164* ID_MODEL_FROM_DATABASE=Radeon HD 6450 1 GB DDR3 +pci:v00001002d00006779sv0000174Bsd0000E180* + ID_MODEL_FROM_DATABASE=Radeon HD 6450 + +pci:v00001002d00006779sv0000174Bsd0000E201* + ID_MODEL_FROM_DATABASE=Radeon HD 6450 + pci:v00001002d00006779sv000017AFsd00008450* ID_MODEL_FROM_DATABASE=Radeon HD 8450 OEM +pci:v00001002d00006779sv00001B0Asd00009096* + ID_MODEL_FROM_DATABASE=Radeon HD 6450 + +pci:v00001002d00006779sv00001B0Asd00009097* + ID_MODEL_FROM_DATABASE=Radeon HD 6450 + +pci:v00001002d00006779sv00001B0Asd000090A8* + ID_MODEL_FROM_DATABASE=Radeon HD 6450A + +pci:v00001002d00006779sv00001B0Asd000090B1* + ID_MODEL_FROM_DATABASE=Radeon HD 6450 + +pci:v00001002d00006779sv00001B0Asd000090B3* + ID_MODEL_FROM_DATABASE=Radeon HD 7450A + +pci:v00001002d00006779sv00001B0Asd000090BB* + ID_MODEL_FROM_DATABASE=Radeon HD 7450A + pci:v00001002d0000677B* ID_MODEL_FROM_DATABASE=Caicos PRO [Radeon HD 7450] @@ -4418,6 +5684,9 @@ pci:v00001002d00006798* pci:v00001002d00006798sv00001002sd00003000* ID_MODEL_FROM_DATABASE=Tahiti XT2 [Radeon HD 7970 GHz Edition] +pci:v00001002d00006798sv00001002sd00004000* + ID_MODEL_FROM_DATABASE=Radeon HD 8970 OEM + pci:v00001002d00006798sv00001043sd0000041C* ID_MODEL_FROM_DATABASE=HD 7970 DirectCU II @@ -4481,12 +5750,42 @@ pci:v00001002d0000679Asv00001462sd00003000* pci:v00001002d0000679B* ID_MODEL_FROM_DATABASE=Malta [Radeon HD 7990] +pci:v00001002d0000679Bsv00001002sd00000B28* + ID_MODEL_FROM_DATABASE=Radeon HD 8990 OEM + +pci:v00001002d0000679Bsv00001002sd00000B2A* + ID_MODEL_FROM_DATABASE=Radeon HD 7990 + +pci:v00001002d0000679Bsv00001462sd00008036* + ID_MODEL_FROM_DATABASE=Radeon HD 8990 OEM + pci:v00001002d0000679E* ID_MODEL_FROM_DATABASE=Tahiti LE [Radeon HD 7870 XT] pci:v00001002d0000679F* ID_MODEL_FROM_DATABASE=Tahiti +pci:v00001002d000067A0* + ID_MODEL_FROM_DATABASE=Hawaii XT GL + +pci:v00001002d000067A1* + ID_MODEL_FROM_DATABASE=Hawaii GL + +pci:v00001002d000067A2* + ID_MODEL_FROM_DATABASE=Hawaii GL + +pci:v00001002d000067B0* + ID_MODEL_FROM_DATABASE=Hawaii XT [Radeon HD 8970] + +pci:v00001002d000067B1* + ID_MODEL_FROM_DATABASE=Hawaii PRO + +pci:v00001002d000067B9* + ID_MODEL_FROM_DATABASE=Vesuvius + +pci:v00001002d000067BE* + ID_MODEL_FROM_DATABASE=Hawaii LE + pci:v00001002d00006800* ID_MODEL_FROM_DATABASE=Wimbledon XT [Radeon HD 7970M] @@ -4542,26 +5841,32 @@ pci:v00001002d00006818* ID_MODEL_FROM_DATABASE=Pitcairn XT [Radeon HD 7870 GHz Edition] pci:v00001002d00006818sv00001002sd00000B05* - ID_MODEL_FROM_DATABASE=Pitcairn XT [Radeon HD 8870 OEM] + ID_MODEL_FROM_DATABASE=Radeon HD 8870 OEM + +pci:v00001002d00006818sv0000174Bsd00008B04* + ID_MODEL_FROM_DATABASE=Radeon HD 8860 pci:v00001002d00006819* ID_MODEL_FROM_DATABASE=Pitcairn PRO [Radeon HD 7850] pci:v00001002d00006819sv0000174Bsd0000E221* - ID_MODEL_FROM_DATABASE=Sapphire Radeon HD 7850 2 GB GDDR5 DVI-I/DVI-D/HDMI/DP + ID_MODEL_FROM_DATABASE=Radeon HD 7850 2GB GDDR5 DVI-I/DVI-D/HDMI/DP pci:v00001002d00006820* ID_MODEL_FROM_DATABASE=Venus XTX [Radeon HD 8800M Series] +pci:v00001002d00006820sv0000103Csd00001851* + ID_MODEL_FROM_DATABASE=Radeon HD 7750M + pci:v00001002d00006821* ID_MODEL_FROM_DATABASE=Venus XT [Radeon HD 8800M Series] +pci:v00001002d00006822* + ID_MODEL_FROM_DATABASE=Venus PRO + pci:v00001002d00006823* ID_MODEL_FROM_DATABASE=Venus PRO [Radeon HD 8800M Series] -pci:v00001002d00006824* - ID_MODEL_FROM_DATABASE=Chelsea [Radeon HD 7700M Series] - pci:v00001002d00006825* ID_MODEL_FROM_DATABASE=Heathrow XT [Radeon HD 7870M] @@ -4580,6 +5885,9 @@ pci:v00001002d00006828* pci:v00001002d00006829* ID_MODEL_FROM_DATABASE=Cape Verde +pci:v00001002d0000682A* + ID_MODEL_FROM_DATABASE=Venus PRO + pci:v00001002d0000682B* ID_MODEL_FROM_DATABASE=Venus LE [Radeon HD 8800M Series] @@ -4589,12 +5897,18 @@ pci:v00001002d0000682D* pci:v00001002d0000682F* ID_MODEL_FROM_DATABASE=Chelsea LP [Radeon HD 7730M] +pci:v00001002d0000682Fsv0000103Csd00001851* + ID_MODEL_FROM_DATABASE=Radeon HD 7750M + pci:v00001002d00006830* ID_MODEL_FROM_DATABASE=Cape Verde [Radeon HD 7800M Series] pci:v00001002d00006831* ID_MODEL_FROM_DATABASE=Cape Verde [AMD Radeon HD 7700M Series] +pci:v00001002d00006835* + ID_MODEL_FROM_DATABASE=Cape Verde PRX + pci:v00001002d00006837* ID_MODEL_FROM_DATABASE=Cape Verde LE [Radeon HD 7730] @@ -4626,23 +5940,332 @@ pci:v00001002d0000683F* ID_MODEL_FROM_DATABASE=Cape Verde PRO [Radeon HD 7750] pci:v00001002d00006840* - ID_MODEL_FROM_DATABASE=Thames XT [Radeon HD 7670M] + ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] + +pci:v00001002d00006840sv00001025sd0000050E* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001025sd0000050F* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001025sd00000513* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001025sd00000514* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001025sd0000056D* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001025sd0000059A* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001025sd0000059B* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001025sd0000059E* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001025sd00000600* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001025sd00000606* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001025sd00000696* + ID_MODEL_FROM_DATABASE=Radeon HD 7650M + +pci:v00001002d00006840sv00001025sd00000697* + ID_MODEL_FROM_DATABASE=Radeon HD 7650M + +pci:v00001002d00006840sv00001025sd00000698* + ID_MODEL_FROM_DATABASE=Radeon HD 7650M + +pci:v00001002d00006840sv00001025sd00000699* + ID_MODEL_FROM_DATABASE=Radeon HD 7650M + +pci:v00001002d00006840sv00001025sd00000757* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001028sd0000056A* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001028sd0000056E* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001028sd00000598* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001028sd0000059D* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001028sd000005A3* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001028sd000005B9* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001028sd000005BB* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv0000103Csd000017F1* + ID_MODEL_FROM_DATABASE=Radeon HD 7570M + +pci:v00001002d00006840sv0000103Csd000017F4* + ID_MODEL_FROM_DATABASE=Radeon HD 7650M + +pci:v00001002d00006840sv0000103Csd00001813* + ID_MODEL_FROM_DATABASE=Radeon HD 7590M + +pci:v00001002d00006840sv0000103Csd0000182F* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv0000103Csd00001830* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv0000103Csd00001835* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv0000103Csd0000183A* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv0000103Csd0000183C* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv0000103Csd0000183E* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv0000103Csd00001840* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv0000103Csd00001842* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv0000103Csd00001844* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv0000103Csd00001848* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv0000103Csd0000184A* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv0000103Csd0000184C* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv0000103Csd00001895* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv0000103Csd00001897* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv0000103Csd000018A5* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv0000103Csd000018A7* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv0000103Csd000018F4* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001043sd0000100A* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001043sd0000104B* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001043sd000010DC* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001043sd00002121* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001043sd00002122* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001043sd00002123* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001043sd00002125* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001043sd00002127* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001179sd0000FB11* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001179sd0000FB22* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001179sd0000FB23* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001179sd0000FB2C* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001179sd0000FB31* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001179sd0000FB32* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001179sd0000FB38* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001179sd0000FB39* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001179sd0000FB3A* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001179sd0000FB40* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001179sd0000FB41* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001179sd0000FB47* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001179sd0000FB48* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001179sd0000FB51* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001179sd0000FB52* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001179sd0000FB53* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001179sd0000FB81* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001179sd0000FB82* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001179sd0000FB83* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001179sd0000FC56* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001179sd0000FCD4* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv00001179sd0000FCEE* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv0000144Dsd0000C0C5* + ID_MODEL_FROM_DATABASE=Radeon HD 7690M + +pci:v00001002d00006840sv0000144Dsd0000C0CE* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv0000144Dsd0000C0DA* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv000017AAsd00003970* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv000017AAsd0000397B* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv000017AAsd00005101* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv000017AAsd00005102* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M + +pci:v00001002d00006840sv000017AAsd00005103* + ID_MODEL_FROM_DATABASE=Radeon HD 7670M pci:v00001002d00006841* ID_MODEL_FROM_DATABASE=Thames [Radeon 7550M/7570M/7650M] +pci:v00001002d00006841sv00001028sd00000561* + ID_MODEL_FROM_DATABASE=Radeon HD 7650M + +pci:v00001002d00006841sv00001028sd0000056C* + ID_MODEL_FROM_DATABASE=Radeon HD 7650M + +pci:v00001002d00006841sv00001028sd0000057F* + ID_MODEL_FROM_DATABASE=Radeon HD 7570M + +pci:v00001002d00006841sv0000103Csd000017F1* + ID_MODEL_FROM_DATABASE=Radeon HD 7570M + +pci:v00001002d00006841sv0000103Csd000017F4* + ID_MODEL_FROM_DATABASE=Radeon HD 7650M + +pci:v00001002d00006841sv0000103Csd00001813* + ID_MODEL_FROM_DATABASE=Radeon HD 7570M + +pci:v00001002d00006841sv0000103Csd0000183A* + ID_MODEL_FROM_DATABASE=Radeon HD 7650M + +pci:v00001002d00006841sv0000103Csd0000183C* + ID_MODEL_FROM_DATABASE=Radeon HD 7650M + +pci:v00001002d00006841sv0000103Csd0000183E* + ID_MODEL_FROM_DATABASE=Radeon HD 7650M + +pci:v00001002d00006841sv0000103Csd00001840* + ID_MODEL_FROM_DATABASE=Radeon HD 7650M + +pci:v00001002d00006841sv0000103Csd00001842* + ID_MODEL_FROM_DATABASE=Radeon HD 7650M + +pci:v00001002d00006841sv0000103Csd00001844* + ID_MODEL_FROM_DATABASE=Radeon HD 7650M + +pci:v00001002d00006841sv00001043sd0000100A* + ID_MODEL_FROM_DATABASE=Radeon HD 7650M + +pci:v00001002d00006841sv00001043sd0000104B* + ID_MODEL_FROM_DATABASE=Radeon HD 7650M + +pci:v00001002d00006841sv00001043sd000010DC* + ID_MODEL_FROM_DATABASE=Radeon HD 7650M + +pci:v00001002d00006841sv00001043sd00002134* + ID_MODEL_FROM_DATABASE=Radeon HD 7650M + +pci:v00001002d00006841sv00001179sd00000001* + ID_MODEL_FROM_DATABASE=Radeon HD 7570M + +pci:v00001002d00006841sv00001179sd00000002* + ID_MODEL_FROM_DATABASE=Radeon HD 7570M + +pci:v00001002d00006841sv00001179sd0000FB43* + ID_MODEL_FROM_DATABASE=Radeon HD 7550M + +pci:v00001002d00006841sv00001179sd0000FB91* + ID_MODEL_FROM_DATABASE=Radeon HD 7550M + +pci:v00001002d00006841sv00001179sd0000FB92* + ID_MODEL_FROM_DATABASE=Radeon HD 7550M + +pci:v00001002d00006841sv00001179sd0000FB93* + ID_MODEL_FROM_DATABASE=Radeon HD 7550M + +pci:v00001002d00006841sv00001179sd0000FBA2* + ID_MODEL_FROM_DATABASE=Radeon HD 7550M + +pci:v00001002d00006841sv00001179sd0000FBA3* + ID_MODEL_FROM_DATABASE=Radeon HD 7550M + +pci:v00001002d00006841sv0000144Dsd0000C0C7* + ID_MODEL_FROM_DATABASE=Radeon HD 7550M + pci:v00001002d00006842* ID_MODEL_FROM_DATABASE=Thames LE [Radeon HD 7000M Series] pci:v00001002d00006843* ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7670M] -pci:v00001002d00006849* - ID_MODEL_FROM_DATABASE=Lombok [AMD Radeon HD 7400 Series] - -pci:v00001002d00006880* - ID_MODEL_FROM_DATABASE=Cypress - pci:v00001002d00006888* ID_MODEL_FROM_DATABASE=Cypress XT [FirePro V8800] @@ -4724,9 +6347,66 @@ pci:v00001002d000068A1sv0000106Bsd000000CC* pci:v00001002d000068A8* ID_MODEL_FROM_DATABASE=Granville [Radeon HD 6850M/6870M] +pci:v00001002d000068A8sv00001025sd00000442* + ID_MODEL_FROM_DATABASE=Radeon HD 6850M + +pci:v00001002d000068A8sv00001025sd00000451* + ID_MODEL_FROM_DATABASE=Radeon HD 6850M + +pci:v00001002d000068A8sv00001025sd0000050A* + ID_MODEL_FROM_DATABASE=Radeon HD 6850M + +pci:v00001002d000068A8sv00001025sd0000050B* + ID_MODEL_FROM_DATABASE=Radeon HD 6850M + +pci:v00001002d000068A8sv00001025sd0000050C* + ID_MODEL_FROM_DATABASE=Radeon HD 6850M + +pci:v00001002d000068A8sv00001025sd0000050E* + ID_MODEL_FROM_DATABASE=Radeon HD 6850M + +pci:v00001002d000068A8sv00001025sd0000050F* + ID_MODEL_FROM_DATABASE=Radeon HD 6850M + +pci:v00001002d000068A8sv00001025sd00000513* + ID_MODEL_FROM_DATABASE=Radeon HD 6850M + +pci:v00001002d000068A8sv00001025sd00000514* + ID_MODEL_FROM_DATABASE=Radeon HD 6850M + +pci:v00001002d000068A8sv00001025sd00000515* + ID_MODEL_FROM_DATABASE=Radeon HD 6850M + +pci:v00001002d000068A8sv00001025sd00000516* + ID_MODEL_FROM_DATABASE=Radeon HD 6850M + +pci:v00001002d000068A8sv00001025sd00000525* + ID_MODEL_FROM_DATABASE=Radeon HD 6850M + +pci:v00001002d000068A8sv00001025sd00000526* + ID_MODEL_FROM_DATABASE=Radeon HD 6850M + +pci:v00001002d000068A8sv00001025sd0000056D* + ID_MODEL_FROM_DATABASE=Radeon HD 6850M + +pci:v00001002d000068A8sv00001028sd0000048F* + ID_MODEL_FROM_DATABASE=Radeon HD 6870M + +pci:v00001002d000068A8sv00001028sd00000490* + ID_MODEL_FROM_DATABASE=Radeon HD 6870M + +pci:v00001002d000068A8sv00001028sd000004B9* + ID_MODEL_FROM_DATABASE=Radeon HD 6870M + +pci:v00001002d000068A8sv00001028sd000004BA* + ID_MODEL_FROM_DATABASE=Radeon HD 6870M + pci:v00001002d000068A8sv0000103Csd0000159B* ID_MODEL_FROM_DATABASE=Radeon HD 6850M +pci:v00001002d000068A8sv0000144Dsd0000C0AD* + ID_MODEL_FROM_DATABASE=Radeon HD 6850M + pci:v00001002d000068A9* ID_MODEL_FROM_DATABASE=Juniper XT [FirePro V5800] @@ -4757,6 +6437,21 @@ pci:v00001002d000068BFsv0000174Bsd00006750* pci:v00001002d000068C0* ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5730 / 6570M] +pci:v00001002d000068C0sv00001019sd00002383* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5730 + +pci:v00001002d000068C0sv00001028sd000002A2* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5730 + +pci:v00001002d000068C0sv00001028sd000002FE* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5730 + +pci:v00001002d000068C0sv00001028sd00000419* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5730 + +pci:v00001002d000068C0sv0000103Csd0000147D* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5730 + pci:v00001002d000068C0sv0000103Csd00001521* ID_MODEL_FROM_DATABASE=Madison XT [FirePro M5800] @@ -4769,21 +6464,429 @@ pci:v00001002d000068C0sv0000103Csd00001596* pci:v00001002d000068C0sv0000103Csd00001599* ID_MODEL_FROM_DATABASE=Mobility Radeon HD 6570 +pci:v00001002d000068C0sv00001043sd00001C22* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5730 + +pci:v00001002d000068C0sv000017AAsd00003927* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5730 + +pci:v00001002d000068C0sv000017AAsd00003952* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5730 + +pci:v00001002d000068C0sv000017AAsd00003978* + ID_MODEL_FROM_DATABASE=Radeon HD 6570M + pci:v00001002d000068C1* - ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6550M] + ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] + +pci:v00001002d000068C1sv00001025sd00000205* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000293* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000294* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000296* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000308* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd0000030A* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000311* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000312* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd0000031C* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd0000031D* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 pci:v00001002d000068C1sv00001025sd0000033D* ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 +pci:v00001002d000068C1sv00001025sd0000033E* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd0000033F* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000346* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + pci:v00001002d000068C1sv00001025sd00000347* ID_MODEL_FROM_DATABASE=Aspire 7740G +pci:v00001002d000068C1sv00001025sd00000348* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000356* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000357* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000358* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000359* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd0000035A* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd0000035B* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd0000035C* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd0000035D* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd0000035E* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000360* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000362* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000364* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000365* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000366* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000367* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000368* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd0000036C* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd0000036D* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd0000036E* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd0000036F* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000372* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000373* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000377* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000378* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000379* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd0000037A* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd0000037B* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd0000037E* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd0000037F* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000382* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000383* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000384* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000385* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000386* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000387* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000388* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd0000038B* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd0000038C* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd0000039A* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000411* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000412* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000418* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000419* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000420* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000421* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000425* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd0000042A* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd0000042E* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd0000042F* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000432* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000433* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000442* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd0000044C* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd0000044E* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000451* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000454* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000455* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000475* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000476* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000487* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000489* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000498* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000517* + ID_MODEL_FROM_DATABASE=Radeon HD 6550M + +pci:v00001002d000068C1sv00001025sd0000051A* + ID_MODEL_FROM_DATABASE=Radeon HD 6550M + +pci:v00001002d000068C1sv00001025sd0000051B* + ID_MODEL_FROM_DATABASE=Radeon HD 6550M + +pci:v00001002d000068C1sv00001025sd0000051C* + ID_MODEL_FROM_DATABASE=Radeon HD 6550M + +pci:v00001002d000068C1sv00001025sd0000051D* + ID_MODEL_FROM_DATABASE=Radeon HD 6550M + +pci:v00001002d000068C1sv00001025sd00000525* + ID_MODEL_FROM_DATABASE=Radeon HD 6550M + +pci:v00001002d000068C1sv00001025sd00000526* + ID_MODEL_FROM_DATABASE=Radeon HD 6550M + +pci:v00001002d000068C1sv00001025sd0000052B* + ID_MODEL_FROM_DATABASE=Radeon HD 6550M + +pci:v00001002d000068C1sv00001025sd0000052C* + ID_MODEL_FROM_DATABASE=Radeon HD 6550M + +pci:v00001002d000068C1sv00001025sd0000053C* + ID_MODEL_FROM_DATABASE=Radeon HD 6550M + +pci:v00001002d000068C1sv00001025sd0000053D* + ID_MODEL_FROM_DATABASE=Radeon HD 6550M + +pci:v00001002d000068C1sv00001025sd0000053E* + ID_MODEL_FROM_DATABASE=Radeon HD 6550M + +pci:v00001002d000068C1sv00001025sd0000053F* + ID_MODEL_FROM_DATABASE=Radeon HD 6550M + +pci:v00001002d000068C1sv00001025sd00000607* + ID_MODEL_FROM_DATABASE=Radeon HD 6550M + +pci:v00001002d000068C1sv00001028sd0000041B* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001028sd00000447* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001028sd00000448* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001028sd00000456* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001028sd00000457* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv0000103Csd00001436* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv0000103Csd00001437* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv0000103Csd00001440* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv0000103Csd00001448* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv0000103Csd00001449* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv0000103Csd0000144A* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv0000103Csd0000144B* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv0000103Csd0000147B* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv0000103Csd0000149C* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv0000103Csd0000149E* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + pci:v00001002d000068C1sv0000103Csd00001521* ID_MODEL_FROM_DATABASE=Madison Pro [FirePro M5800] +pci:v00001002d000068C1sv00001043sd00001BC2* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv0000104Dsd00009071* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv0000104Dsd00009077* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv0000104Dsd00009081* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001179sd0000FD00* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001179sd0000FD12* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001179sd0000FD1A* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001179sd0000FD30* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001179sd0000FD31* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001179sd0000FD50* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001179sd0000FD52* + ID_MODEL_FROM_DATABASE=Radeon HD 6530M + +pci:v00001002d000068C1sv00001179sd0000FD63* + ID_MODEL_FROM_DATABASE=Radeon HD 6530M + +pci:v00001002d000068C1sv00001179sd0000FD65* + ID_MODEL_FROM_DATABASE=Radeon HD 6530M + +pci:v00001002d000068C1sv00001179sd0000FDD0* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001179sd0000FDD2* + ID_MODEL_FROM_DATABASE=Radeon HD 6530M + +pci:v00001002d000068C1sv0000144Dsd0000C07E* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv0000144Dsd0000C085* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv000014C0sd00000043* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv000014C0sd0000004D* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv000017AAsd00003928* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv000017AAsd00003951* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv000017AAsd00003977* + ID_MODEL_FROM_DATABASE=Radeon HD 6550M + pci:v00001002d000068C7* ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5570/6550A] +pci:v00001002d000068C7sv00001462sd00002241* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5570 + +pci:v00001002d000068C7sv00001462sd00002243* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5570 + +pci:v00001002d000068C7sv00001462sd00002244* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5570 + +pci:v00001002d000068C7sv00001462sd00002245* + ID_MODEL_FROM_DATABASE=Radeon HD 6550A + +pci:v00001002d000068C7sv00001462sd00002246* + ID_MODEL_FROM_DATABASE=Radeon HD 6550A + pci:v00001002d000068C8* ID_MODEL_FROM_DATABASE=Redwood XT GL [FirePro V4800] @@ -4791,13 +6894,46 @@ pci:v00001002d000068C9* ID_MODEL_FROM_DATABASE=Redwood PRO GL [FirePro V3800] pci:v00001002d000068D8* - ID_MODEL_FROM_DATABASE=Redwood XT [Radeon HD 5670] + ID_MODEL_FROM_DATABASE=Redwood XT [Radeon HD 5670/5690/5730] + +pci:v00001002d000068D8sv00001028sd000068E0* + ID_MODEL_FROM_DATABASE=Radeon HD 5670 + +pci:v00001002d000068D8sv0000174Bsd00005690* + ID_MODEL_FROM_DATABASE=Radeon HD 5690 + +pci:v00001002d000068D8sv0000174Bsd00005730* + ID_MODEL_FROM_DATABASE=Radeon HD 5730 + +pci:v00001002d000068D8sv0000174Bsd0000E151* + ID_MODEL_FROM_DATABASE=Radeon HD 5670 pci:v00001002d000068D8sv00001787sd00003000* ID_MODEL_FROM_DATABASE=Radeon HD 5730 +pci:v00001002d000068D8sv000017AFsd00003010* + ID_MODEL_FROM_DATABASE=Radeon HD 5730 + +pci:v00001002d000068D8sv000017AFsd00003011* + ID_MODEL_FROM_DATABASE=Radeon HD 5690 + pci:v00001002d000068D9* - ID_MODEL_FROM_DATABASE=Redwood PRO [Radeon HD 5570] + ID_MODEL_FROM_DATABASE=Redwood PRO [Radeon HD 5550/5570/5630/6510/6610/7570] + +pci:v00001002d000068D9sv0000103Csd00006870* + ID_MODEL_FROM_DATABASE=Radeon HD 5570 + +pci:v00001002d000068D9sv0000103Csd00006872* + ID_MODEL_FROM_DATABASE=Radeon HD 5570 + +pci:v00001002d000068D9sv00001043sd000003CE* + ID_MODEL_FROM_DATABASE=Radeon HD 5550 + +pci:v00001002d000068D9sv00001462sd00002151* + ID_MODEL_FROM_DATABASE=Radeon HD 5570 + +pci:v00001002d000068D9sv00001462sd00002240* + ID_MODEL_FROM_DATABASE=Radeon HD 5570 pci:v00001002d000068D9sv0000148Csd00003000* ID_MODEL_FROM_DATABASE=Radeon HD 6510 @@ -4805,8 +6941,41 @@ pci:v00001002d000068D9sv0000148Csd00003000* pci:v00001002d000068D9sv0000148Csd00003001* ID_MODEL_FROM_DATABASE=Radeon HD 6610 +pci:v00001002d000068D9sv00001545sd00005550* + ID_MODEL_FROM_DATABASE=Radeon HD 5550 + +pci:v00001002d000068D9sv00001545sd00007570* + ID_MODEL_FROM_DATABASE=Radeon HD 7570 + +pci:v00001002d000068D9sv00001642sd00003985* + ID_MODEL_FROM_DATABASE=Radeon HD 5570 + +pci:v00001002d000068D9sv00001642sd00003996* + ID_MODEL_FROM_DATABASE=Radeon HD 5570 + +pci:v00001002d000068D9sv0000174Bsd00003000* + ID_MODEL_FROM_DATABASE=Radeon HD 6510 + +pci:v00001002d000068D9sv0000174Bsd00006510* + ID_MODEL_FROM_DATABASE=Radeon HD 6510 + +pci:v00001002d000068D9sv0000174Bsd00006610* + ID_MODEL_FROM_DATABASE=Radeon HD 6610 + +pci:v00001002d000068D9sv0000174Bsd0000E142* + ID_MODEL_FROM_DATABASE=Radeon HD 5570 + +pci:v00001002d000068D9sv00001787sd00003000* + ID_MODEL_FROM_DATABASE=Radeon HD 6510 + +pci:v00001002d000068D9sv000017AFsd00003000* + ID_MODEL_FROM_DATABASE=Radeon HD 6510 + +pci:v00001002d000068D9sv000017AFsd00003010* + ID_MODEL_FROM_DATABASE=Radeon HD 5630 + pci:v00001002d000068DA* - ID_MODEL_FROM_DATABASE=Redwood LE [Radeon HD 5550] + ID_MODEL_FROM_DATABASE=Redwood LE [Radeon HD 5550/5570/5630/6390/6490/7570] pci:v00001002d000068DAsv0000148Csd00003000* ID_MODEL_FROM_DATABASE=Radeon HD 6390 @@ -4814,30 +6983,156 @@ pci:v00001002d000068DAsv0000148Csd00003000* pci:v00001002d000068DAsv0000148Csd00003001* ID_MODEL_FROM_DATABASE=Radeon HD 6490 +pci:v00001002d000068DAsv00001545sd00007570* + ID_MODEL_FROM_DATABASE=Radeon HD 7570 + +pci:v00001002d000068DAsv0000174Bsd00003000* + ID_MODEL_FROM_DATABASE=Radeon HD 6390 + +pci:v00001002d000068DAsv0000174Bsd00005570* + ID_MODEL_FROM_DATABASE=Radeon HD 5570 + +pci:v00001002d000068DAsv0000174Bsd00005630* + ID_MODEL_FROM_DATABASE=Radeon HD 5630 + +pci:v00001002d000068DAsv0000174Bsd00006490* + ID_MODEL_FROM_DATABASE=Radeon HD 6490 + +pci:v00001002d000068DAsv00001787sd00003000* + ID_MODEL_FROM_DATABASE=Radeon HD 5630 + +pci:v00001002d000068DAsv000017AFsd00003000* + ID_MODEL_FROM_DATABASE=Radeon HD 6390 + +pci:v00001002d000068DAsv000017AFsd00003010* + ID_MODEL_FROM_DATABASE=Radeon HD 5630 + pci:v00001002d000068DE* ID_MODEL_FROM_DATABASE=Redwood pci:v00001002d000068E0* ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430/5450/5470] +pci:v00001002d000068E0sv00001028sd00000404* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5450 + +pci:v00001002d000068E0sv00001028sd00000414* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5450 + +pci:v00001002d000068E0sv00001028sd00000434* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5450 + +pci:v00001002d000068E0sv0000103Csd00001433* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5450 + +pci:v00001002d000068E0sv0000103Csd00001434* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5450 + +pci:v00001002d000068E0sv0000103Csd00001469* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5450 + +pci:v00001002d000068E0sv0000103Csd0000146B* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5450 + pci:v00001002d000068E0sv0000103Csd00001486* ID_MODEL_FROM_DATABASE=TouchSmart tm2-2050er discrete GPU (Mobility Radeon HD 5450) +pci:v00001002d000068E0sv0000103Csd00001622* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5450 + +pci:v00001002d000068E0sv0000103Csd00001623* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5450 + +pci:v00001002d000068E0sv0000103Csd0000EEEE* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5450 + +pci:v00001002d000068E0sv0000104Dsd00009076* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5450 + +pci:v00001002d000068E0sv00001682sd0000304E* + ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 5450] + +pci:v00001002d000068E0sv00001682sd00006000* + ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 5450] + +pci:v00001002d000068E0sv000017AAsd00009E52* + ID_MODEL_FROM_DATABASE=FirePro M3800 + +pci:v00001002d000068E0sv000017AAsd00009E53* + ID_MODEL_FROM_DATABASE=FirePro M3800 + pci:v00001002d000068E1* ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430] +pci:v00001002d000068E1sv00001043sd0000041F* + ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 7350] + +pci:v00001002d000068E1sv00001043sd00003000* + ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 5450] + +pci:v00001002d000068E1sv0000148Csd00003000* + ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 5450] + +pci:v00001002d000068E1sv0000148Csd00003001* + ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6230] + +pci:v00001002d000068E1sv0000148Csd00003002* + ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6250] + +pci:v00001002d000068E1sv0000148Csd00003003* + ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6350] + pci:v00001002d000068E1sv0000148Csd00007350* ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 7350] +pci:v00001002d000068E1sv0000148Csd00008350* + ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 8350] + pci:v00001002d000068E1sv00001545sd00005450* ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 5450] +pci:v00001002d000068E1sv00001545sd00007350* + ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 7350] + +pci:v00001002d000068E1sv00001682sd00003000* + ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 5450] + +pci:v00001002d000068E1sv00001682sd00006000* + ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 5450] + +pci:v00001002d000068E1sv00001682sd00007350* + ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 7350] + +pci:v00001002d000068E1sv0000174Bsd00003000* + ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 5450] + pci:v00001002d000068E1sv0000174Bsd00005470* ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 5470] +pci:v00001002d000068E1sv0000174Bsd00006000* + ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 5450] + +pci:v00001002d000068E1sv0000174Bsd00006230* + ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6230] + pci:v00001002d000068E1sv0000174Bsd00006350* ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6350] +pci:v00001002d000068E1sv0000174Bsd00007350* + ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 7350] + +pci:v00001002d000068E1sv00001787sd00003000* + ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 5450] + +pci:v00001002d000068E1sv000017AFsd00003000* + ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 5450] + +pci:v00001002d000068E1sv000017AFsd00003001* + ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6230] + +pci:v00001002d000068E1sv000017AFsd00003014* + ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6350] + pci:v00001002d000068E1sv000017AFsd00003015* ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 7350] @@ -4847,11 +7142,221 @@ pci:v00001002d000068E1sv000017AFsd00008350* pci:v00001002d000068E4* ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] +pci:v00001002d000068E4sv00001019sd00002386* + ID_MODEL_FROM_DATABASE=Radeon HD 6350M + +pci:v00001002d000068E4sv00001019sd00002387* + ID_MODEL_FROM_DATABASE=Radeon HD 6350M + +pci:v00001002d000068E4sv00001019sd0000238D* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv00001019sd0000238E* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv00001025sd00000382* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv00001025sd00000489* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv00001025sd0000048A* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv00001025sd0000048B* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv00001025sd0000048C* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv00001028sd000004C1* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv00001028sd000004CA* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv00001028sd000004CC* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv00001028sd000004CD* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv00001028sd000004D7* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv0000103Csd00001411* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv0000103Csd00001421* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv0000103Csd00001426* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv0000103Csd00001428* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv0000103Csd0000142A* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv0000103Csd0000142B* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv0000103Csd0000143A* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv0000103Csd0000143C* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv0000103Csd00001445* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv0000103Csd0000162C* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv0000103Csd0000162D* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv0000103Csd0000162E* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv0000103Csd0000162F* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv0000103Csd00001639* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv0000103Csd0000163A* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv0000103Csd0000163B* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv0000103Csd0000163C* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv0000103Csd0000163D* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv0000103Csd0000163E* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv0000103Csd0000163F* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv0000103Csd00001641* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv0000103Csd00001643* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv0000103Csd00003578* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv0000103Csd0000357A* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv0000103Csd00003673* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv0000103Csd00003675* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv00001043sd00001C92* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv00001043sd000084A1* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv00001043sd000084AD* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv0000104Dsd00009081* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv00001545sd00007350* + ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350] + +pci:v00001002d000068E4sv00001558sd00004510* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv00001558sd00005505* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv0000174Bsd00005450* + ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5450] + +pci:v00001002d000068E4sv000017AAsd000021DD* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv000017AAsd000021E9* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv000017AAsd00003971* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M + +pci:v00001002d000068E4sv000017AAsd00003972* + ID_MODEL_FROM_DATABASE=Radeon HD 7370M + +pci:v00001002d000068E4sv000017AAsd0000397A* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M/7370M + +pci:v00001002d000068E4sv000017AAsd0000397B* + ID_MODEL_FROM_DATABASE=Radeon HD 6370M/7370M + +pci:v00001002d000068E4sv000017AAsd0000397F* + ID_MODEL_FROM_DATABASE=Radeon HD 7370M + pci:v00001002d000068E5* ID_MODEL_FROM_DATABASE=Robson LE [Radeon HD 6330M] +pci:v00001002d000068E5sv00001179sd0000FD3C* + ID_MODEL_FROM_DATABASE=Radeon HD 6330M + +pci:v00001002d000068E5sv00001179sd0000FD50* + ID_MODEL_FROM_DATABASE=Radeon HD 6330M + +pci:v00001002d000068E5sv00001179sd0000FD52* + ID_MODEL_FROM_DATABASE=Radeon HD 6330M + +pci:v00001002d000068E5sv00001179sd0000FD63* + ID_MODEL_FROM_DATABASE=Radeon HD 6330M + +pci:v00001002d000068E5sv00001179sd0000FD65* + ID_MODEL_FROM_DATABASE=Radeon HD 6330M + +pci:v00001002d000068E5sv00001179sd0000FD73* + ID_MODEL_FROM_DATABASE=Radeon HD 6330M + +pci:v00001002d000068E5sv00001179sd0000FD75* + ID_MODEL_FROM_DATABASE=Radeon HD 6330M + +pci:v00001002d000068E5sv00001179sd0000FDD0* + ID_MODEL_FROM_DATABASE=Radeon HD 6330M + +pci:v00001002d000068E5sv00001179sd0000FDD2* + ID_MODEL_FROM_DATABASE=Radeon HD 6330M + +pci:v00001002d000068E5sv00001179sd0000FDEA* + ID_MODEL_FROM_DATABASE=Radeon HD 6330M + +pci:v00001002d000068E5sv00001179sd0000FDF8* + ID_MODEL_FROM_DATABASE=Radeon HD 6330M + +pci:v00001002d000068E5sv0000148Csd00005450* + ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5450] + +pci:v00001002d000068E5sv0000148Csd00006350* + ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 6350] + pci:v00001002d000068E5sv0000148Csd00007350* - ID_MODEL_FROM_DATABASE=Radeon HD 7350 + ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350] + +pci:v00001002d000068E5sv0000148Csd00008350* + ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 8350] + +pci:v00001002d000068E5sv00001545sd00007350* + ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350] pci:v00001002d000068E8* ID_MODEL_FROM_DATABASE=Cedar @@ -4869,20 +7374,74 @@ pci:v00001002d000068F8* ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7300 Series] pci:v00001002d000068F9* - ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350 Series] + ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] pci:v00001002d000068F9sv00001019sd00000001* ID_MODEL_FROM_DATABASE=Radeon HD 5450 +pci:v00001002d000068F9sv00001019sd00000002* + ID_MODEL_FROM_DATABASE=Radeon HD 5450 + pci:v00001002d000068F9sv00001019sd00000019* ID_MODEL_FROM_DATABASE=Radeon HD 6350 +pci:v00001002d000068F9sv00001025sd00000518* + ID_MODEL_FROM_DATABASE=Radeon HD 5450 + +pci:v00001002d000068F9sv00001025sd00000519* + ID_MODEL_FROM_DATABASE=Radeon HD 5450 + pci:v00001002d000068F9sv00001028sd0000010E* ID_MODEL_FROM_DATABASE=XPS 8300 +pci:v00001002d000068F9sv00001028sd00002126* + ID_MODEL_FROM_DATABASE=Radeon HD 6350 + +pci:v00001002d000068F9sv0000103Csd00002126* + ID_MODEL_FROM_DATABASE=Radeon HD 6350 + +pci:v00001002d000068F9sv0000103Csd00002AAC* + ID_MODEL_FROM_DATABASE=Radeon HD 5450 + +pci:v00001002d000068F9sv0000103Csd00002AAE* + ID_MODEL_FROM_DATABASE=Radeon HD 5450 + +pci:v00001002d000068F9sv0000103Csd00003580* + ID_MODEL_FROM_DATABASE=Radeon HD 5450 + pci:v00001002d000068F9sv00001043sd000003C2* ID_MODEL_FROM_DATABASE=EAH5450 SILENT/DI/512MD2 (LP) +pci:v00001002d000068F9sv00001462sd00002130* + ID_MODEL_FROM_DATABASE=Radeon HD 5450 + +pci:v00001002d000068F9sv00001462sd00002131* + ID_MODEL_FROM_DATABASE=Radeon HD 5450 + +pci:v00001002d000068F9sv00001462sd00002133* + ID_MODEL_FROM_DATABASE=Radeon HD 6350 + +pci:v00001002d000068F9sv00001462sd00002180* + ID_MODEL_FROM_DATABASE=Radeon HD 5450 + +pci:v00001002d000068F9sv00001462sd00002181* + ID_MODEL_FROM_DATABASE=Radeon HD 5450 + +pci:v00001002d000068F9sv00001462sd00002182* + ID_MODEL_FROM_DATABASE=Radeon HD 6350 + +pci:v00001002d000068F9sv00001462sd00002183* + ID_MODEL_FROM_DATABASE=Radeon HD 6350 + +pci:v00001002d000068F9sv00001462sd00002230* + ID_MODEL_FROM_DATABASE=Radeon HD 5450 + +pci:v00001002d000068F9sv00001462sd00002231* + ID_MODEL_FROM_DATABASE=Radeon HD 5450 + +pci:v00001002d000068F9sv00001462sd00002495* + ID_MODEL_FROM_DATABASE=Radeon HD 6350 + pci:v00001002d000068F9sv0000148Csd00003001* ID_MODEL_FROM_DATABASE=Radeon HD 5530/6250 @@ -4898,6 +7457,39 @@ pci:v00001002d000068F9sv0000148Csd00003004* pci:v00001002d000068F9sv0000148Csd00007350* ID_MODEL_FROM_DATABASE=Radeon HD 7350 +pci:v00001002d000068F9sv0000148Csd00008350* + ID_MODEL_FROM_DATABASE=Radeon HD 8350 + +pci:v00001002d000068F9sv00001545sd00007350* + ID_MODEL_FROM_DATABASE=Radeon HD 7350 + +pci:v00001002d000068F9sv00001642sd00003983* + ID_MODEL_FROM_DATABASE=Radeon HD 5450 + +pci:v00001002d000068F9sv00001642sd00003984* + ID_MODEL_FROM_DATABASE=Radeon HD 6350 + +pci:v00001002d000068F9sv00001642sd00003987* + ID_MODEL_FROM_DATABASE=Radeon HD 6350 + +pci:v00001002d000068F9sv00001642sd00003997* + ID_MODEL_FROM_DATABASE=Radeon HD 5450 + +pci:v00001002d000068F9sv00001642sd00003A05* + ID_MODEL_FROM_DATABASE=Radeon HD 5450 + +pci:v00001002d000068F9sv00001642sd00003B31* + ID_MODEL_FROM_DATABASE=Radeon HD 6350A + +pci:v00001002d000068F9sv00001682sd00003270* + ID_MODEL_FROM_DATABASE=Radeon HD 7350 + +pci:v00001002d000068F9sv0000174Bsd00003000* + ID_MODEL_FROM_DATABASE=Radeon HD 6230 + +pci:v00001002d000068F9sv0000174Bsd00003987* + ID_MODEL_FROM_DATABASE=Radeon HD 6350 + pci:v00001002d000068F9sv0000174Bsd00005470* ID_MODEL_FROM_DATABASE=Radeon HD 5470 @@ -4907,11 +7499,131 @@ pci:v00001002d000068F9sv0000174Bsd00005490* pci:v00001002d000068F9sv0000174Bsd00005530* ID_MODEL_FROM_DATABASE=Radeon HD 5530 +pci:v00001002d000068F9sv0000174Bsd00006230* + ID_MODEL_FROM_DATABASE=Radeon HD 6230 + +pci:v00001002d000068F9sv0000174Bsd00006250* + ID_MODEL_FROM_DATABASE=Radeon HD 6250 + +pci:v00001002d000068F9sv0000174Bsd00006290* + ID_MODEL_FROM_DATABASE=Radeon HD 6290 + +pci:v00001002d000068F9sv0000174Bsd00006350* + ID_MODEL_FROM_DATABASE=Radeon HD 6350 + pci:v00001002d000068F9sv0000174Bsd00007350* ID_MODEL_FROM_DATABASE=Radeon HD 7350 +pci:v00001002d000068F9sv0000174Bsd00008350* + ID_MODEL_FROM_DATABASE=Radeon HD 8350 + +pci:v00001002d000068F9sv0000174Bsd0000E127* + ID_MODEL_FROM_DATABASE=Radeon HD 5450 + +pci:v00001002d000068F9sv0000174Bsd0000E145* + ID_MODEL_FROM_DATABASE=Radeon HD 5450 + +pci:v00001002d000068F9sv0000174Bsd0000E153* + ID_MODEL_FROM_DATABASE=Radeon HD 5450 + +pci:v00001002d000068F9sv00001787sd00003000* + ID_MODEL_FROM_DATABASE=Radeon HD 5470 + +pci:v00001002d000068F9sv00001787sd00003001* + ID_MODEL_FROM_DATABASE=Radeon HD 5530 + +pci:v00001002d000068F9sv00001787sd00003002* + ID_MODEL_FROM_DATABASE=Radeon HD 5490 + +pci:v00001002d000068F9sv000017AAsd00003602* + ID_MODEL_FROM_DATABASE=Radeon HD 5450 + +pci:v00001002d000068F9sv000017AAsd00003603* + ID_MODEL_FROM_DATABASE=Radeon HD 5450 + +pci:v00001002d000068F9sv000017AAsd0000360F* + ID_MODEL_FROM_DATABASE=Radeon HD 5450 + +pci:v00001002d000068F9sv000017AAsd00003619* + ID_MODEL_FROM_DATABASE=Radeon HD 5450 + +pci:v00001002d000068F9sv000017AFsd00003000* + ID_MODEL_FROM_DATABASE=Radeon HD 6250 + +pci:v00001002d000068F9sv000017AFsd00003001* + ID_MODEL_FROM_DATABASE=Radeon HD 6230 + +pci:v00001002d000068F9sv000017AFsd00003002* + ID_MODEL_FROM_DATABASE=Radeon HD 6290 + +pci:v00001002d000068F9sv000017AFsd00003011* + ID_MODEL_FROM_DATABASE=Radeon HD 5470 + +pci:v00001002d000068F9sv000017AFsd00003012* + ID_MODEL_FROM_DATABASE=Radeon HD 5490 + +pci:v00001002d000068F9sv000017AFsd00003013* + ID_MODEL_FROM_DATABASE=Radeon HD 5470 + +pci:v00001002d000068F9sv000017AFsd00003014* + ID_MODEL_FROM_DATABASE=Radeon HD 6350 + pci:v00001002d000068FA* - ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350] + ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350/8350] + +pci:v00001002d000068FAsv00001019sd00000019* + ID_MODEL_FROM_DATABASE=Radeon HD 7350 + +pci:v00001002d000068FAsv00001019sd00000021* + ID_MODEL_FROM_DATABASE=Radeon HD 7350 + +pci:v00001002d000068FAsv00001019sd00000022* + ID_MODEL_FROM_DATABASE=Radeon HD 7350 + +pci:v00001002d000068FAsv00001019sd00000026* + ID_MODEL_FROM_DATABASE=Radeon HD 8350 + +pci:v00001002d000068FAsv0000103Csd00002ADF* + ID_MODEL_FROM_DATABASE=Radeon HD 7350A + +pci:v00001002d000068FAsv0000103Csd00002AE8* + ID_MODEL_FROM_DATABASE=Radeon HD 7350A + +pci:v00001002d000068FAsv00001043sd00008350* + ID_MODEL_FROM_DATABASE=Radeon HD 8350 + +pci:v00001002d000068FAsv00001462sd00002128* + ID_MODEL_FROM_DATABASE=Radeon HD 7350 + +pci:v00001002d000068FAsv00001462sd00002184* + ID_MODEL_FROM_DATABASE=Radeon HD 7350 + +pci:v00001002d000068FAsv00001462sd00002186* + ID_MODEL_FROM_DATABASE=Radeon HD 7350 + +pci:v00001002d000068FAsv00001462sd00002495* + ID_MODEL_FROM_DATABASE=Radeon HD 7350 + +pci:v00001002d000068FAsv00001462sd0000B490* + ID_MODEL_FROM_DATABASE=Radeon HD 7350 + +pci:v00001002d000068FAsv00001642sd00003985* + ID_MODEL_FROM_DATABASE=Radeon HD 7350 + +pci:v00001002d000068FAsv0000174Bsd00007350* + ID_MODEL_FROM_DATABASE=Radeon HD 7350 + +pci:v00001002d000068FAsv0000174Bsd00008153* + ID_MODEL_FROM_DATABASE=Radeon HD 8350 + +pci:v00001002d000068FAsv0000174Bsd0000E127* + ID_MODEL_FROM_DATABASE=Radeon HD 7350 + +pci:v00001002d000068FAsv0000174Bsd0000E153* + ID_MODEL_FROM_DATABASE=Radeon HD 7350 + +pci:v00001002d000068FAsv0000174Bsd0000E180* + ID_MODEL_FROM_DATABASE=Radeon HD 7350 pci:v00001002d000068FAsv000017AFsd00003015* ID_MODEL_FROM_DATABASE=Radeon HD 7350 @@ -4919,6 +7631,9 @@ pci:v00001002d000068FAsv000017AFsd00003015* pci:v00001002d000068FE* ID_MODEL_FROM_DATABASE=Cedar LE +pci:v00001002d00006920* + ID_MODEL_FROM_DATABASE=Tonga + pci:v00001002d0000700F* ID_MODEL_FROM_DATABASE=RS100 AGP Bridge @@ -5418,7 +8133,7 @@ pci:v00001002d00009442sv00001002sd00000502* ID_MODEL_FROM_DATABASE=MSI Radeon HD 4850 512MB GDDR3 pci:v00001002d00009442sv0000174Bsd0000E810* - ID_MODEL_FROM_DATABASE=Sapphire Radeon HD 4850 512MB GDDR3 + ID_MODEL_FROM_DATABASE=Radeon HD 4850 512MB GDDR3 pci:v00001002d00009443* ID_MODEL_FROM_DATABASE=R700 [Radeon HD 4850 X2] @@ -5442,7 +8157,7 @@ pci:v00001002d0000944E* ID_MODEL_FROM_DATABASE=RV770 CE [Radeon HD 4710] pci:v00001002d0000944Esv0000174Bsd00003261* - ID_MODEL_FROM_DATABASE=Sapphire Radeon HD 4810 + ID_MODEL_FROM_DATABASE=Radeon HD 4810 pci:v00001002d00009450* ID_MODEL_FROM_DATABASE=RV770 GL [FireStream 9270] @@ -5469,7 +8184,7 @@ pci:v00001002d00009480* ID_MODEL_FROM_DATABASE=RV730/M96 [Mobility Radeon HD 4650/5165] pci:v00001002d00009480sv0000103Csd00003628* - ID_MODEL_FROM_DATABASE=ATI Mobility Radeon HD 4650 [dv6-1190en] + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 4650 [dv6-1190en] pci:v00001002d00009488* ID_MODEL_FROM_DATABASE=RV730/M96-XT [Mobility Radeon HD 4670] @@ -5547,7 +8262,7 @@ pci:v00001002d000094C3sv00001028sd00000302* ID_MODEL_FROM_DATABASE=Radeon HD 2400 Pro pci:v00001002d000094C3sv0000174Bsd0000E400* - ID_MODEL_FROM_DATABASE=Sapphire Radeon HD 2400 PRO + ID_MODEL_FROM_DATABASE=Radeon HD 2400 PRO pci:v00001002d000094C3sv000018BCsd00003550* ID_MODEL_FROM_DATABASE=GeCube Radeon HD 2400 PRO @@ -5583,7 +8298,7 @@ pci:v00001002d00009501* ID_MODEL_FROM_DATABASE=RV670 [Radeon HD 3870] pci:v00001002d00009501sv0000174Bsd0000E620* - ID_MODEL_FROM_DATABASE=Sapphire Radeon HD 3870 PCIe 2.0 + ID_MODEL_FROM_DATABASE=Radeon HD 3870 pci:v00001002d00009504* ID_MODEL_FROM_DATABASE=RV670/M88 [Mobility Radeon HD 3850] @@ -5898,7 +8613,7 @@ pci:v00001002d00009802* ID_MODEL_FROM_DATABASE=Wrestler [Radeon HD 6310] pci:v00001002d00009802sv0000174Bsd00001001* - ID_MODEL_FROM_DATABASE=Sapphire PURE Fusion Mini + ID_MODEL_FROM_DATABASE=PURE Fusion Mini pci:v00001002d00009803* ID_MODEL_FROM_DATABASE=Wrestler [Radeon HD 6310] @@ -5964,7 +8679,7 @@ pci:v00001002d0000983C* ID_MODEL_FROM_DATABASE=Kabini pci:v00001002d0000983D* - ID_MODEL_FROM_DATABASE=Kabini [Radeon HD 8250] + ID_MODEL_FROM_DATABASE=Temash [Radeon HD 8250/8280G] pci:v00001002d0000983E* ID_MODEL_FROM_DATABASE=Kabini @@ -5972,6 +8687,54 @@ pci:v00001002d0000983E* pci:v00001002d0000983F* ID_MODEL_FROM_DATABASE=Kabini +pci:v00001002d00009850* + ID_MODEL_FROM_DATABASE=Mullins [Radeon APU A6-6200 with R3 Graphics] + +pci:v00001002d00009851* + ID_MODEL_FROM_DATABASE=Mullins [Radeon APU A4-6000 with R2 Graphics] + +pci:v00001002d00009852* + ID_MODEL_FROM_DATABASE=Mullins [Radeon APU A4-6000 with R2 Graphics] + +pci:v00001002d00009853* + ID_MODEL_FROM_DATABASE=Mullins [Radeon APU E2-4000 with R2 Graphics] + +pci:v00001002d00009854* + ID_MODEL_FROM_DATABASE=Mullins [Radeon APU E2-3700 with R2 Graphics] + +pci:v00001002d00009855* + ID_MODEL_FROM_DATABASE=Mullins [Radeon APU XX-2450M with R3 Graphics] + +pci:v00001002d00009856* + ID_MODEL_FROM_DATABASE=Mullins [Radeon APU XX-2200M with R2 Graphics] + +pci:v00001002d00009857* + ID_MODEL_FROM_DATABASE=Mullins [Radeon APU XX-2200M with R2 Graphics] + +pci:v00001002d00009858* + ID_MODEL_FROM_DATABASE=Mullins + +pci:v00001002d00009859* + ID_MODEL_FROM_DATABASE=Mullins + +pci:v00001002d0000985A* + ID_MODEL_FROM_DATABASE=Mullins + +pci:v00001002d0000985B* + ID_MODEL_FROM_DATABASE=Mullins + +pci:v00001002d0000985C* + ID_MODEL_FROM_DATABASE=Mullins + +pci:v00001002d0000985D* + ID_MODEL_FROM_DATABASE=Mullins + +pci:v00001002d0000985E* + ID_MODEL_FROM_DATABASE=Mullins + +pci:v00001002d0000985F* + ID_MODEL_FROM_DATABASE=Mullins + pci:v00001002d00009901* ID_MODEL_FROM_DATABASE=Trinity [Radeon HD 7660D] @@ -6093,10 +8856,10 @@ pci:v00001002d0000AA10* ID_MODEL_FROM_DATABASE=RV610 HDMI Audio [Radeon HD 2350/2400 Series] pci:v00001002d0000AA10sv0000174Bsd0000AA10* - ID_MODEL_FROM_DATABASE=Sapphire HD 2400 PRO audio device + ID_MODEL_FROM_DATABASE=Radeon HD 2400 PRO pci:v00001002d0000AA10sv000018BCsd0000AA10* - ID_MODEL_FROM_DATABASE=GeCube Radeon HD 2400 PRO HDCP-capable digital-only audio device + ID_MODEL_FROM_DATABASE=GeCube Radeon HD 2400 PRO pci:v00001002d0000AA18* ID_MODEL_FROM_DATABASE=RV670/680 HDMI Audio [Radeon HD 3690/3800 Series] @@ -6111,16 +8874,13 @@ pci:v00001002d0000AA30* ID_MODEL_FROM_DATABASE=RV770 HDMI Audio [Radeon HD 4850/4870] pci:v00001002d0000AA30sv0000174Bsd0000AA30* - ID_MODEL_FROM_DATABASE=Sapphire HD 4850 512MB GDDR3 PCI-E Dual Slot Fansink + ID_MODEL_FROM_DATABASE=Radeon HD 4850 512MB GDDR3 PCI-E Dual Slot Fansink pci:v00001002d0000AA38* ID_MODEL_FROM_DATABASE=RV710/730 HDMI Audio [Radeon HD 4000 series] pci:v00001002d0000AA38sv0000103Csd00003628* - ID_MODEL_FROM_DATABASE=ATI RV710/730 [dv6-1190en] - -pci:v00001002d0000AA38sv0000174Bsd0000AA38* - ID_MODEL_FROM_DATABASE=R700 Audio Device [Radeon HD 4000 Series] + ID_MODEL_FROM_DATABASE=dv6-1190en pci:v00001002d0000AA50* ID_MODEL_FROM_DATABASE=Cypress HDMI Audio [Radeon HD 5800 Series] @@ -6159,7 +8919,7 @@ pci:v00001002d0000AA98* ID_MODEL_FROM_DATABASE=Caicos HDMI Audio [Radeon HD 6400 Series] pci:v00001002d0000AA98sv0000174Bsd0000AA98* - ID_MODEL_FROM_DATABASE=Sapphire HD 6450 1GB DDR3 + ID_MODEL_FROM_DATABASE=Radeon HD 6450 1GB DDR3 pci:v00001002d0000AAA0* ID_MODEL_FROM_DATABASE=Tahiti XT HDMI Audio [Radeon HD 7970 Series] @@ -7370,6 +10130,9 @@ pci:v00001014d0000034Asv00001014sd0000035E* pci:v00001014d0000034Asv00001014sd000003FB* ID_MODEL_FROM_DATABASE=PCIe3 28GB Cache RAID SAS Enclosure 6Gb x 16 (57D5) +pci:v00001014d000004AA* + ID_MODEL_FROM_DATABASE=Flash Adapter 900GB Full Height + pci:v00001014d00003022* ID_MODEL_FROM_DATABASE=QLA3022 Network Adapter @@ -7674,14 +10437,11 @@ pci:v00001022d00001510* ID_MODEL_FROM_DATABASE=Family 14h Processor Root Complex pci:v00001022d00001510sv0000174Bsd00001001* - ID_MODEL_FROM_DATABASE=Sapphire PURE Fusion Mini + ID_MODEL_FROM_DATABASE=PURE Fusion Mini pci:v00001022d00001512* ID_MODEL_FROM_DATABASE=Family 14h Processor Root Port -pci:v00001022d00001512sv0000174Bsd00001001* - ID_MODEL_FROM_DATABASE=Sapphire PURE Fusion Mini - pci:v00001022d00001513* ID_MODEL_FROM_DATABASE=Family 14h Processor Root Port @@ -8126,6 +10886,9 @@ pci:v00001022d0000780C* pci:v00001022d0000780D* ID_MODEL_FROM_DATABASE=FCH Azalia Controller +pci:v00001022d0000780Dsv00001043sd00008444* + ID_MODEL_FROM_DATABASE=F2A85-M Series + pci:v00001022d0000780E* ID_MODEL_FROM_DATABASE=FCH LPC Bridge @@ -8172,7 +10935,7 @@ pci:v00001022d00009606* ID_MODEL_FROM_DATABASE=RS780 PCI to PCI bridge (PCIE port 2) pci:v00001022d00009607* - ID_MODEL_FROM_DATABASE=RS780 PCI to PCI bridge (PCIE port 3) + ID_MODEL_FROM_DATABASE=RS780/RS880 PCI to PCI bridge (PCIE port 3) pci:v00001022d00009608* ID_MODEL_FROM_DATABASE=RS780/RS880 PCI to PCI bridge (PCIE port 4) @@ -10731,31 +13494,28 @@ pci:v0000103Cd0000323C* ID_MODEL_FROM_DATABASE=Smart Array Gen8+ Controllers pci:v0000103Cd0000323Csv0000103Csd00001920* - ID_MODEL_FROM_DATABASE=Smart Array + ID_MODEL_FROM_DATABASE=P430i pci:v0000103Cd0000323Csv0000103Csd00001921* - ID_MODEL_FROM_DATABASE=Smart Array + ID_MODEL_FROM_DATABASE=P830i pci:v0000103Cd0000323Csv0000103Csd00001922* - ID_MODEL_FROM_DATABASE=Smart Array + ID_MODEL_FROM_DATABASE=P430 pci:v0000103Cd0000323Csv0000103Csd00001923* - ID_MODEL_FROM_DATABASE=Smart Array + ID_MODEL_FROM_DATABASE=P431 pci:v0000103Cd0000323Csv0000103Csd00001924* - ID_MODEL_FROM_DATABASE=Smart Array + ID_MODEL_FROM_DATABASE=P830 pci:v0000103Cd0000323Csv0000103Csd00001925* ID_MODEL_FROM_DATABASE=Smart Array pci:v0000103Cd0000323Csv0000103Csd00001926* - ID_MODEL_FROM_DATABASE=Smart Array - -pci:v0000103Cd0000323Csv0000103Csd00001927* - ID_MODEL_FROM_DATABASE=Smart Array + ID_MODEL_FROM_DATABASE=P731m pci:v0000103Cd0000323Csv0000103Csd00001928* - ID_MODEL_FROM_DATABASE=Smart Array + ID_MODEL_FROM_DATABASE=P230i pci:v0000103Cd00003300* ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard Virtual USB Controller @@ -11673,7 +14433,7 @@ pci:v0000104Cd00008201* ID_MODEL_FROM_DATABASE=PCI1620 Firmware Loading Function pci:v0000104Cd00008204* - ID_MODEL_FROM_DATABASE=PCI7410,7510,7610 PCI Firmware Loading Function + ID_MODEL_FROM_DATABASE=PCI7410/7510/7610 PCI Firmware Loading Function pci:v0000104Cd00008204sv00001028sd00000139* ID_MODEL_FROM_DATABASE=Latitude D400 @@ -11949,7 +14709,7 @@ pci:v0000104Cd0000AC49* ID_MODEL_FROM_DATABASE=PCI7410 PC Card Cardbus Controller pci:v0000104Cd0000AC4A* - ID_MODEL_FROM_DATABASE=PCI7510,7610 PC card Cardbus Controller + ID_MODEL_FROM_DATABASE=PCI7510/7610 CardBus Bridge pci:v0000104Cd0000AC4Asv00001028sd00000139* ID_MODEL_FROM_DATABASE=Latitude D400 @@ -12063,7 +14823,7 @@ pci:v0000104Cd0000AC8Esv00001028sd0000018D* ID_MODEL_FROM_DATABASE=Inspiron 700m/710m pci:v0000104Cd0000AC8F* - ID_MODEL_FROM_DATABASE=PCI7420/7620 Combo CardBus, 1394a-2000 OHCI and SD/MS-Pro Controller + ID_MODEL_FROM_DATABASE=PCI7420/7620 SD/MS-Pro Controller pci:v0000104Cd0000AC8Fsv00001028sd0000018D* ID_MODEL_FROM_DATABASE=Inspiron 700m/710m @@ -13766,9 +16526,6 @@ pci:v00001083d00000001* pci:v00001084* ID_VENDOR_FROM_DATABASE=Parador -pci:v00001085* - ID_VENDOR_FROM_DATABASE=Tulip Computers Int.B.V. - pci:v00001086* ID_VENDOR_FROM_DATABASE=J. Bond Computer Systems @@ -17447,6 +20204,9 @@ pci:v000010DEd00000044* pci:v000010DEd00000045* ID_MODEL_FROM_DATABASE=NV40 [GeForce 6800 GT] +pci:v000010DEd00000045sv00001043sd0000817D* + ID_MODEL_FROM_DATABASE=V9999GT + pci:v000010DEd00000045sv00001458sd00003140* ID_MODEL_FROM_DATABASE=GV-N68T256D @@ -20687,6 +23447,9 @@ pci:v000010DEd000005E2* pci:v000010DEd000005E3* ID_MODEL_FROM_DATABASE=GT200b [GeForce GTX 285] +pci:v000010DEd000005E3sv00001682sd00002490* + ID_MODEL_FROM_DATABASE=GX-285N-ZDF + pci:v000010DEd000005E6* ID_MODEL_FROM_DATABASE=GT200b [GeForce GTX 275] @@ -21719,9 +24482,30 @@ pci:v000010DEd00000871* pci:v000010DEd00000872* ID_MODEL_FROM_DATABASE=C79 [GeForce G102M] +pci:v000010DEd00000872sv00001043sd000019B4* + ID_MODEL_FROM_DATABASE=GeForce G102M + +pci:v000010DEd00000872sv00001043sd00001AA2* + ID_MODEL_FROM_DATABASE=GeForce G102M + +pci:v000010DEd00000872sv00001043sd00001C02* + ID_MODEL_FROM_DATABASE=GeForce G102M + +pci:v000010DEd00000872sv00001043sd00001C42* + ID_MODEL_FROM_DATABASE=GeForce G205M + pci:v000010DEd00000873* ID_MODEL_FROM_DATABASE=C79 [GeForce G102M] +pci:v000010DEd00000873sv00001043sd000019B4* + ID_MODEL_FROM_DATABASE=GeForce G102M + +pci:v000010DEd00000873sv00001043sd00001C12* + ID_MODEL_FROM_DATABASE=GeForce G102M + +pci:v000010DEd00000873sv00001043sd00001C52* + ID_MODEL_FROM_DATABASE=GeForce G205M + pci:v000010DEd00000874* ID_MODEL_FROM_DATABASE=C79 [ION] @@ -22427,11 +25211,14 @@ pci:v000010DEd00000E09* pci:v000010DEd00000E0A* ID_MODEL_FROM_DATABASE=GK104 HDMI Audio Controller +pci:v000010DEd00000E0B* + ID_MODEL_FROM_DATABASE=GK106 HDMI Audio Controller + pci:v000010DEd00000E0C* ID_MODEL_FROM_DATABASE=GF114 HDMI Audio Controller pci:v000010DEd00000E1A* - ID_MODEL_FROM_DATABASE=GK110 HDMI Audio [GeForce GTX Titan] + ID_MODEL_FROM_DATABASE=GK110 HDMI Audio pci:v000010DEd00000E1B* ID_MODEL_FROM_DATABASE=GK107 HDMI Audio Controller @@ -22505,6 +25292,18 @@ pci:v000010DEd00000FD1sv00001043sd00002141* pci:v000010DEd00000FD2* ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 640M] +pci:v000010DEd00000FD2sv00001028sd0000054F* + ID_MODEL_FROM_DATABASE=GeForce GT 640M + +pci:v000010DEd00000FD2sv00001028sd0000055F* + ID_MODEL_FROM_DATABASE=GeForce GT 640M + +pci:v000010DEd00000FD2sv00001028sd00000595* + ID_MODEL_FROM_DATABASE=GeForce GT 640M LE + +pci:v000010DEd00000FD2sv00001028sd000005B2* + ID_MODEL_FROM_DATABASE=GeForce GT 640M LE + pci:v000010DEd00000FD3* ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 640M LE] @@ -22541,6 +25340,12 @@ pci:v000010DEd00000FE5* pci:v000010DEd00000FE6* ID_MODEL_FROM_DATABASE=GK107 [NVS K1 USM] +pci:v000010DEd00000FE7* + ID_MODEL_FROM_DATABASE=GRID K1 vGPU + +pci:v000010DEd00000FE7sv000010DEsd0000101E* + ID_MODEL_FROM_DATABASE=GRID K100 + pci:v000010DEd00000FEF* ID_MODEL_FROM_DATABASE=GK107GL [GRID K340] @@ -22556,6 +25361,9 @@ pci:v000010DEd00000FF5* pci:v000010DEd00000FF7* ID_MODEL_FROM_DATABASE=GK107GL [Quadro K1 USM] +pci:v000010DEd00000FF7sv000010DEsd00001037* + ID_MODEL_FROM_DATABASE=GRID K140Q + pci:v000010DEd00000FF9* ID_MODEL_FROM_DATABASE=GK107GL [Quadro K2000D] @@ -22580,6 +25388,9 @@ pci:v000010DEd00000FFF* pci:v000010DEd00001003* ID_MODEL_FROM_DATABASE=GK110 [GeForce GTX Titan LE] +pci:v000010DEd00001004* + ID_MODEL_FROM_DATABASE=GK110 [GeForce GTX 780] + pci:v000010DEd00001005* ID_MODEL_FROM_DATABASE=GK110 [GeForce GTX Titan] @@ -22688,6 +25499,9 @@ pci:v000010DEd0000105Asv00001043sd00002112* pci:v000010DEd0000105B* ID_MODEL_FROM_DATABASE=GF119M [GeForce 705M] +pci:v000010DEd0000105Bsv0000103Csd00002AFB* + ID_MODEL_FROM_DATABASE=GeForce 705A + pci:v000010DEd0000107C* ID_MODEL_FROM_DATABASE=GF119 [NVS 315] @@ -22775,27 +25589,108 @@ pci:v000010DEd000010D8* pci:v000010DEd00001140* ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M / GT 620M/625M/630M/720M] +pci:v000010DEd00001140sv00001025sd00000600* + ID_MODEL_FROM_DATABASE=GeForce GT 620M + +pci:v000010DEd00001140sv00001025sd00000606* + ID_MODEL_FROM_DATABASE=GeForce GT 620M + pci:v000010DEd00001140sv00001025sd0000064A* ID_MODEL_FROM_DATABASE=GeForce GT 620M pci:v000010DEd00001140sv00001025sd0000064C* ID_MODEL_FROM_DATABASE=GeForce GT 620M +pci:v000010DEd00001140sv00001025sd0000067A* + ID_MODEL_FROM_DATABASE=GeForce GT 620M + +pci:v000010DEd00001140sv00001025sd00000680* + ID_MODEL_FROM_DATABASE=GeForce GT 620M + +pci:v000010DEd00001140sv00001025sd00000686* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001025sd00000689* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001025sd0000068B* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001025sd0000068D* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001025sd0000068E* + ID_MODEL_FROM_DATABASE=GeForce 710M + pci:v000010DEd00001140sv00001025sd00000691* ID_MODEL_FROM_DATABASE=GeForce 710M +pci:v000010DEd00001140sv00001025sd00000692* + ID_MODEL_FROM_DATABASE=GeForce GT 620M + +pci:v000010DEd00001140sv00001025sd00000694* + ID_MODEL_FROM_DATABASE=GeForce GT 620M + +pci:v000010DEd00001140sv00001025sd00000702* + ID_MODEL_FROM_DATABASE=GeForce GT 620M + pci:v000010DEd00001140sv00001025sd00000719* ID_MODEL_FROM_DATABASE=GeForce GT 620M pci:v000010DEd00001140sv00001025sd00000725* ID_MODEL_FROM_DATABASE=GeForce GT 620M +pci:v000010DEd00001140sv00001025sd00000728* + ID_MODEL_FROM_DATABASE=GeForce GT 620M + pci:v000010DEd00001140sv00001025sd0000072B* ID_MODEL_FROM_DATABASE=GeForce GT 620M +pci:v000010DEd00001140sv00001025sd0000072E* + ID_MODEL_FROM_DATABASE=GeForce GT 620M + +pci:v000010DEd00001140sv00001025sd00000732* + ID_MODEL_FROM_DATABASE=GeForce GT 620M + +pci:v000010DEd00001140sv00001025sd00000763* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + pci:v000010DEd00001140sv00001025sd00000773* ID_MODEL_FROM_DATABASE=GeForce 710M +pci:v000010DEd00001140sv00001025sd00000774* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001025sd00000776* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + +pci:v000010DEd00001140sv00001025sd0000077A* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001025sd0000077B* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001025sd0000077C* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001025sd0000077D* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001025sd0000077E* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001025sd0000077F* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001025sd00000798* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + +pci:v000010DEd00001140sv00001025sd0000079B* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + +pci:v000010DEd00001140sv00001025sd00000821* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + pci:v000010DEd00001140sv00001028sd0000054D* ID_MODEL_FROM_DATABASE=GeForce GT 630M @@ -22811,6 +25706,57 @@ pci:v000010DEd00001140sv00001028sd00000557* pci:v000010DEd00001140sv00001028sd00000565* ID_MODEL_FROM_DATABASE=GeForce GT 630M +pci:v000010DEd00001140sv00001028sd00000568* + ID_MODEL_FROM_DATABASE=GeForce GT 630M + +pci:v000010DEd00001140sv00001028sd00000590* + ID_MODEL_FROM_DATABASE=GeForce GT 630M + +pci:v000010DEd00001140sv00001028sd00000592* + ID_MODEL_FROM_DATABASE=GeForce GT 625M + +pci:v000010DEd00001140sv00001028sd00000594* + ID_MODEL_FROM_DATABASE=GeForce GT 625M + +pci:v000010DEd00001140sv00001028sd00000595* + ID_MODEL_FROM_DATABASE=GeForce GT 625M + +pci:v000010DEd00001140sv00001028sd000005A2* + ID_MODEL_FROM_DATABASE=GeForce GT 625M + +pci:v000010DEd00001140sv00001028sd000005B1* + ID_MODEL_FROM_DATABASE=GeForce GT 625M + +pci:v000010DEd00001140sv00001028sd000005B3* + ID_MODEL_FROM_DATABASE=GeForce GT 625M + +pci:v000010DEd00001140sv00001028sd000005DA* + ID_MODEL_FROM_DATABASE=GeForce GT 630M + +pci:v000010DEd00001140sv00001028sd000005E8* + ID_MODEL_FROM_DATABASE=GeForce GT 630M + +pci:v000010DEd00001140sv0000103Csd000018EF* + ID_MODEL_FROM_DATABASE=GeForce GT 630M + +pci:v000010DEd00001140sv0000103Csd000018F9* + ID_MODEL_FROM_DATABASE=GeForce GT 630M + +pci:v000010DEd00001140sv0000103Csd000018FB* + ID_MODEL_FROM_DATABASE=GeForce GT 630M + +pci:v000010DEd00001140sv0000103Csd000018FD* + ID_MODEL_FROM_DATABASE=GeForce GT 630M + +pci:v000010DEd00001140sv0000103Csd000018FF* + ID_MODEL_FROM_DATABASE=GeForce GT 630M + +pci:v000010DEd00001140sv0000103Csd00002AEF* + ID_MODEL_FROM_DATABASE=GeForce GT 720A + +pci:v000010DEd00001140sv0000103Csd00002AF9* + ID_MODEL_FROM_DATABASE=GeForce 710A + pci:v000010DEd00001140sv00001043sd000010DD* ID_MODEL_FROM_DATABASE=NVS 5200M @@ -22826,6 +25772,9 @@ pci:v000010DEd00001140sv00001043sd0000124D* pci:v000010DEd00001140sv00001043sd0000126D* ID_MODEL_FROM_DATABASE=GeForce GT 720M +pci:v000010DEd00001140sv00001043sd0000131D* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + pci:v000010DEd00001140sv00001043sd000014C7* ID_MODEL_FROM_DATABASE=GeForce GT 720M @@ -22847,39 +25796,156 @@ pci:v000010DEd00001140sv00001043sd000021FA* pci:v000010DEd00001140sv00001043sd0000220A* ID_MODEL_FROM_DATABASE=GeForce GT 720M +pci:v000010DEd00001140sv00001043sd0000221A* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + +pci:v000010DEd00001140sv0000144Dsd0000C0D5* + ID_MODEL_FROM_DATABASE=GeForce GT 630M + pci:v000010DEd00001140sv0000144Dsd0000C0D7* ID_MODEL_FROM_DATABASE=GeForce GT 620M +pci:v000010DEd00001140sv0000144Dsd0000C0E2* + ID_MODEL_FROM_DATABASE=NVS 5200M + +pci:v000010DEd00001140sv0000144Dsd0000C0E3* + ID_MODEL_FROM_DATABASE=NVS 5200M + +pci:v000010DEd00001140sv0000144Dsd0000C0E4* + ID_MODEL_FROM_DATABASE=NVS 5200M + pci:v000010DEd00001140sv0000144Dsd0000C652* ID_MODEL_FROM_DATABASE=GeForce GT 620M +pci:v000010DEd00001140sv0000144Dsd0000C709* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv0000144Dsd0000C711* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001462sd000010B8* + ID_MODEL_FROM_DATABASE=GeForce GT 710M + +pci:v000010DEd00001140sv00001462sd000010E9* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + +pci:v000010DEd00001140sv0000152Dsd00000926* + ID_MODEL_FROM_DATABASE=GeForce 620M + +pci:v000010DEd00001140sv0000152Dsd00000982* + ID_MODEL_FROM_DATABASE=GeForce GT 630M + +pci:v000010DEd00001140sv0000152Dsd00000983* + ID_MODEL_FROM_DATABASE=GeForce GT 630M + +pci:v000010DEd00001140sv0000152Dsd00001030* + ID_MODEL_FROM_DATABASE=GeForce GT 630M + pci:v000010DEd00001140sv000017AAsd00002200* ID_MODEL_FROM_DATABASE=NVS 5200M +pci:v000010DEd00001140sv000017AAsd00003656* + ID_MODEL_FROM_DATABASE=GeForce GT 620M + +pci:v000010DEd00001140sv000017AAsd00003800* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + +pci:v000010DEd00001140sv000017AAsd00003801* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + +pci:v000010DEd00001140sv000017AAsd00003802* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + +pci:v000010DEd00001140sv000017AAsd00003803* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + pci:v000010DEd00001140sv000017AAsd00003901* ID_MODEL_FROM_DATABASE=GeForce 610M / GT 620M +pci:v000010DEd00001140sv000017AAsd00003902* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv000017AAsd00003903* + ID_MODEL_FROM_DATABASE=GeForce 610M/710M + pci:v000010DEd00001140sv000017AAsd00003904* ID_MODEL_FROM_DATABASE=GeForce GT 620M/625M +pci:v000010DEd00001140sv000017AAsd00003905* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + +pci:v000010DEd00001140sv000017AAsd00003910* + ID_MODEL_FROM_DATABASE=GeForce 720M + +pci:v000010DEd00001140sv000017AAsd00003912* + ID_MODEL_FROM_DATABASE=GeForce 720M + +pci:v000010DEd00001140sv000017AAsd00003977* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + pci:v000010DEd00001140sv000017AAsd00003983* ID_MODEL_FROM_DATABASE=GeForce 610M +pci:v000010DEd00001140sv000017AAsd00005003* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + pci:v000010DEd00001140sv000017AAsd0000500D* ID_MODEL_FROM_DATABASE=GeForce GT 620M +pci:v000010DEd00001140sv000017AAsd00005014* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv000017AAsd00005017* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv000017AAsd00005019* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv000017AAsd0000501A* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv000017AAsd0000501F* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + +pci:v000010DEd00001140sv000017AAsd00005027* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv000017AAsd0000502A* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001854sd00000177* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001854sd00000180* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001B0Asd000020DD* + ID_MODEL_FROM_DATABASE=GeForce GT 620M + +pci:v000010DEd00001140sv00001B0Asd000020DF* + ID_MODEL_FROM_DATABASE=GeForce GT 620M + pci:v000010DEd00001180* ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 680] pci:v000010DEd00001180sv00003842sd00003682* ID_MODEL_FROM_DATABASE=GeForce GTX 680 Mac Edition +pci:v000010DEd00001182* + ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 760 Ti] + pci:v000010DEd00001183* ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 660 Ti] +pci:v000010DEd00001184* + ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 770] + pci:v000010DEd00001185* ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 660 OEM] +pci:v000010DEd00001187* + ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 760] + pci:v000010DEd00001188* ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 690] @@ -22895,9 +25961,18 @@ pci:v000010DEd0000118B* pci:v000010DEd0000118C* ID_MODEL_FROM_DATABASE=GK104 [NVS K2 USM] +pci:v000010DEd0000118D* + ID_MODEL_FROM_DATABASE=GRID K2 vGPU + +pci:v000010DEd0000118Dsv000010DEsd0000101D* + ID_MODEL_FROM_DATABASE=GRID K200 + pci:v000010DEd0000118F* ID_MODEL_FROM_DATABASE=GK104GL [Tesla K10] +pci:v000010DEd0000119D* + ID_MODEL_FROM_DATABASE=GK104M [GeForce GTX 775M] + pci:v000010DEd0000119F* ID_MODEL_FROM_DATABASE=GK104M [GeForce GTX 780M] @@ -22913,12 +25988,21 @@ pci:v000010DEd000011A2* pci:v000010DEd000011A3* ID_MODEL_FROM_DATABASE=GK104M [GeForce GTX 680MX] +pci:v000010DEd000011A3sv0000106Bsd0000010D* + ID_MODEL_FROM_DATABASE=iMac 13,2 + pci:v000010DEd000011A7* ID_MODEL_FROM_DATABASE=GK104M [GeForce GTX 675MX] pci:v000010DEd000011B0* ID_MODEL_FROM_DATABASE=GK104GL [Quadro K2 USM] +pci:v000010DEd000011B0sv000010DEsd0000101A* + ID_MODEL_FROM_DATABASE=GRID K240Q + +pci:v000010DEd000011B0sv000010DEsd0000101B* + ID_MODEL_FROM_DATABASE=GRID K260Q + pci:v000010DEd000011B1* ID_MODEL_FROM_DATABASE=GK104GL [Tesla K2 USM] @@ -22979,6 +26063,9 @@ pci:v000010DEd000011C6* pci:v000010DEd000011E0* ID_MODEL_FROM_DATABASE=GK106M [GeForce GTX 770M] +pci:v000010DEd000011E1* + ID_MODEL_FROM_DATABASE=GK106M [GeForce GTX 765M] + pci:v000010DEd000011E2* ID_MODEL_FROM_DATABASE=GK106M [GeForce GTX 765M] @@ -23078,9 +26165,27 @@ pci:v000010DEd00001251* pci:v000010DEd00001280* ID_MODEL_FROM_DATABASE=GK208 [GeForce GT 635] +pci:v000010DEd00001282* + ID_MODEL_FROM_DATABASE=GK208 [GeForce GT 640 Rev. 2] + +pci:v000010DEd00001284* + ID_MODEL_FROM_DATABASE=GK208 [GeForce GT 630 Rev. 2] + pci:v000010DEd00001290* ID_MODEL_FROM_DATABASE=GK208M [GeForce GT 730M] +pci:v000010DEd00001290sv0000103Csd00002AFA* + ID_MODEL_FROM_DATABASE=GeForce GT 730A + +pci:v000010DEd00001290sv0000103Csd00002B04* + ID_MODEL_FROM_DATABASE=GeForce GT 730A + +pci:v000010DEd00001290sv00001043sd000013AD* + ID_MODEL_FROM_DATABASE=GeForce GT 730M + +pci:v000010DEd00001290sv00001043sd000013CD* + ID_MODEL_FROM_DATABASE=GeForce GT 730M + pci:v000010DEd00001291* ID_MODEL_FROM_DATABASE=GK208M [GeForce GT 735M] @@ -23739,7 +26844,7 @@ pci:v000010ECd00008167sv00001462sd0000236C* ID_MODEL_FROM_DATABASE=945P Neo3-F motherboard pci:v000010ECd00008168* - ID_MODEL_FROM_DATABASE=RTL8111/8168 PCI Express Gigabit Ethernet controller + ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller pci:v000010ECd00008168sv00001019sd00008168* ID_MODEL_FROM_DATABASE=RTL8111/8168 PCI Express Gigabit Ethernet controller @@ -38412,7 +41517,7 @@ pci:v0000148B* ID_VENDOR_FROM_DATABASE=INNOMEDIALOGIC Inc. pci:v0000148C* - ID_VENDOR_FROM_DATABASE=C.P. Technology Co. Ltd + ID_VENDOR_FROM_DATABASE=Tul Corporation / PowerColor pci:v0000148D* ID_VENDOR_FROM_DATABASE=DIGICOM Systems, Inc. @@ -38475,7 +41580,10 @@ pci:v00001498d00003064* ID_MODEL_FROM_DATABASE=TPCI100 (2 Slot IndustryPack PCI Carrier) pci:v00001498d000030C8* - ID_MODEL_FROM_DATABASE=TPCI200 + ID_MODEL_FROM_DATABASE=TPCI200 4 Slot IndustryPack PCI Carrier + +pci:v00001498d000070C8* + ID_MODEL_FROM_DATABASE=TPCE200 4 Slot IndustryPack PCIe Carrier pci:v00001499* ID_VENDOR_FROM_DATABASE=EMTEC CO., Ltd @@ -39005,6 +42113,9 @@ pci:v000014E4d0000163Asv0000103Csd0000171D* pci:v000014E4d0000163Asv0000103Csd00007056* ID_MODEL_FROM_DATABASE=NC382i Integrated Quad Port PCI Express Gigabit Server Adapter +pci:v000014E4d0000163Asv00001259sd00002984* + ID_MODEL_FROM_DATABASE=AT-2973SX + pci:v000014E4d0000163B* ID_MODEL_FROM_DATABASE=NetXtreme II BCM5716 Gigabit Ethernet @@ -40487,6 +43598,9 @@ pci:v000014E4d00004365* pci:v000014E4d00004365sv00001028sd00000016* ID_MODEL_FROM_DATABASE=Wireless 1704 802.11n + BT 4.0 +pci:v000014E4d000043A0* + ID_MODEL_FROM_DATABASE=BCM4360 802.11ac Wireless Network Adapter + pci:v000014E4d000043B1* ID_MODEL_FROM_DATABASE=BCM4352 802.11ac Wireless Network Adapter @@ -43157,6 +46271,9 @@ pci:v0000163Cd00005449* pci:v00001641* ID_VENDOR_FROM_DATABASE=MKNet Corp. +pci:v00001642* + ID_VENDOR_FROM_DATABASE=Bitland(ShenZhen) Information Technology Co., Ltd. + pci:v00001657* ID_VENDOR_FROM_DATABASE=Brocade Communications Systems, Inc. @@ -44415,7 +47532,7 @@ pci:v00001749* ID_VENDOR_FROM_DATABASE=RLX Technologies pci:v0000174B* - ID_VENDOR_FROM_DATABASE=PC Partner Limited + ID_VENDOR_FROM_DATABASE=PC Partner Limited / Sapphire Technology pci:v0000174D* ID_VENDOR_FROM_DATABASE=WellX Telecom SA @@ -45692,6 +48809,18 @@ pci:v000018F4d000000E5* pci:v000018F4d000000F5* ID_MODEL_FROM_DATABASE=NT4E2-4T-BP Network Adapter 4x1Gb with Electrical Bypass +pci:v000018F4d00000105* + ID_MODEL_FROM_DATABASE=NT4E2-4-PTP Network Adapter 4x1Gb + +pci:v000018F4d00000115* + ID_MODEL_FROM_DATABASE=NT20E2-PTP Network Adapter 2x10Gb + +pci:v000018F4d00000125* + ID_MODEL_FROM_DATABASE=NT4E2-4-PTP Network Adapter 4x1Gb + +pci:v000018F4d00000135* + ID_MODEL_FROM_DATABASE=NT20E2-PTP Network Adapter 2x10Gb + pci:v000018F6* ID_VENDOR_FROM_DATABASE=NextIO @@ -45791,6 +48920,15 @@ pci:v000018F7d00000021* pci:v000018F7d00000022* ID_MODEL_FROM_DATABASE=SuperFSCC/4-LVDS Serial PCIe Adapter [Fastcom] +pci:v000018F7d00000023* + ID_MODEL_FROM_DATABASE=SuperFSCC/4 Serial cPCI Adapter [Fastcom] + +pci:v000018F7d00000025* + ID_MODEL_FROM_DATABASE=SuperFSCC/4-LVDS Serial PCI Adapter [Fastcom] + +pci:v000018F7d00000026* + ID_MODEL_FROM_DATABASE=SuperFSCC-LVDS Serial PCI Adapter [Fastcom] + pci:v000018FB* ID_VENDOR_FROM_DATABASE=Resilience Corporation @@ -45938,6 +49076,24 @@ pci:v00001924d00000710sv00001924sd00005202* pci:v00001924d00000803* ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] +pci:v00001924d00000803sv00001014sd00000478* + ID_MODEL_FROM_DATABASE=2-port 10GbE Low-Latency (R7) + +pci:v00001924d00000803sv00001014sd00000479* + ID_MODEL_FROM_DATABASE=2-port 10GbE OpenOnload (R7) + +pci:v00001924d00000803sv00001014sd000004A7* + ID_MODEL_FROM_DATABASE=Solarflare 10Gb Low-latency Dual-port HBA (R7) + +pci:v00001924d00000803sv00001014sd000004A8* + ID_MODEL_FROM_DATABASE=Solarflare 10Gb Dual-port HBA (R7) + +pci:v00001924d00000803sv0000103Csd00002132* + ID_MODEL_FROM_DATABASE=Ethernet 10Gb 2-port 570FLR-SFP+ Adapter (R1) + +pci:v00001924d00000803sv0000103Csd00002136* + ID_MODEL_FROM_DATABASE=Ethernet 10Gb 2-port 570SFP+ Adapter (R7) + pci:v00001924d00000803sv00001924sd00001201* ID_MODEL_FROM_DATABASE=SFA6902F-R1 SFP+ AOE Adapter @@ -46905,7 +50061,10 @@ pci:v00001A41d00000002* ID_MODEL_FROM_DATABASE=TILEPro processor pci:v00001A41d00000200* - ID_MODEL_FROM_DATABASE=TILE-Gx36 processor + ID_MODEL_FROM_DATABASE=TILE-Gx processor + +pci:v00001A41d00002000* + ID_MODEL_FROM_DATABASE=TILE-Gx PCI Express Bridge pci:v00001A4A* ID_VENDOR_FROM_DATABASE=SLAC National Accelerator Lab PPA-REG @@ -47033,6 +50192,12 @@ pci:v00001A78d00000031sv00001A78sd00000039* pci:v00001A78d00000040* ID_MODEL_FROM_DATABASE=FlashMAX II +pci:v00001A78d00000041* + ID_MODEL_FROM_DATABASE=FlashMAX II + +pci:v00001A78d00000042* + ID_MODEL_FROM_DATABASE=FlashMAX II + pci:v00001A84* ID_VENDOR_FROM_DATABASE=Commex Technologies @@ -47091,7 +50256,7 @@ pci:v00001AB9* ID_VENDOR_FROM_DATABASE=Espia Srl pci:v00001ACC* - ID_VENDOR_FROM_DATABASE=Point of View B.V + ID_VENDOR_FROM_DATABASE=Point of View BV pci:v00001AD7* ID_VENDOR_FROM_DATABASE=Spectracom Corporation @@ -47219,6 +50384,9 @@ pci:v00001B03d00006100* pci:v00001B08* ID_VENDOR_FROM_DATABASE=MSC Vertriebs GmbH +pci:v00001B0A* + ID_VENDOR_FROM_DATABASE=Pegatron + pci:v00001B13* ID_VENDOR_FROM_DATABASE=Jaton Corp @@ -49607,6 +52775,9 @@ pci:v00008086d00000153sv00001043sd00001517* pci:v00008086d00000154* ID_MODEL_FROM_DATABASE=3rd Gen Core processor DRAM Controller +pci:v00008086d00000154sv0000103Csd000017F6* + ID_MODEL_FROM_DATABASE=ProBook 4540s + pci:v00008086d00000154sv00001043sd00001477* ID_MODEL_FROM_DATABASE=N56VZ @@ -49734,22 +52905,28 @@ pci:v00008086d00000374* ID_MODEL_FROM_DATABASE=80333 Address Translation Unit pci:v00008086d00000402* - ID_MODEL_FROM_DATABASE=Haswell Integrated Graphics Controller + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3/4th Gen Core Processor Integrated Graphics Controller pci:v00008086d00000406* - ID_MODEL_FROM_DATABASE=Haswell Integrated Graphics Controller + ID_MODEL_FROM_DATABASE=4th Gen Core Processor Integrated Graphics Controller pci:v00008086d0000040A* - ID_MODEL_FROM_DATABASE=Haswell Integrated Graphics Controller + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3 Processor Integrated Graphics Controller pci:v00008086d00000412* - ID_MODEL_FROM_DATABASE=Haswell Integrated Graphics Controller + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3/4th Gen Core Processor Integrated Graphics Controller pci:v00008086d00000416* - ID_MODEL_FROM_DATABASE=Haswell Integrated Graphics Controller + ID_MODEL_FROM_DATABASE=4th Gen Core Processor Integrated Graphics Controller pci:v00008086d0000041A* - ID_MODEL_FROM_DATABASE=Haswell Integrated Graphics Controller + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3 Processor Integrated Graphics Controller + +pci:v00008086d00000433* + ID_MODEL_FROM_DATABASE=Coleto Creek ACC - ME/CPM interface + +pci:v00008086d00000435* + ID_MODEL_FROM_DATABASE=Coleto Creek PCIe Endpoint pci:v00008086d00000436* ID_MODEL_FROM_DATABASE=DH8900CC Null Device @@ -50349,25 +53526,25 @@ pci:v00008086d00000BF7* ID_MODEL_FROM_DATABASE=Atom Processor D2xxx/N2xxx DRAM Controller pci:v00008086d00000C00* - ID_MODEL_FROM_DATABASE=Haswell DRAM Controller + ID_MODEL_FROM_DATABASE=4th Gen Core Processor DRAM Controller pci:v00008086d00000C01* - ID_MODEL_FROM_DATABASE=Haswell PCI Express x16 Controller + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3/4th Gen Core Processor PCI Express x16 Controller pci:v00008086d00000C04* - ID_MODEL_FROM_DATABASE=Haswell DRAM Controller + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3/4th Gen Core Processor DRAM Controller pci:v00008086d00000C05* - ID_MODEL_FROM_DATABASE=Haswell PCI Express x8 Controller + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3/4th Gen Core Processor PCI Express x8 Controller pci:v00008086d00000C08* - ID_MODEL_FROM_DATABASE=Haswell DRAM Controller + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3 Processor DRAM Controller pci:v00008086d00000C09* - ID_MODEL_FROM_DATABASE=Haswell PCI Express x4 Controller + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3/4th Gen Core Processor PCI Express x4 Controller pci:v00008086d00000C0C* - ID_MODEL_FROM_DATABASE=Haswell HD Audio Controller + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3/4th Gen Core Processor HD Audio Controller pci:v00008086d00000C46* ID_MODEL_FROM_DATABASE=Atom Processor S1200 PCI Express Root Port 1 @@ -52448,6 +55625,9 @@ pci:v00008086d000010FBsv00008086sd00000003* pci:v00008086d000010FBsv00008086sd00000006* ID_MODEL_FROM_DATABASE=Ethernet Server Adapter X520-1 +pci:v00008086d000010FBsv00008086sd00000008* + ID_MODEL_FROM_DATABASE=Ethernet OCP Server Adapter X520-2 + pci:v00008086d000010FBsv00008086sd0000000A* ID_MODEL_FROM_DATABASE=Ethernet Server Adapter X520-1 @@ -53291,6 +56471,12 @@ pci:v00008086d00001522sv00008086sd00000003* pci:v00008086d00001522sv00008086sd00000004* ID_MODEL_FROM_DATABASE=Ethernet Server Adapter I350-F2 +pci:v00008086d00001522sv00008086sd00000005* + ID_MODEL_FROM_DATABASE=Ethernet Server Adapter I350-F1 + +pci:v00008086d00001522sv00008086sd000000A2* + ID_MODEL_FROM_DATABASE=Ethernet Server Adapter I350-T2 + pci:v00008086d00001522sv00008086sd000000A3* ID_MODEL_FROM_DATABASE=Ethernet Server Adapter I350-F4 @@ -53441,18 +56627,45 @@ pci:v00008086d0000154Dsv00008086sd00007B11* pci:v00008086d00001557* ID_MODEL_FROM_DATABASE=82599 10 Gigabit Network Connection +pci:v00008086d00001557sv00008086sd00000001* + ID_MODEL_FROM_DATABASE=Ethernet OCP Server Adapter X520-1 + pci:v00008086d00001559* ID_MODEL_FROM_DATABASE=Ethernet Connection I218-V pci:v00008086d0000155A* ID_MODEL_FROM_DATABASE=Ethernet Connection I218-LM +pci:v00008086d0000155C* + ID_MODEL_FROM_DATABASE=Ethernet Server Bypass Adapter + +pci:v00008086d0000155Csv00008086sd00000001* + ID_MODEL_FROM_DATABASE=Ethernet Server Bypass Adapter X540-T2 + +pci:v00008086d0000155D* + ID_MODEL_FROM_DATABASE=Ethernet Server Bypass Adapter + +pci:v00008086d0000155Dsv00008086sd00000001* + ID_MODEL_FROM_DATABASE=Ethernet Server Bypass Adapter X520-SR2 + pci:v00008086d00001560* ID_MODEL_FROM_DATABASE=Ethernet Controller X540-AT1 pci:v00008086d0000157B* ID_MODEL_FROM_DATABASE=I210 Gigabit Network Connection +pci:v00008086d000015A0* + ID_MODEL_FROM_DATABASE=Ethernet Connection (2) I218-LM + +pci:v00008086d000015A1* + ID_MODEL_FROM_DATABASE=Ethernet Connection (2) I218-V + +pci:v00008086d000015A2* + ID_MODEL_FROM_DATABASE=Ethernet Connection (3) I218-LM + +pci:v00008086d000015A3* + ID_MODEL_FROM_DATABASE=Ethernet Connection (3) I218-V + pci:v00008086d00001960* ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor @@ -54585,7 +57798,13 @@ pci:v00008086d00001F45* ID_MODEL_FROM_DATABASE=Avoton GbE 2500base-KX pci:v00008086d00002250* - ID_MODEL_FROM_DATABASE=Xeon Phi Coprocessor 5110P + ID_MODEL_FROM_DATABASE=Xeon Phi coprocessor 5100 series + +pci:v00008086d0000225C* + ID_MODEL_FROM_DATABASE=Xeon Phi coprocessor SE10/7120 series + +pci:v00008086d0000225D* + ID_MODEL_FROM_DATABASE=Xeon Phi coprocessor 3120 series pci:v00008086d00002310* ID_MODEL_FROM_DATABASE=DH89xxCC LPC Controller @@ -54641,6 +57860,66 @@ pci:v00008086d00002364* pci:v00008086d00002365* ID_MODEL_FROM_DATABASE=DH89xxCC MEI 1 +pci:v00008086d00002390* + ID_MODEL_FROM_DATABASE=Coleto Creek LPC Controller + +pci:v00008086d000023A1* + ID_MODEL_FROM_DATABASE=Coleto Creek 2-Port SATA Controller [IDE Mode] + +pci:v00008086d000023A3* + ID_MODEL_FROM_DATABASE=Coleto Creek 4-Port SATA Controller [AHCI Mode] + +pci:v00008086d000023A6* + ID_MODEL_FROM_DATABASE=Coleto Creek 2-Port SATA Controller [IDE Mode] + +pci:v00008086d000023B0* + ID_MODEL_FROM_DATABASE=Coleto Creek SMBus Controller + +pci:v00008086d000023B1* + ID_MODEL_FROM_DATABASE=Coleto Creek CHAP Counter + +pci:v00008086d000023B2* + ID_MODEL_FROM_DATABASE=Coleto Creek Thermal Management Controller + +pci:v00008086d000023B4* + ID_MODEL_FROM_DATABASE=Coleto Creek USB2 Enhanced Host Controller #1 + +pci:v00008086d000023B5* + ID_MODEL_FROM_DATABASE=Coleto Creek USB2 Enhanced Host Controller #1 + +pci:v00008086d000023C2* + ID_MODEL_FROM_DATABASE=Coleto Creek PCI Express Root Port #1 + +pci:v00008086d000023C3* + ID_MODEL_FROM_DATABASE=Coleto Creek PCI Express Root Port #1 + +pci:v00008086d000023C4* + ID_MODEL_FROM_DATABASE=Coleto Creek PCI Express Root Port #2 + +pci:v00008086d000023C5* + ID_MODEL_FROM_DATABASE=Coleto Creek PCI Express Root Port #2 + +pci:v00008086d000023C6* + ID_MODEL_FROM_DATABASE=Coleto Creek PCI Express Root Port #3 + +pci:v00008086d000023C7* + ID_MODEL_FROM_DATABASE=Coleto Creek PCI Express Root Port #3 + +pci:v00008086d000023C8* + ID_MODEL_FROM_DATABASE=Coleto Creek PCI Express Root Port #4 + +pci:v00008086d000023C9* + ID_MODEL_FROM_DATABASE=Coleto Creek PCI Express Root Port #4 + +pci:v00008086d000023E0* + ID_MODEL_FROM_DATABASE=Coleto Creek Watchdog Timer + +pci:v00008086d000023E4* + ID_MODEL_FROM_DATABASE=Coleto Creek MEI Controller #1 + +pci:v00008086d000023E5* + ID_MODEL_FROM_DATABASE=Coleto Creek MEI Controller #2 + pci:v00008086d00002410* ID_MODEL_FROM_DATABASE=82801AA ISA Bridge (LPC) @@ -61118,6 +64397,45 @@ pci:v00008086d00002F0A* pci:v00008086d00002F0B* ID_MODEL_FROM_DATABASE=Haswell-E PCI Express Root Port 3 +pci:v00008086d00002F10* + ID_MODEL_FROM_DATABASE=Haswell-E IIO Debug + +pci:v00008086d00002F11* + ID_MODEL_FROM_DATABASE=Haswell-E IIO Debug + +pci:v00008086d00002F12* + ID_MODEL_FROM_DATABASE=Haswell-E IIO Debug + +pci:v00008086d00002F13* + ID_MODEL_FROM_DATABASE=Haswell-E IIO Debug + +pci:v00008086d00002F14* + ID_MODEL_FROM_DATABASE=Haswell-E IIO Debug + +pci:v00008086d00002F15* + ID_MODEL_FROM_DATABASE=Haswell-E IIO Debug + +pci:v00008086d00002F16* + ID_MODEL_FROM_DATABASE=Haswell-E IIO Debug + +pci:v00008086d00002F17* + ID_MODEL_FROM_DATABASE=Haswell-E IIO Debug + +pci:v00008086d00002F18* + ID_MODEL_FROM_DATABASE=Haswell-E IIO Debug + +pci:v00008086d00002F19* + ID_MODEL_FROM_DATABASE=Haswell-E IIO Debug + +pci:v00008086d00002F1A* + ID_MODEL_FROM_DATABASE=Haswell-E IIO Debug + +pci:v00008086d00002F1B* + ID_MODEL_FROM_DATABASE=Haswell-E IIO Debug + +pci:v00008086d00002F1C* + ID_MODEL_FROM_DATABASE=Haswell-E IIO Debug + pci:v00008086d00002F1D* ID_MODEL_FROM_DATABASE=Haswell-E PCIe Ring Interface @@ -61208,6 +64526,15 @@ pci:v00008086d00002F41* pci:v00008086d00002F43* ID_MODEL_FROM_DATABASE=Haswell-E QPI Link 2 +pci:v00008086d00002F45* + ID_MODEL_FROM_DATABASE=Haswell-E QPI Link 2 Debug + +pci:v00008086d00002F46* + ID_MODEL_FROM_DATABASE=Haswell-E QPI Link 2 Debug + +pci:v00008086d00002F47* + ID_MODEL_FROM_DATABASE=Haswell-E QPI Link 2 Debug + pci:v00008086d00002F60* ID_MODEL_FROM_DATABASE=Haswell-E Home Agent 1 @@ -61238,6 +64565,9 @@ pci:v00008086d00002F70* pci:v00008086d00002F71* ID_MODEL_FROM_DATABASE=Haswell-E Integrated Memory Controller 0 Target Address, Thermal & RAS Registers +pci:v00008086d00002F76* + ID_MODEL_FROM_DATABASE=Haswell-E E3 QPI Link Debug + pci:v00008086d00002F78* ID_MODEL_FROM_DATABASE=Haswell-E Home Agent 1 Debug @@ -61247,6 +64577,9 @@ pci:v00008086d00002F79* pci:v00008086d00002F7D* ID_MODEL_FROM_DATABASE=Haswell-E Scratchpad & Semaphore Registers +pci:v00008086d00002F7E* + ID_MODEL_FROM_DATABASE=Haswell-E E3 QPI Link Debug + pci:v00008086d00002F80* ID_MODEL_FROM_DATABASE=Haswell-E QPI Link 0 @@ -61256,12 +64589,45 @@ pci:v00008086d00002F81* pci:v00008086d00002F83* ID_MODEL_FROM_DATABASE=Haswell-E QPI Link 0 +pci:v00008086d00002F85* + ID_MODEL_FROM_DATABASE=Haswell-E QPI Link 0 Debug + +pci:v00008086d00002F86* + ID_MODEL_FROM_DATABASE=Haswell-E QPI Link 0 Debug + +pci:v00008086d00002F87* + ID_MODEL_FROM_DATABASE=Haswell-E QPI Link 0 Debug + +pci:v00008086d00002F88* + ID_MODEL_FROM_DATABASE=Haswell-E VCU + +pci:v00008086d00002F8A* + ID_MODEL_FROM_DATABASE=Haswell-E VCU + pci:v00008086d00002F90* ID_MODEL_FROM_DATABASE=Haswell-E QPI Link 1 pci:v00008086d00002F93* ID_MODEL_FROM_DATABASE=Haswell-E QPI Link 1 +pci:v00008086d00002F95* + ID_MODEL_FROM_DATABASE=Haswell-E QPI Link 1 Debug + +pci:v00008086d00002F96* + ID_MODEL_FROM_DATABASE=Haswell-E QPI Link 1 Debug + +pci:v00008086d00002F98* + ID_MODEL_FROM_DATABASE=Haswell-E Power Control Unit + +pci:v00008086d00002F99* + ID_MODEL_FROM_DATABASE=Haswell-E Power Control Unit + +pci:v00008086d00002F9A* + ID_MODEL_FROM_DATABASE=Haswell-E Power Control Unit + +pci:v00008086d00002F9C* + ID_MODEL_FROM_DATABASE=Haswell-E Power Control Unit + pci:v00008086d00002FA0* ID_MODEL_FROM_DATABASE=Haswell-E Home Agent 0 @@ -61304,6 +64670,12 @@ pci:v00008086d00002FB4* pci:v00008086d00002FB5* ID_MODEL_FROM_DATABASE=Haswell-E Integrated Memory Controller 0 Channel 3 Thermal Control +pci:v00008086d00002FB6* + ID_MODEL_FROM_DATABASE=Haswell-E Integrated Memory Controller 0 Channel 2 ERROR Registers + +pci:v00008086d00002FB7* + ID_MODEL_FROM_DATABASE=Haswell-E Integrated Memory Controller 0 Channel 3 ERROR Registers + pci:v00008086d00002FB8* ID_MODEL_FROM_DATABASE=Haswell-E DDRIO (VMSE) 2 & 3 @@ -61335,16 +64707,16 @@ pci:v00008086d00002FC1* ID_MODEL_FROM_DATABASE=Haswell-E Power Control Unit pci:v00008086d00002FC2* - ID_MODEL_FROM_DATABASE=Power Control Unit + ID_MODEL_FROM_DATABASE=Haswell-E Power Control Unit pci:v00008086d00002FC3* - ID_MODEL_FROM_DATABASE=Power Control Unit + ID_MODEL_FROM_DATABASE=Haswell-E Power Control Unit pci:v00008086d00002FC4* - ID_MODEL_FROM_DATABASE=Power Control Unit + ID_MODEL_FROM_DATABASE=Haswell-E Power Control Unit pci:v00008086d00002FC5* - ID_MODEL_FROM_DATABASE=Power Control Unit + ID_MODEL_FROM_DATABASE=Haswell-E Power Control Unit pci:v00008086d00002FD0* ID_MODEL_FROM_DATABASE=Haswell-E Integrated Memory Controller 1 Channel 0 Thermal Control @@ -64206,226 +67578,226 @@ pci:v00008086d00008819* ID_MODEL_FROM_DATABASE=Platform Controller Hub EG20T IEEE 1588 Hardware Assist pci:v00008086d00008C00* - ID_MODEL_FROM_DATABASE=Lynx Point 4-port SATA Controller 1 [IDE mode] + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family 4-port SATA Controller 1 [IDE mode] pci:v00008086d00008C01* - ID_MODEL_FROM_DATABASE=Lynx Point 4-port SATA Controller 1 [IDE mode] + ID_MODEL_FROM_DATABASE=8 Series Chipset Family 4-port SATA Controller 1 [IDE mode] - Mobile pci:v00008086d00008C02* - ID_MODEL_FROM_DATABASE=Lynx Point 6-port SATA Controller 1 [AHCI mode] + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family 6-port SATA Controller 1 [AHCI mode] pci:v00008086d00008C03* - ID_MODEL_FROM_DATABASE=Lynx Point 6-port SATA Controller 1 [AHCI mode] + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family 6-port SATA Controller 1 [AHCI mode] pci:v00008086d00008C04* - ID_MODEL_FROM_DATABASE=Lynx Point SATA Controller 1 [RAID mode] + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family SATA Controller 1 [RAID mode] pci:v00008086d00008C05* - ID_MODEL_FROM_DATABASE=Lynx Point SATA Controller 1 [RAID mode] + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family SATA Controller 1 [RAID mode] pci:v00008086d00008C06* - ID_MODEL_FROM_DATABASE=Lynx Point SATA Controller 1 [RAID mode] + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family SATA Controller 1 [RAID mode] pci:v00008086d00008C07* - ID_MODEL_FROM_DATABASE=Lynx Point SATA Controller 1 [RAID mode] + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family SATA Controller 1 [RAID mode] pci:v00008086d00008C08* - ID_MODEL_FROM_DATABASE=Lynx Point 2-port SATA Controller 2 [IDE mode] + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family 2-port SATA Controller 2 [IDE mode] pci:v00008086d00008C09* - ID_MODEL_FROM_DATABASE=Lynx Point 2-port SATA Controller 2 [IDE mode] + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family 2-port SATA Controller 2 [IDE mode] pci:v00008086d00008C0E* - ID_MODEL_FROM_DATABASE=Lynx Point SATA Controller 1 [RAID mode] + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family SATA Controller 1 [RAID mode] pci:v00008086d00008C0F* - ID_MODEL_FROM_DATABASE=Lynx Point SATA Controller 1 [RAID mode] + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family SATA Controller 1 [RAID mode] pci:v00008086d00008C10* - ID_MODEL_FROM_DATABASE=Lynx Point PCI Express Root Port #1 + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #1 pci:v00008086d00008C11* - ID_MODEL_FROM_DATABASE=Lynx Point PCI Express Root Port #1 + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #1 pci:v00008086d00008C12* - ID_MODEL_FROM_DATABASE=Lynx Point PCI Express Root Port #2 + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #2 pci:v00008086d00008C13* - ID_MODEL_FROM_DATABASE=Lynx Point PCI Express Root Port #2 + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #2 pci:v00008086d00008C14* - ID_MODEL_FROM_DATABASE=Lynx Point PCI Express Root Port #3 + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #3 pci:v00008086d00008C15* - ID_MODEL_FROM_DATABASE=Lynx Point PCI Express Root Port #3 + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #3 pci:v00008086d00008C16* - ID_MODEL_FROM_DATABASE=Lynx Point PCI Express Root Port #4 + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #4 pci:v00008086d00008C17* - ID_MODEL_FROM_DATABASE=Lynx Point PCI Express Root Port #4 + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #4 pci:v00008086d00008C18* - ID_MODEL_FROM_DATABASE=Lynx Point PCI Express Root Port #5 + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #5 pci:v00008086d00008C19* - ID_MODEL_FROM_DATABASE=Lynx Point PCI Express Root Port #5 + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #5 pci:v00008086d00008C1A* - ID_MODEL_FROM_DATABASE=Lynx Point PCI Express Root Port #6 + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #6 pci:v00008086d00008C1B* - ID_MODEL_FROM_DATABASE=Lynx Point PCI Express Root Port #6 + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #6 pci:v00008086d00008C1C* - ID_MODEL_FROM_DATABASE=Lynx Point PCI Express Root Port #7 + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #7 pci:v00008086d00008C1D* - ID_MODEL_FROM_DATABASE=Lynx Point PCI Express Root Port #7 + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #7 pci:v00008086d00008C1E* - ID_MODEL_FROM_DATABASE=Lynx Point PCI Express Root Port #8 + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #8 pci:v00008086d00008C1F* - ID_MODEL_FROM_DATABASE=Lynx Point PCI Express Root Port #8 + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #8 pci:v00008086d00008C20* - ID_MODEL_FROM_DATABASE=Lynx Point High Definition Audio Controller + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset High Definition Audio Controller pci:v00008086d00008C21* - ID_MODEL_FROM_DATABASE=Lynx Point High Definition Audio Controller + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset High Definition Audio Controller pci:v00008086d00008C22* - ID_MODEL_FROM_DATABASE=Lynx Point SMBus Controller + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family SMBus Controller pci:v00008086d00008C23* - ID_MODEL_FROM_DATABASE=Lynx Point CHAP Counters + ID_MODEL_FROM_DATABASE=8 Series Chipset Family CHAP Counters pci:v00008086d00008C24* - ID_MODEL_FROM_DATABASE=Lynx Point Thermal Management Controller + ID_MODEL_FROM_DATABASE=8 Series Chipset Family Thermal Management Controller pci:v00008086d00008C26* - ID_MODEL_FROM_DATABASE=Lynx Point USB Enhanced Host Controller #1 + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB EHCI #1 pci:v00008086d00008C2D* - ID_MODEL_FROM_DATABASE=Lynx Point USB Enhanced Host Controller #2 + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB EHCI #2 pci:v00008086d00008C31* - ID_MODEL_FROM_DATABASE=Lynx Point USB xHCI Host Controller + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB xHCI pci:v00008086d00008C33* - ID_MODEL_FROM_DATABASE=Lynx Point LAN Controller + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family LAN Controller pci:v00008086d00008C34* - ID_MODEL_FROM_DATABASE=Lynx Point NAND Controller + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family NAND Controller pci:v00008086d00008C3A* - ID_MODEL_FROM_DATABASE=Lynx Point MEI Controller #1 + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family MEI Controller #1 pci:v00008086d00008C3B* - ID_MODEL_FROM_DATABASE=Lynx Point MEI Controller #2 + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family MEI Controller #2 pci:v00008086d00008C3C* - ID_MODEL_FROM_DATABASE=Lynx Point IDE-r Controller + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family IDE-r Controller pci:v00008086d00008C3D* - ID_MODEL_FROM_DATABASE=Lynx Point KT Controller + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family KT Controller pci:v00008086d00008C40* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family LPC Controller pci:v00008086d00008C41* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=8 Series Chipset Family Mobile Super SKU LPC Controller pci:v00008086d00008C42* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family Desktop Super SKU LPC Controller pci:v00008086d00008C43* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family LPC Controller pci:v00008086d00008C44* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=Z87 Express LPC Controller pci:v00008086d00008C45* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family LPC Controller pci:v00008086d00008C46* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=Z85 Express LPC Controller pci:v00008086d00008C47* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family LPC Controller pci:v00008086d00008C48* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family LPC Controller pci:v00008086d00008C49* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=HM86 Express LPC Controller pci:v00008086d00008C4A* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=H87 Express LPC Controller pci:v00008086d00008C4B* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=HM87 Express LPC Controller pci:v00008086d00008C4C* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=Q85 Express LPC Controller pci:v00008086d00008C4D* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family LPC Controller pci:v00008086d00008C4E* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=Q87 Express LPC Controller pci:v00008086d00008C4F* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=QM87 Express LPC Controller pci:v00008086d00008C50* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=B85 Express LPC Controller pci:v00008086d00008C51* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family LPC Controller pci:v00008086d00008C52* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=C222 Series Chipset Family Server Essential SKU LPC Controller pci:v00008086d00008C53* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family LPC Controller pci:v00008086d00008C54* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=C224 Series Chipset Family Server Standard SKU LPC Controller pci:v00008086d00008C55* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family LPC Controller pci:v00008086d00008C56* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=C226 Series Chipset Family Server Advanced SKU LPC Controller pci:v00008086d00008C57* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family LPC Controller pci:v00008086d00008C58* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family WS SKU LPC Controller pci:v00008086d00008C59* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family LPC Controller pci:v00008086d00008C5A* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family LPC Controller pci:v00008086d00008C5B* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family LPC Controller pci:v00008086d00008C5C* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=C220 Series Chipset Family H81 Express LPC Controller pci:v00008086d00008C5D* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family LPC Controller pci:v00008086d00008C5E* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family LPC Controller pci:v00008086d00008C5F* - ID_MODEL_FROM_DATABASE=Lynx Point LPC Controller + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family LPC Controller pci:v00008086d00008D00* ID_MODEL_FROM_DATABASE=Wellsburg 4-port SATA Controller [IDE mode] @@ -66332,8 +69704,35 @@ pci:v0000BD11* pci:v0000BDBD* ID_VENDOR_FROM_DATABASE=Blackmagic Design +pci:v0000BDBDd0000A117* + ID_MODEL_FROM_DATABASE=Intensity Pro + +pci:v0000BDBDd0000A11A* + ID_MODEL_FROM_DATABASE=DeckLink HD Extreme 2 + pci:v0000BDBDd0000A11B* - ID_MODEL_FROM_DATABASE=DeckLink SDI + ID_MODEL_FROM_DATABASE=DeckLink SDI/Duo/Quad + +pci:v0000BDBDd0000A11C* + ID_MODEL_FROM_DATABASE=DeckLink HD Extreme 3 + +pci:v0000BDBDd0000A11D* + ID_MODEL_FROM_DATABASE=DeckLink Studio + +pci:v0000BDBDd0000A11E* + ID_MODEL_FROM_DATABASE=DeckLink Optical Fibre + +pci:v0000BDBDd0000A121* + ID_MODEL_FROM_DATABASE=DeckLink HD Extreme 3D/3D+ + +pci:v0000BDBDd0000A12E* + ID_MODEL_FROM_DATABASE=DeckLink 4K Extreme + +pci:v0000BDBDd0000A12F* + ID_MODEL_FROM_DATABASE=DeckLink Mini Monitor + +pci:v0000BDBDd0000A130* + ID_MODEL_FROM_DATABASE=DeckLink Mini Recorder pci:v0000C001* ID_VENDOR_FROM_DATABASE=TSI Telsys @@ -66464,6 +69863,12 @@ pci:v0000D161d00008007* pci:v0000D161d00008008* ID_MODEL_FROM_DATABASE=Hx8 Series 8-port Base Card (PCI-Express) +pci:v0000D161d0000800A* + ID_MODEL_FROM_DATABASE=Wildcard TE133 single-span T1/E1/J1 card (PCI Express) + +pci:v0000D161d0000800B* + ID_MODEL_FROM_DATABASE=Wildcard TE134 single-span T1/E1/J1 card + pci:v0000D161d0000B410* ID_MODEL_FROM_DATABASE=Wildcard B410 quad-BRI card diff --git a/hwdb/20-usb-vendor-model.hwdb b/hwdb/20-usb-vendor-model.hwdb index 8c9584b358..f4ec816c69 100644 --- a/hwdb/20-usb-vendor-model.hwdb +++ b/hwdb/20-usb-vendor-model.hwdb @@ -29375,6 +29375,12 @@ usb:v0955p7030* usb:v0955p7100* ID_MODEL_FROM_DATABASE=Notion Ink Adam +usb:v0955pB400* + ID_MODEL_FROM_DATABASE=SHIELD (debug) + +usb:v0955pB401* + ID_MODEL_FROM_DATABASE=SHIELD + usb:v0956* ID_VENDOR_FROM_DATABASE=BSquare Corp. -- cgit v1.2.1 From 67410e9f73a6cdd8453c78b966451b5151def14a Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 1 Jul 2013 22:34:43 +0200 Subject: hwdb: add --device= and --filter= --- src/libudev/libudev-device.c | 2 +- src/libudev/libudev.h | 2 +- src/udev/udev-builtin-hwdb.c | 40 ++++++++++++++++++++++++++++++++++------ src/udev/udev-builtin-net_id.c | 2 +- src/udev/udev.h | 2 +- 5 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/libudev/libudev-device.c b/src/libudev/libudev-device.c index 6bb2e41510..eb43668c56 100644 --- a/src/libudev/libudev-device.c +++ b/src/libudev/libudev-device.c @@ -780,7 +780,7 @@ _public_ struct udev_device *udev_device_new_from_devnum(struct udev *udev, char * * Returns: a new udev device, or #NULL, if it does not exist **/ -_public_ struct udev_device *udev_device_new_from_device_id(struct udev *udev, char *id) +_public_ struct udev_device *udev_device_new_from_device_id(struct udev *udev, const char *id) { char type; int maj, min; diff --git a/src/libudev/libudev.h b/src/libudev/libudev.h index 61567b1d67..b9b8f13e44 100644 --- a/src/libudev/libudev.h +++ b/src/libudev/libudev.h @@ -81,7 +81,7 @@ struct udev *udev_device_get_udev(struct udev_device *udev_device); struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char *syspath); struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum); struct udev_device *udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname); -struct udev_device *udev_device_new_from_device_id(struct udev *udev, char *id); +struct udev_device *udev_device_new_from_device_id(struct udev *udev, const char *id); struct udev_device *udev_device_new_from_environment(struct udev *udev); /* udev_device_get_parent_*() does not take a reference on the returned device, it is automatically unref'd with the parent */ struct udev_device *udev_device_get_parent(struct udev_device *udev_device); diff --git a/src/udev/udev-builtin-hwdb.c b/src/udev/udev-builtin-hwdb.c index 0b35d799fe..9895f651c5 100644 --- a/src/udev/udev-builtin-hwdb.c +++ b/src/udev/udev-builtin-hwdb.c @@ -23,13 +23,15 @@ #include #include #include +#include #include #include "udev.h" static struct udev_hwdb *hwdb; -int udev_builtin_hwdb_lookup(struct udev_device *dev, const char *modalias, bool test) { +int udev_builtin_hwdb_lookup(struct udev_device *dev, + const char *modalias, const char *filter, bool test) { struct udev_list_entry *entry; int n = 0; @@ -37,6 +39,9 @@ int udev_builtin_hwdb_lookup(struct udev_device *dev, const char *modalias, bool return -ENOENT; udev_list_entry_foreach(entry, udev_hwdb_get_properties_list_entry(hwdb, modalias, 0)) { + if (filter && fnmatch(filter, udev_list_entry_get_name(entry), FNM_NOESCAPE) != 0) + continue; + if (udev_builtin_add_property(dev, test, udev_list_entry_get_name(entry), udev_list_entry_get_value(entry)) < 0) @@ -66,12 +71,13 @@ static const char *modalias_usb(struct udev_device *dev, char *s, size_t size) { return s; } -static int udev_builtin_hwdb_search(struct udev_device *dev, const char *subsystem, bool test) { +static int udev_builtin_hwdb_search(struct udev_device *dev, struct udev_device *srcdev, + const char *subsystem, const char *filter, bool test) { struct udev_device *d; char s[16]; int n = 0; - for (d = dev; d; d = udev_device_get_parent(d)) { + for (d = srcdev; d; d = udev_device_get_parent(d)) { const char *dsubsys; const char *modalias = NULL; @@ -85,14 +91,15 @@ static int udev_builtin_hwdb_search(struct udev_device *dev, const char *subsyst /* the usb_device does not have a modalias, compose one */ if (streq(dsubsys, "usb")) - modalias = modalias_usb(dev, s, sizeof(s)); + modalias = modalias_usb(d, s, sizeof(s)); if (!modalias) modalias = udev_device_get_property_value(d, "MODALIAS"); if (!modalias) continue; - n = udev_builtin_hwdb_lookup(dev, modalias, test); + + n = udev_builtin_hwdb_lookup(dev, modalias, filter, test); if (n > 0) break; } @@ -102,10 +109,15 @@ static int udev_builtin_hwdb_search(struct udev_device *dev, const char *subsyst static int builtin_hwdb(struct udev_device *dev, int argc, char *argv[], bool test) { static const struct option options[] = { + { "filter", required_argument, NULL, 'f' }, + { "device", required_argument, NULL, 'd' }, { "subsystem", required_argument, NULL, 's' }, {} }; + const char *filter = NULL; + const char *device = NULL; const char *subsystem = NULL; + struct udev_device *srcdev; if (!hwdb) return EXIT_FAILURE; @@ -118,13 +130,29 @@ static int builtin_hwdb(struct udev_device *dev, int argc, char *argv[], bool te break; switch (option) { + case 'f': + filter = optarg; + break; + + case 'd': + device = optarg; + break; + case 's': subsystem = optarg; break; } } - if (udev_builtin_hwdb_search(dev, subsystem, test) < 0) + /* read data from another device than the device we will store the data */ + if (device) { + srcdev = udev_device_new_from_device_id(udev_device_get_udev(dev), device); + if (!srcdev) + return EXIT_FAILURE; + } else + srcdev = dev; + + if (udev_builtin_hwdb_search(dev, srcdev, subsystem, filter, test) < 0) return EXIT_FAILURE; return EXIT_SUCCESS; } diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c index 5b732bb418..e1d8087122 100644 --- a/src/udev/udev-builtin-net_id.c +++ b/src/udev/udev-builtin-net_id.c @@ -396,7 +396,7 @@ static int ieee_oui(struct udev_device *dev, struct netnames *names, bool test) snprintf(str, sizeof(str), "OUI:%02X%02X%02X%02X%02X%02X", names->mac[0], names->mac[1], names->mac[2], names->mac[3], names->mac[4], names->mac[5]); - udev_builtin_hwdb_lookup(dev, str, test); + udev_builtin_hwdb_lookup(dev, str, NULL, test); return 0; } diff --git a/src/udev/udev.h b/src/udev/udev.h index caec5f0a5d..d5f8cd7dcf 100644 --- a/src/udev/udev.h +++ b/src/udev/udev.h @@ -190,7 +190,7 @@ int udev_builtin_run(struct udev_device *dev, enum udev_builtin_cmd cmd, const c void udev_builtin_list(struct udev *udev); bool udev_builtin_validate(struct udev *udev); int udev_builtin_add_property(struct udev_device *dev, bool test, const char *key, const char *val); -int udev_builtin_hwdb_lookup(struct udev_device *dev, const char *modalias, bool test); +int udev_builtin_hwdb_lookup(struct udev_device *dev, const char *modalias, const char *filter, bool test); /* udev logging */ void udev_main_log(struct udev *udev, int priority, -- cgit v1.2.1 From eb2059d897dbf2c5e4bc97fb950e8e5defa72f13 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 1 Jul 2013 23:55:34 +0200 Subject: keymap: remove non-existing driver string matches There are no such strings for input devices in the kernel. --- Makefile.am | 1 - keymaps/module-asus-w3j | 11 ----------- src/udev/keymap/95-keymap.rules | 2 -- 3 files changed, 14 deletions(-) delete mode 100644 keymaps/module-asus-w3j diff --git a/Makefile.am b/Makefile.am index 4593245d40..e79756e30b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2591,7 +2591,6 @@ dist_udevkeymap_DATA = \ keymaps/medion-fid2060 \ keymaps/medionnb-a555 \ keymaps/micro-star \ - keymaps/module-asus-w3j \ keymaps/module-ibm \ keymaps/module-lenovo \ keymaps/module-sony \ diff --git a/keymaps/module-asus-w3j b/keymaps/module-asus-w3j deleted file mode 100644 index 773e0b3e82..0000000000 --- a/keymaps/module-asus-w3j +++ /dev/null @@ -1,11 +0,0 @@ -0x41 nextsong -0x45 playpause -0x43 stopcd -0x40 previoussong -0x4C ejectclosecd -0x32 mute -0x31 volumedown -0x30 volumeup -0x5D wlan -0x7E bluetooth -0x8A media # high keycode: "tv" diff --git a/src/udev/keymap/95-keymap.rules b/src/udev/keymap/95-keymap.rules index 30c28a480d..60d39a85dd 100644 --- a/src/udev/keymap/95-keymap.rules +++ b/src/udev/keymap/95-keymap.rules @@ -45,10 +45,8 @@ ENV{DMI_VENDOR}="$attr{[dmi/id]sys_vendor}" ENV{DMI_VENDOR}=="", GOTO="keyboard_end" ENV{DMI_VENDOR}=="LENOVO*", KERNELS=="input*", ATTRS{name}=="ThinkPad Extra Buttons", RUN+="keymap $name module-lenovo" -ENV{DMI_VENDOR}=="LENOVO*", KERNELS=="input*", ATTRS{name}=="Lenovo ThinkPad SL Series extra buttons", RUN+="keymap $name 0x0E bluetooth" ENV{DMI_VENDOR}=="LENOVO*", KERNELS=="input*", ATTRS{name}=="Ideapad extra buttons", RUN+="keymap $name 0x42 f23 0x43 f22" -ENV{DMI_VENDOR}=="ASUS*", KERNELS=="input*", ATTRS{name}=="Asus Extra Buttons", ATTR{[dmi/id]product_name}=="W3J", RUN+="keymap $name module-asus-w3j" ENV{DMI_VENDOR}=="ASUS*", KERNELS=="input*", ATTRS{name}=="Asus Laptop extra buttons", RUN+="keymap $name 0x6B f21" ENV{DMI_VENDOR}=="ASUS*", KERNELS=="input*", ATTRS{name}=="Asus Laptop Support", RUN+="keymap $name 0x6B f21" ENV{DMI_VENDOR}=="ASUS*", KERNELS=="input*", ATTRS{name}=="Asus WMI hotkeys", RUN+="keymap $name 0x6B f21" -- cgit v1.2.1 From cc23f9f17434aad3941dff3c20bce485b39ce47c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 2 Jul 2013 01:34:04 +0200 Subject: scope: make TimeoutStopUSec= settable for transient units --- src/core/dbus-scope.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/core/dbus-scope.c b/src/core/dbus-scope.c index bddf8f4753..0205cfff6e 100644 --- a/src/core/dbus-scope.c +++ b/src/core/dbus-scope.c @@ -126,6 +126,21 @@ static int bus_scope_set_transient_property( return -EINVAL; return 1; + + } else if (streq(name, "TimeoutStopUSec")) { + + if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_UINT64) + return -EINVAL; + + if (mode != UNIT_CHECK) { + uint64_t t; + + dbus_message_iter_get_basic(i, &t); + + s->timeout_stop_usec = t; + } + + return 1; } return 0; -- cgit v1.2.1 From ede3a7967560506486e1e25d09ef4e74600851ff Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 2 Jul 2013 01:35:08 +0200 Subject: core: split out unit bus path unescaping into unit_name_from_dbus_path() --- src/core/manager.c | 13 ++++--------- src/shared/unit-name.c | 16 ++++++++++++++++ src/shared/unit-name.h | 1 + 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/core/manager.c b/src/core/manager.c index 42c9bcd48c..080561b5d1 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -1783,7 +1783,7 @@ int manager_loop(Manager *m) { } int manager_load_unit_from_dbus_path(Manager *m, const char *s, DBusError *e, Unit **_u) { - char *n; + _cleanup_free_ char *n = NULL; Unit *u; int r; @@ -1791,16 +1791,11 @@ int manager_load_unit_from_dbus_path(Manager *m, const char *s, DBusError *e, Un assert(s); assert(_u); - if (!startswith(s, "/org/freedesktop/systemd1/unit/")) - return -EINVAL; - - n = bus_path_unescape(s+31); - if (!n) - return -ENOMEM; + r = unit_name_from_dbus_path(s, &n); + if (r < 0) + return r; r = manager_load_unit(m, n, NULL, e, &u); - free(n); - if (r < 0) return r; diff --git a/src/shared/unit-name.c b/src/shared/unit-name.c index f2c30a6e4f..7733aae0e7 100644 --- a/src/shared/unit-name.c +++ b/src/shared/unit-name.c @@ -467,6 +467,22 @@ char *unit_dbus_path_from_name(const char *name) { return strappend("/org/freedesktop/systemd1/unit/", e); } +int unit_name_from_dbus_path(const char *path, char **name) { + const char *e; + char *n; + + e = startswith(path, "/org/freedesktop/systemd1/unit/"); + if (!e) + return -EINVAL; + + n = bus_path_unescape(e); + if (!n) + return -ENOMEM; + + *name = n; + return 0; +} + char *unit_name_mangle(const char *name) { char *r, *t; const char *f; diff --git a/src/shared/unit-name.h b/src/shared/unit-name.h index 88f2b83443..7f4ae56433 100644 --- a/src/shared/unit-name.h +++ b/src/shared/unit-name.h @@ -95,6 +95,7 @@ char *unit_name_from_path_instance(const char *prefix, const char *path, const c char *unit_name_to_path(const char *name); char *unit_dbus_path_from_name(const char *name); +int unit_name_from_dbus_path(const char *path, char **name); char *unit_name_mangle(const char *name); char *unit_name_mangle_with_suffix(const char *name, const char *suffix); -- cgit v1.2.1 From 8bcca7e201b235a7e7ea28d735db142ad96b9d64 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 2 Jul 2013 01:35:35 +0200 Subject: scope: implement reset-failed command --- src/core/scope.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/core/scope.c b/src/core/scope.c index f88addadf3..e1a3545dbb 100644 --- a/src/core/scope.c +++ b/src/core/scope.c @@ -283,6 +283,17 @@ static int scope_stop(Unit *u) { return 0; } +static void scope_reset_failed(Unit *u) { + Scope *s = SCOPE(u); + + assert(s); + + if (s->state == SCOPE_FAILED) + scope_set_state(s, SCOPE_DEAD); + + s->result = SCOPE_SUCCESS; +} + static int scope_kill(Unit *u, KillWho who, int signo, DBusError *error) { return unit_kill_common(u, who, signo, -1, -1, error); } @@ -455,6 +466,8 @@ const UnitVTable scope_vtable = { .timer_event = scope_timer_event, + .reset_failed = scope_reset_failed, + .notify_cgroup_empty = scope_notify_cgroup_empty_event, .bus_interface = "org.freedesktop.systemd1.Scope", -- cgit v1.2.1 From 358712f3de33789b2d1293825f1add2c6f4b8e66 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 2 Jul 2013 01:35:58 +0200 Subject: scope: fix state string table --- src/core/scope.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/scope.c b/src/core/scope.c index e1a3545dbb..e0de951b11 100644 --- a/src/core/scope.c +++ b/src/core/scope.c @@ -414,7 +414,7 @@ _pure_ static const char *scope_sub_state_to_string(Unit *u) { static const char* const scope_state_table[_SCOPE_STATE_MAX] = { [SCOPE_DEAD] = "dead", - [SCOPE_RUNNING] = "active", + [SCOPE_RUNNING] = "running", [SCOPE_STOP_SIGTERM] = "stop-sigterm", [SCOPE_STOP_SIGKILL] = "stop-sigkill", [SCOPE_FAILED] = "failed", -- cgit v1.2.1 From fb6becb4436ae4078337011b2017ce294e7361cf Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 2 Jul 2013 01:46:30 +0200 Subject: logind: port over to use scopes+slices for all cgroup stuff In order to prepare things for the single-writer cgroup scheme, let's make logind use systemd's own primitives for cgroup management. Every login user now gets his own private slice unit, in which his sessions live in a scope unit each. Also, add user@$UID.service to the same slice, and implicitly start it on first login. --- TODO | 16 ++ src/core/bus-errors.h | 1 + src/login/logind-dbus.c | 578 +++++++++++++++++++++++++++++----------- src/login/logind-gperf.gperf | 2 - src/login/logind-machine-dbus.c | 89 +++++-- src/login/logind-machine.c | 220 ++++++--------- src/login/logind-machine.h | 23 +- src/login/logind-session-dbus.c | 99 +++++-- src/login/logind-session.c | 334 ++++++----------------- src/login/logind-session.h | 16 +- src/login/logind-user-dbus.c | 20 -- src/login/logind-user.c | 240 +++++++++-------- src/login/logind-user.h | 8 +- src/login/logind.c | 231 +++++----------- src/login/logind.conf | 2 - src/login/logind.h | 21 +- src/login/pam-module.c | 183 +------------ src/shared/unit-name.c | 27 ++ src/shared/unit-name.h | 2 + src/systemctl/systemctl.c | 2 +- units/user@.service.in | 6 +- 21 files changed, 1010 insertions(+), 1110 deletions(-) diff --git a/TODO b/TODO index e8afa5f3df..cde2ced312 100644 --- a/TODO +++ b/TODO @@ -28,6 +28,22 @@ Fedora 19: Features: +* libsystemd-logind: recognize new session/user/machine units + +* logind: implement session kill exceptions + +* fix machine regstration to forward property array + +* fix loginctl cgroup enumeration + +* move "systemctl dump" to systemd-analyze + +* introduce "mainpid" for scopes + +* add a fixed dbus path for "my own unit", "my own session", ... to PID1, logind, ... + +* add implicit slice for instantiated services + * service_coldplug() appears to reinstall the wrong stop timeout watch? * transient units: allow creating auxiliary units with the same call diff --git a/src/core/bus-errors.h b/src/core/bus-errors.h index 7a4084ea15..9368d68e80 100644 --- a/src/core/bus-errors.h +++ b/src/core/bus-errors.h @@ -40,3 +40,4 @@ #define BUS_ERROR_TRANSACTION_ORDER_IS_CYCLIC "org.freedesktop.systemd1.TransactionOrderIsCyclic" #define BUS_ERROR_SHUTTING_DOWN "org.freedesktop.systemd1.ShuttingDown" #define BUS_ERROR_NO_SUCH_PROCESS "org.freedesktop.systemd1.NoSuchProcess" +#define BUS_ERROR_JOB_FAILED "org.freedesktop.systemd1.JobFailed" diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 631006924f..d8d25b0041 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -38,6 +38,8 @@ #include "label.h" #include "utf8.h" #include "unit-name.h" +#include "bus-errors.h" +#include "virt.h" #define BUS_MANAGER_INTERFACE \ " \n" \ @@ -94,9 +96,7 @@ " \n" \ " \n" \ " \n" \ - " \n" \ - " \n" \ - " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ @@ -114,8 +114,8 @@ " \n" \ " \n" \ " \n" \ - " \n" \ " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ @@ -345,27 +345,24 @@ static int bus_manager_append_preparing(DBusMessageIter *i, const char *property return 0; } -static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMessage **_reply) { +static int bus_manager_create_session(Manager *m, DBusMessage *message) { + const char *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *service; uint32_t uid, leader, audit_id = 0; - dbus_bool_t remote, kill_processes, exists; - _cleanup_strv_free_ char **controllers = NULL, **reset_controllers = NULL; - _cleanup_free_ char *cgroup = NULL, *id = NULL, *p = NULL; - SessionType t; - SessionClass c; - DBusMessageIter iter; - int r; - uint32_t vtnr = 0; - _cleanup_close_ int fifo_fd = -1; - _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + _cleanup_free_ char *id = NULL; Session *session = NULL; User *user = NULL; Seat *seat = NULL; + DBusMessageIter iter; + dbus_bool_t remote; + uint32_t vtnr = 0; + SessionType t; + SessionClass c; bool b; + int r; assert(m); assert(message); - assert(_reply); if (!dbus_message_iter_init(message, &iter) || dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) @@ -515,67 +512,37 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess dbus_message_iter_get_basic(&iter, &remote_host); - if (!dbus_message_iter_next(&iter) || - dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || - dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRING) - return -EINVAL; - - r = bus_parse_strv_iter(&iter, &controllers); - if (r < 0) - return -EINVAL; - - if (!dbus_message_iter_next(&iter) || - dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || - dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRING) { - r = -EINVAL; - goto fail; - } - - r = bus_parse_strv_iter(&iter, &reset_controllers); - if (r < 0) - goto fail; - - if (!dbus_message_iter_next(&iter) || - dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN) { - r = -EINVAL; - goto fail; - } - - dbus_message_iter_get_basic(&iter, &kill_processes); - if (leader <= 0) { leader = bus_get_unix_process_id(m->bus, dbus_message_get_sender(message), NULL); if (leader == 0) return -EINVAL; } - r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, leader, &cgroup); - if (r < 0) - goto fail; + r = manager_get_session_by_pid(m, leader, &session); + if (session) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + _cleanup_free_ char *path = NULL; + _cleanup_close_ int fifo_fd = -1; + bool exists; - r = manager_get_session_by_cgroup(m, cgroup, &session); - if (r < 0) - goto fail; + /* Session already exists, client is probably + * something like "su" which changes uid but is still + * the same session */ - if (session) { fifo_fd = session_create_fifo(session); if (fifo_fd < 0) { r = fifo_fd; goto fail; } - /* Session already exists, client is probably - * something like "su" which changes uid but - * is still the same audit session */ - - reply = dbus_message_new_method_return(message); - if (!reply) { + path = session_bus_path(session); + if (!path) { r = -ENOMEM; goto fail; } - p = session_bus_path(session); - if (!p) { + reply = dbus_message_new_method_return(message); + if (!reply) { r = -ENOMEM; goto fail; } @@ -587,7 +554,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess b = dbus_message_append_args( reply, DBUS_TYPE_STRING, &session->id, - DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_STRING, &session->user->runtime_path, DBUS_TYPE_UNIX_FD, &fifo_fd, DBUS_TYPE_STRING, &cseat, @@ -599,8 +566,10 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess goto fail; } - *_reply = reply; - reply = NULL; + if (!dbus_connection_send(m->bus, reply, NULL)) { + r = -ENOMEM; + goto fail; + } return 0; } @@ -654,13 +623,8 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess session->type = t; session->class = c; session->remote = remote; - session->kill_processes = kill_processes; session->vtnr = vtnr; - session->controllers = cg_shorten_controllers(controllers); - session->reset_controllers = cg_shorten_controllers(reset_controllers); - controllers = reset_controllers = NULL; - if (!isempty(tty)) { session->tty = strdup(tty); if (!session->tty) { @@ -701,12 +665,6 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess } } - fifo_fd = session_create_fifo(session); - if (fifo_fd < 0) { - r = fifo_fd; - goto fail; - } - if (seat) { r = seat_attach_session(seat, session); if (r < 0) @@ -717,38 +675,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess if (r < 0) goto fail; - reply = dbus_message_new_method_return(message); - if (!reply) { - r = -ENOMEM; - goto fail; - } - - p = session_bus_path(session); - if (!p) { - r = -ENOMEM; - goto fail; - } - - cseat = seat ? seat->id : ""; - exists = false; - b = dbus_message_append_args( - reply, - DBUS_TYPE_STRING, &session->id, - DBUS_TYPE_OBJECT_PATH, &p, - DBUS_TYPE_STRING, &session->user->runtime_path, - DBUS_TYPE_UNIX_FD, &fifo_fd, - DBUS_TYPE_STRING, &cseat, - DBUS_TYPE_UINT32, &vtnr, - DBUS_TYPE_BOOLEAN, &exists, - DBUS_TYPE_INVALID); - - if (!b) { - r = -ENOMEM; - goto fail; - } - - *_reply = reply; - reply = NULL; + session->create_message = dbus_message_ref(message); return 0; @@ -779,26 +706,20 @@ static bool valid_machine_name(const char *p) { return true; } -static int bus_manager_create_machine( - Manager *manager, - DBusMessage *message, - DBusMessage **_reply) { +static int bus_manager_create_machine(Manager *manager, DBusMessage *message) { const char *name, *service, *class, *slice, *root_directory; - _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; _cleanup_free_ char *p = NULL; DBusMessageIter iter, sub; MachineClass c; uint32_t leader; sd_id128_t id; - dbus_bool_t b; Machine *m; int n, r; void *v; assert(manager); assert(message); - assert(_reply); if (!dbus_message_iter_init(message, &iter) || dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) @@ -887,14 +808,6 @@ static int bus_manager_create_machine( } } - if (!isempty(slice)) { - m->slice = strdup(slice); - if (!m->slice) { - r = -ENOMEM; - goto fail; - } - } - if (!isempty(root_directory)) { m->root_directory = strdup(root_directory); if (!m->root_directory) { @@ -907,29 +820,8 @@ static int bus_manager_create_machine( if (r < 0) goto fail; - reply = dbus_message_new_method_return(message); - if (!reply) { - r = -ENOMEM; - goto fail; - } - - p = machine_bus_path(m); - if (!p) { - r = -ENOMEM; - goto fail; - } - - b = dbus_message_append_args( - reply, - DBUS_TYPE_OBJECT_PATH, &p, - DBUS_TYPE_INVALID); - if (!b) { - r = -ENOMEM; - goto fail; - } + m->create_message = dbus_message_ref(message); - *_reply = reply; - reply = NULL; return 0; fail: @@ -1608,8 +1500,6 @@ static int bus_manager_do_shutdown_or_sleep( static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_manager_append_handle_action, handle_action, HandleAction); static const BusProperty bus_login_manager_properties[] = { - { "Controllers", bus_property_append_strv, "as", offsetof(Manager, controllers), true }, - { "ResetControllers", bus_property_append_strv, "as", offsetof(Manager, reset_controllers), true }, { "NAutoVTs", bus_property_append_unsigned, "u", offsetof(Manager, n_autovts) }, { "KillOnlyUsers", bus_property_append_strv, "as", offsetof(Manager, kill_only_users), true }, { "KillExcludeUsers", bus_property_append_strv, "as", offsetof(Manager, kill_exclude_users), true }, @@ -2109,7 +1999,7 @@ static DBusHandlerResult manager_message_handler( } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "CreateSession")) { - r = bus_manager_create_session(m, message, &reply); + r = bus_manager_create_session(m, message); /* Don't delay the work on OOM here, since it might be * triggered by a low RLIMIT_NOFILE here (since we @@ -2118,9 +2008,10 @@ static DBusHandlerResult manager_message_handler( if (r < 0) return bus_send_error_reply(connection, message, NULL, r); + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "CreateMachine")) { - r = bus_manager_create_machine(m, message, &reply); + r = bus_manager_create_machine(m, message); if (r < 0) return bus_send_error_reply(connection, message, NULL, r); @@ -2753,7 +2644,7 @@ static DBusHandlerResult manager_message_handler( if (reply) { if (!bus_maybe_send_reply(connection, message, reply)) - goto oom; + goto oom; } return DBUS_HANDLER_RESULT_HANDLED; @@ -2782,29 +2673,23 @@ DBusHandlerResult bus_message_filter( dbus_error_init(&error); - if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Agent", "Released")) { - const char *cgroup; + log_debug("Got message: %s %s %s", strna(dbus_message_get_sender(message)), strna(dbus_message_get_interface(message)), strna(dbus_message_get_member(message))); - if (!dbus_message_get_args(message, &error, - DBUS_TYPE_STRING, &cgroup, - DBUS_TYPE_INVALID)) - log_error("Failed to parse Released message: %s", bus_error_message(&error)); - else - manager_cgroup_notify_empty(m, cgroup); - - } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Manager", "JobRemoved")) { - uint32_t id; + if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Manager", "JobRemoved")) { const char *path, *result, *unit; + uint32_t id; if (!dbus_message_get_args(message, &error, DBUS_TYPE_UINT32, &id, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_STRING, &unit, DBUS_TYPE_STRING, &result, - DBUS_TYPE_INVALID)) + DBUS_TYPE_INVALID)) { log_error("Failed to parse JobRemoved message: %s", bus_error_message(&error)); + goto finish; + } - else if (m->action_job && streq(m->action_job, path)) { + if (m->action_job && streq(m->action_job, path)) { log_info("Operation finished."); /* Tell people that they now may take a lock again */ @@ -2814,9 +2699,97 @@ DBusHandlerResult bus_message_filter( m->action_job = NULL; m->action_unit = NULL; m->action_what = 0; + + } else { + Machine *mm; + Session *s; + User *u; + + s = hashmap_get(m->session_units, unit); + if (s) { + if (streq_ptr(path, s->scope_job)) { + free(s->scope_job); + s->scope_job = NULL; + + if (s->started) { + if (streq(result, "done")) + session_send_create_reply(s, NULL); + else { + dbus_set_error(&error, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result); + session_send_create_reply(s, &error); + } + } + } + + session_add_to_gc_queue(s); + } + + u = hashmap_get(m->user_units, unit); + if (u) { + if (streq_ptr(path, u->service_job)) { + free(u->service_job); + u->service_job = NULL; + } + + if (streq_ptr(path, u->slice_job)) { + free(u->slice_job); + u->slice_job = NULL; + } + + user_add_to_gc_queue(u); + } + + mm = hashmap_get(m->machine_units, unit); + if (mm) { + if (streq_ptr(path, mm->scope_job)) { + free(mm->scope_job); + mm->scope_job = NULL; + + if (mm->started) { + if (streq(result, "done")) + machine_send_create_reply(mm, NULL); + else { + dbus_set_error(&error, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result); + machine_send_create_reply(mm, &error); + } + } + } + + machine_add_to_gc_queue(mm); + } + } + + } else if (dbus_message_is_signal(message, "org.freedesktop.DBus.Properties", "PropertiesChanged")) { + + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + _cleanup_free_ char *unit = NULL; + const char *path; + + path = dbus_message_get_path(message); + if (!path) + goto finish; + + unit_name_from_dbus_path(path, &unit); + if (unit) { + Machine *mm; + Session *s; + User *u; + + s = hashmap_get(m->session_units, unit); + if (s) + session_add_to_gc_queue(s); + + u = hashmap_get(m->user_units, unit); + if (u) + user_add_to_gc_queue(u); + + mm = hashmap_get(m->machine_units, unit); + if (mm) + machine_add_to_gc_queue(mm); } } +finish: dbus_error_free(&error); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; @@ -2871,3 +2844,288 @@ int manager_dispatch_delayed(Manager *manager) { return 1; } + +int manager_start_scope( + Manager *manager, + const char *scope, + pid_t pid, + const char *slice, + const char *description, + DBusError *error, + char **job) { + + _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL; + DBusMessageIter iter, sub, sub2, sub3, sub4; + const char *timeout_stop_property = "TimeoutStopUSec"; + const char *pids_property = "PIDs"; + uint64_t timeout = 500 * USEC_PER_MSEC; + const char *fail = "fail"; + uint32_t u; + + assert(manager); + assert(scope); + assert(pid > 1); + + if (!slice) + slice = ""; + + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "StartTransientUnit"); + if (!m) + return log_oom(); + + dbus_message_iter_init_append(m, &iter); + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &scope) || + !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &fail) || + !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(sv)", &sub)) + return log_oom(); + + if (!isempty(slice)) { + const char *slice_property = "Slice"; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &slice_property) || + !dbus_message_iter_open_container(&sub2, DBUS_TYPE_VARIANT, "s", &sub3) || + !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, &slice) || + !dbus_message_iter_close_container(&sub2, &sub3) || + !dbus_message_iter_close_container(&sub, &sub2)) + return log_oom(); + } + + if (!isempty(description)) { + const char *description_property = "Description"; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &description_property) || + !dbus_message_iter_open_container(&sub2, DBUS_TYPE_VARIANT, "s", &sub3) || + !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, &description) || + !dbus_message_iter_close_container(&sub2, &sub3) || + !dbus_message_iter_close_container(&sub, &sub2)) + return log_oom(); + } + + /* cgroup empty notification is not available in containers + * currently. To make this less problematic, let's shorten the + * stop timeout for sessions, so that we don't wait + * forever. */ + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &timeout_stop_property) || + !dbus_message_iter_open_container(&sub2, DBUS_TYPE_VARIANT, "t", &sub3) || + !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_UINT64, &timeout) || + !dbus_message_iter_close_container(&sub2, &sub3) || + !dbus_message_iter_close_container(&sub, &sub2)) + return log_oom(); + + u = pid; + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &pids_property) || + !dbus_message_iter_open_container(&sub2, DBUS_TYPE_VARIANT, "au", &sub3) || + !dbus_message_iter_open_container(&sub3, DBUS_TYPE_ARRAY, "u", &sub4) || + !dbus_message_iter_append_basic(&sub4, DBUS_TYPE_UINT32, &u) || + !dbus_message_iter_close_container(&sub3, &sub4) || + !dbus_message_iter_close_container(&sub2, &sub3) || + !dbus_message_iter_close_container(&sub, &sub2) || + !dbus_message_iter_close_container(&iter, &sub)) + return log_oom(); + + reply = dbus_connection_send_with_reply_and_block(manager->bus, m, -1, error); + if (!reply) + return -EIO; + + if (job) { + const char *j; + char *copy; + + if (!dbus_message_get_args(reply, error, DBUS_TYPE_OBJECT_PATH, &j, DBUS_TYPE_INVALID)) + return -EIO; + + copy = strdup(j); + if (!copy) + return -ENOMEM; + + *job = copy; + } + + return 0; +} + +int manager_start_unit(Manager *manager, const char *unit, DBusError *error, char **job) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + const char *fail = "fail"; + int r; + + assert(manager); + assert(unit); + + r = bus_method_call_with_reply( + manager->bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "StartUnit", + &reply, + error, + DBUS_TYPE_STRING, &unit, + DBUS_TYPE_STRING, &fail, + DBUS_TYPE_INVALID); + if (r < 0) { + log_error("Failed to start unit %s: %s", unit, bus_error(error, r)); + return r; + } + + if (job) { + const char *j; + char *copy; + + if (!dbus_message_get_args(reply, error, + DBUS_TYPE_OBJECT_PATH, &j, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse reply."); + return -EIO; + } + + copy = strdup(j); + if (!copy) + return -ENOMEM; + + *job = copy; + } + + return 0; +} + +int manager_stop_unit(Manager *manager, const char *unit, DBusError *error, char **job) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + const char *fail = "fail"; + int r; + + assert(manager); + assert(unit); + + r = bus_method_call_with_reply( + manager->bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "StopUnit", + &reply, + error, + DBUS_TYPE_STRING, &unit, + DBUS_TYPE_STRING, &fail, + DBUS_TYPE_INVALID); + if (r < 0) { + log_error("Failed to stop unit %s: %s", unit, bus_error(error, r)); + return r; + } + + if (job) { + const char *j; + char *copy; + + if (!dbus_message_get_args(reply, error, + DBUS_TYPE_OBJECT_PATH, &j, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse reply."); + return -EIO; + } + + copy = strdup(j); + if (!copy) + return -ENOMEM; + + *job = copy; + } + + return 0; +} + +int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, DBusError *error) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + const char *w; + int r; + + assert(manager); + assert(unit); + + w = who == KILL_LEADER ? "process" : "cgroup"; + assert_cc(sizeof(signo) == sizeof(int32_t)); + + r = bus_method_call_with_reply( + manager->bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "KillUnit", + &reply, + error, + DBUS_TYPE_STRING, &unit, + DBUS_TYPE_STRING, &w, + DBUS_TYPE_INT32, &signo, + DBUS_TYPE_INVALID); + if (r < 0) { + log_error("Failed to stop unit %s: %s", unit, bus_error(error, r)); + return r; + } + + return 0; +} + +int manager_unit_is_active(Manager *manager, const char *unit) { + + const char *interface = "org.freedesktop.systemd1.Unit"; + const char *property = "ActiveState"; + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + _cleanup_free_ char *path = NULL; + DBusMessageIter iter, sub; + const char *state; + DBusError error; + int r; + + assert(manager); + assert(unit); + + dbus_error_init(&error); + + path = unit_dbus_path_from_name(unit); + if (!path) + return -ENOMEM; + + r = bus_method_call_with_reply( + manager->bus, + "org.freedesktop.systemd1", + path, + "org.freedesktop.DBus.Properties", + "Get", + &reply, + &error, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_STRING, &property, + DBUS_TYPE_INVALID); + + if (r < 0) { + log_error("Failed to query ActiveState: %s", bus_error(&error, r)); + dbus_error_free(&error); + return r; + } + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) { + log_error("Failed to parse reply."); + return -EINVAL; + } + + dbus_message_iter_recurse(&iter, &sub); + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) { + log_error("Failed to parse reply."); + return -EINVAL; + } + + dbus_message_iter_get_basic(&sub, &state); + + return !streq(state, "inactive") && !streq(state, "failed"); +} diff --git a/src/login/logind-gperf.gperf b/src/login/logind-gperf.gperf index 735d2dbc9c..845302a54d 100644 --- a/src/login/logind-gperf.gperf +++ b/src/login/logind-gperf.gperf @@ -19,8 +19,6 @@ Login.ReserveVT, config_parse_unsigned, 0, offsetof(Manag Login.KillUserProcesses, config_parse_bool, 0, offsetof(Manager, kill_user_processes) Login.KillOnlyUsers, config_parse_strv, 0, offsetof(Manager, kill_only_users) Login.KillExcludeUsers, config_parse_strv, 0, offsetof(Manager, kill_exclude_users) -Login.Controllers, config_parse_strv, 0, offsetof(Manager, controllers) -Login.ResetControllers, config_parse_strv, 0, offsetof(Manager, reset_controllers) Login.InhibitDelayMaxSec, config_parse_sec, 0, offsetof(Manager, inhibit_delay_max) Login.HandlePowerKey, config_parse_handle_action, 0, offsetof(Manager, handle_power_key) Login.HandleSuspendKey, config_parse_handle_action, 0, offsetof(Manager, handle_suspend_key) diff --git a/src/login/logind-machine-dbus.c b/src/login/logind-machine-dbus.c index 7feea2e92a..ae8c5d720a 100644 --- a/src/login/logind-machine-dbus.c +++ b/src/login/logind-machine-dbus.c @@ -37,11 +37,11 @@ " \n" \ " \n" \ " \n" \ - " \n" \ " \n" \ - " \n" \ + " \n" \ " \n" \ " \n" \ + " \n" \ " \n" \ " \n" @@ -58,24 +58,6 @@ BUS_GENERIC_INTERFACES_LIST \ "org.freedesktop.login1.Machine\0" -static int bus_machine_append_default_cgroup(DBusMessageIter *i, const char *property, void *data) { - _cleanup_free_ char *t = NULL; - Machine *m = data; - int r; - bool success; - - assert(i); - assert(property); - assert(m); - - r = cg_join_spec(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_path, &t); - if (r < 0) - return r; - - success = dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t); - return success ? 0 : -ENOMEM; -} - static int bus_machine_append_id(DBusMessageIter *i, const char *property, void *data) { DBusMessageIter sub; Machine *m = data; @@ -100,6 +82,22 @@ static int bus_machine_append_id(DBusMessageIter *i, const char *property, void return 0; } +static int bus_machine_append_state(DBusMessageIter *i, const char *property, void *data) { + Machine *m = data; + const char *state; + + assert(i); + assert(property); + assert(m); + + state = machine_state_to_string(machine_get_state(m)); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &state)) + return -ENOMEM; + + return 0; +} + static int get_machine_for_path(Manager *m, const char *path, Machine **_machine) { _cleanup_free_ char *e = NULL; Machine *machine; @@ -130,11 +128,11 @@ static const BusProperty bus_login_machine_properties[] = { { "Id", bus_machine_append_id, "ay", 0 }, { "Timestamp", bus_property_append_usec, "t", offsetof(Machine, timestamp.realtime) }, { "TimestampMonotonic", bus_property_append_usec, "t", offsetof(Machine, timestamp.monotonic) }, - { "DefaultControlGroup", bus_machine_append_default_cgroup, "s", 0 }, { "Service", bus_property_append_string, "s", offsetof(Machine, service), true }, - { "Slice", bus_property_append_string, "s", offsetof(Machine, slice), true }, + { "Scope", bus_property_append_string, "s", offsetof(Machine, scope), true }, { "Leader", bus_property_append_pid, "u", offsetof(Session, leader) }, { "Class", bus_machine_append_class, "s", offsetof(Machine, class) }, + { "State", bus_machine_append_state, "s", 0 }, { "RootDirectory", bus_property_append_string, "s", offsetof(Machine, root_directory), true }, { NULL, } }; @@ -313,3 +311,50 @@ int machine_send_changed(Machine *m, const char *properties) { return 0; } + +int machine_send_create_reply(Machine *m, DBusError *error) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + + assert(m); + + if (!m->create_message) + return 0; + + if (error) { + DBusError buffer; + + dbus_error_init(&buffer); + + if (!error || !dbus_error_is_set(error)) { + dbus_set_error_const(&buffer, DBUS_ERROR_INVALID_ARGS, "Invalid Arguments"); + error = &buffer; + } + + reply = dbus_message_new_error(m->create_message, error->name, error->message); + dbus_error_free(&buffer); + + if (!reply) + return log_oom(); + } else { + _cleanup_free_ char *p = NULL; + + p = machine_bus_path(m); + if (!p) + return log_oom(); + + reply = dbus_message_new_method_return(m->create_message); + if (!reply) + return log_oom(); + + if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &p, DBUS_TYPE_INVALID)) + return log_oom(); + } + + if (!dbus_connection_send(m->manager->bus, reply, NULL)) + return log_oom(); + + dbus_message_unref(m->create_message); + m->create_message = NULL; + + return 0; +} diff --git a/src/login/logind-machine.c b/src/login/logind-machine.c index 0b35a9e2d0..e4edd40dba 100644 --- a/src/login/logind-machine.c +++ b/src/login/logind-machine.c @@ -23,7 +23,8 @@ #include #include -#include "logind-machine.h" +#include + #include "util.h" #include "mkdir.h" #include "cgroup-util.h" @@ -31,7 +32,9 @@ #include "strv.h" #include "fileio.h" #include "special.h" -#include +#include "unit-name.h" +#include "dbus-common.h" +#include "logind-machine.h" Machine* machine_new(Manager *manager, const char *name) { Machine *m; @@ -73,17 +76,21 @@ void machine_free(Machine *m) { if (m->in_gc_queue) LIST_REMOVE(Machine, gc_queue, m->manager->machine_gc_queue, m); - if (m->cgroup_path) { - hashmap_remove(m->manager->machine_cgroups, m->cgroup_path); - free(m->cgroup_path); + if (m->scope) { + hashmap_remove(m->manager->machine_units, m->scope); + free(m->scope); } + free(m->scope_job); + hashmap_remove(m->manager->machines, m->name); + if (m->create_message) + dbus_message_unref(m->create_message); + free(m->name); free(m->state_file); free(m->service); - free(m->slice); free(m->root_directory); free(m); } @@ -114,15 +121,15 @@ int machine_save(Machine *m) { "NAME=%s\n", m->name); - if (m->cgroup_path) - fprintf(f, "CGROUP=%s\n", m->cgroup_path); + if (m->scope) + fprintf(f, "SCOPE=%s\n", m->scope); + + if (m->scope_job) + fprintf(f, "SCOPE_JOB=%s\n", m->scope_job); if (m->service) fprintf(f, "SERVICE=%s\n", m->service); - if (m->slice) - fprintf(f, "SLICE=%s\n", m->slice); - if (m->root_directory) fprintf(f, "ROOT=%s\n", m->root_directory); @@ -164,9 +171,9 @@ int machine_load(Machine *m) { assert(m); r = parse_env_file(m->state_file, NEWLINE, - "CGROUP", &m->cgroup_path, + "SCOPE", &m->scope, + "SCOPE_JOB", &m->scope_job, "SERVICE", &m->service, - "SLICE", &m->slice, "ROOT", &m->root_directory, "ID", &id, "LEADER", &leader, @@ -211,86 +218,44 @@ int machine_load(Machine *m) { return r; } -static int machine_create_one_group(Machine *m, const char *controller, const char *path) { - int r; - - assert(m); - assert(path); - - if (m->leader > 0) - r = cg_create_and_attach(controller, path, m->leader); - else - r = -EINVAL; - - if (r < 0) { - r = cg_create(controller, path); - if (r < 0) - return r; - } - - return 0; -} - -static int machine_create_cgroup(Machine *m) { - char **k; +static int machine_start_scope(Machine *m) { + _cleanup_free_ char *description = NULL; + DBusError error; + char *job; int r; assert(m); - if (!m->slice) { - m->slice = strdup(SPECIAL_MACHINE_SLICE); - if (!m->slice) - return log_oom(); - } - - if (!m->cgroup_path) { - _cleanup_free_ char *escaped = NULL, *slice = NULL; - char *name; + dbus_error_init(&error); - name = strappenda(m->name, ".machine"); + if (!m->scope) { + _cleanup_free_ char *escaped = NULL; - escaped = cg_escape(name); + escaped = unit_name_escape(m->name); if (!escaped) return log_oom(); - r = cg_slice_to_path(m->slice, &slice); - if (r < 0) - return r; - - m->cgroup_path = strjoin(m->manager->cgroup_root, "/", slice, "/", escaped, NULL); - if (!m->cgroup_path) + m->scope = strjoin("machine.", m->name, ".scope", NULL); + if (!m->scope) return log_oom(); - } - r = machine_create_one_group(m, SYSTEMD_CGROUP_CONTROLLER, m->cgroup_path); - if (r < 0) { - log_error("Failed to create cgroup "SYSTEMD_CGROUP_CONTROLLER":%s: %s", m->cgroup_path, strerror(-r)); - return r; - } - - STRV_FOREACH(k, m->manager->controllers) { - - if (strv_contains(m->manager->reset_controllers, *k)) - continue; - - r = machine_create_one_group(m, *k, m->cgroup_path); + r = hashmap_put(m->manager->machine_units, m->scope, m); if (r < 0) - log_warning("Failed to create cgroup %s:%s: %s", *k, m->cgroup_path, strerror(-r)); + log_warning("Failed to create mapping between unit and machine"); } - if (m->leader > 0) { - STRV_FOREACH(k, m->manager->reset_controllers) { - r = cg_attach(*k, "/", m->leader); - if (r < 0) - log_warning("Failed to reset controller %s: %s", *k, strerror(-r)); - } + description = strappend(m->class == MACHINE_VM ? "Virtual Machine " : "Container ", m->name); + + r = manager_start_scope(m->manager, m->scope, m->leader, SPECIAL_MACHINE_SLICE, description, &error, &job); + if (r < 0) { + log_error("Failed to start machine scope: %s", bus_error(&error, r)); + dbus_error_free(&error); } - r = hashmap_put(m->manager->machine_cgroups, m->cgroup_path, m); - if (r < 0) - log_warning("Failed to create mapping between cgroup and machine"); + free(m->scope_job); + m->scope_job = job; - return 0; + return r; } int machine_start(Machine *m) { @@ -301,6 +266,11 @@ int machine_start(Machine *m) { if (m->started) return 0; + /* Create cgroup */ + r = machine_start_scope(m); + if (r < 0) + return r; + log_struct(LOG_INFO, MESSAGE_ID(SD_MESSAGE_MACHINE_START), "NAME=%s", m->name, @@ -308,11 +278,6 @@ int machine_start(Machine *m) { "MESSAGE=New machine %s.", m->name, NULL); - /* Create cgroup */ - r = machine_create_cgroup(m); - if (r < 0) - return r; - if (!dual_timestamp_is_set(&m->timestamp)) dual_timestamp_get(&m->timestamp); @@ -326,28 +291,27 @@ int machine_start(Machine *m) { return 0; } -static int machine_terminate_cgroup(Machine *m) { +static int machine_stop_scope(Machine *m) { + DBusError error; + char *job; int r; - char **k; assert(m); - if (!m->cgroup_path) - return 0; - - cg_trim(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_path, false); + dbus_error_init(&error); - r = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_path, true); - if (r < 0) - log_error("Failed to kill machine cgroup: %s", strerror(-r)); - - STRV_FOREACH(k, m->manager->controllers) - cg_trim(*k, m->cgroup_path, true); + if (!m->scope) + return 0; - hashmap_remove(m->manager->machine_cgroups, m->cgroup_path); + r = manager_stop_unit(m->manager, m->scope, &error, &job); + if (r < 0) { + log_error("Failed to stop machine scope: %s", bus_error(&error, r)); + dbus_error_free(&error); + return r; + } - free(m->cgroup_path); - m->cgroup_path = NULL; + free(m->scope_job); + m->scope_job = job; return r; } @@ -365,7 +329,7 @@ int machine_stop(Machine *m) { NULL); /* Kill cgroup */ - k = machine_terminate_cgroup(m); + k = machine_stop_scope(m); if (k < 0) r = k; @@ -381,21 +345,16 @@ int machine_stop(Machine *m) { } int machine_check_gc(Machine *m, bool drop_not_started) { - int r; - assert(m); if (drop_not_started && !m->started) return 0; - if (m->cgroup_path) { - r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_path, false); - if (r < 0) - return r; + if (m->scope_job) + return 1; - if (r <= 0) - return 1; - } + if (m->scope) + return manager_unit_is_active(m->manager, m->scope) != 0; return 0; } @@ -410,41 +369,22 @@ void machine_add_to_gc_queue(Machine *m) { m->in_gc_queue = true; } -int machine_kill(Machine *m, KillWho who, int signo) { - _cleanup_set_free_ Set *pid_set = NULL; - int r = 0; - - assert(m); - - if (!m->cgroup_path) - return -ESRCH; - - if (m->leader <= 0 && who == KILL_LEADER) - return -ESRCH; +MachineState machine_get_state(Machine *s) { + assert(s); - if (m->leader > 0) - if (kill(m->leader, signo) < 0) - r = -errno; + if (s->scope_job) + return s->started ? MACHINE_OPENING : MACHINE_CLOSING; - if (who == KILL_ALL) { - int q; - - pid_set = set_new(trivial_hash_func, trivial_compare_func); - if (!pid_set) - return log_oom(); + return MACHINE_RUNNING; +} - if (m->leader > 0) { - q = set_put(pid_set, LONG_TO_PTR(m->leader)); - if (q < 0) - r = q; - } +int machine_kill(Machine *m, KillWho who, int signo) { + assert(m); - q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_path, signo, false, true, false, pid_set); - if (q < 0 && (q != -EAGAIN && q != -ESRCH && q != -ENOENT)) - r = q; - } + if (!m->scope) + return -ESRCH; - return r; + return manager_kill_unit(m->manager, m->scope, who, signo, NULL); } static const char* const machine_class_table[_MACHINE_CLASS_MAX] = { @@ -453,3 +393,11 @@ static const char* const machine_class_table[_MACHINE_CLASS_MAX] = { }; DEFINE_STRING_TABLE_LOOKUP(machine_class, MachineClass); + +static const char* const machine_state_table[_MACHINE_STATE_MAX] = { + [MACHINE_OPENING] = "opening", + [MACHINE_RUNNING] = "running", + [MACHINE_CLOSING] = "closing" +}; + +DEFINE_STRING_TABLE_LOOKUP(machine_state, MachineState); diff --git a/src/login/logind-machine.h b/src/login/logind-machine.h index cd5174ff9e..a09f07195a 100644 --- a/src/login/logind-machine.h +++ b/src/login/logind-machine.h @@ -28,6 +28,14 @@ typedef struct Machine Machine; #include "logind.h" #include "logind-session.h" +typedef enum MachineState { + MACHINE_OPENING, /* Machine is being registered */ + MACHINE_RUNNING, /* Machine is running */ + MACHINE_CLOSING, /* Machine is terminating */ + _MACHINE_STATE_MAX, + _MACHINE_STATE_INVALID = -1 +} MachineState; + typedef enum MachineClass { MACHINE_CONTAINER, MACHINE_VM, @@ -41,14 +49,16 @@ struct Machine { char *name; sd_id128_t id; + MachineState state; MachineClass class; char *state_file; char *service; - char *cgroup_path; - char *slice; char *root_directory; + char *scope; + char *scope_job; + pid_t leader; dual_timestamp timestamp; @@ -56,6 +66,8 @@ struct Machine { bool in_gc_queue:1; bool started:1; + DBusMessage *create_message; + LIST_FIELDS(Machine, gc_queue); }; @@ -71,10 +83,17 @@ int machine_kill(Machine *m, KillWho who, int signo); char *machine_bus_path(Machine *s); +MachineState machine_get_state(Machine *u); + extern const DBusObjectPathVTable bus_machine_vtable; int machine_send_signal(Machine *m, bool new_machine); int machine_send_changed(Machine *m, const char *properties); +int machine_send_create_reply(Machine *m, DBusError *error); + const char* machine_class_to_string(MachineClass t) _const_; MachineClass machine_class_from_string(const char *s) _pure_; + +const char* machine_state_to_string(MachineState t) _const_; +MachineState machine_state_from_string(const char *s) _pure_; diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c index e306eabb32..7aba3477aa 100644 --- a/src/login/logind-session-dbus.c +++ b/src/login/logind-session-dbus.c @@ -47,7 +47,6 @@ " \n" \ " \n" \ " \n" \ - " \n" \ " \n" \ " \n" \ " \n" \ @@ -56,15 +55,13 @@ " \n" \ " \n" \ " \n" \ - " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ - " \n" \ - " \n" \ " \n" \ " \n" \ " \n" \ @@ -196,24 +193,6 @@ static int bus_session_append_idle_hint_since(DBusMessageIter *i, const char *pr return 0; } -static int bus_session_append_default_cgroup(DBusMessageIter *i, const char *property, void *data) { - Session *s = data; - _cleanup_free_ char *t = NULL; - int r; - bool success; - - assert(i); - assert(property); - assert(s); - - r = cg_join_spec(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, &t); - if (r < 0) - return r; - - success = dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t); - return success ? 0 : -ENOMEM; -} - static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_session_append_type, session_type, SessionType); static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_session_append_class, session_class, SessionClass); @@ -260,7 +239,6 @@ static const BusProperty bus_login_session_properties[] = { { "Id", bus_property_append_string, "s", offsetof(Session, id), true }, { "Timestamp", bus_property_append_usec, "t", offsetof(Session, timestamp.realtime) }, { "TimestampMonotonic", bus_property_append_usec, "t", offsetof(Session, timestamp.monotonic) }, - { "DefaultControlGroup", bus_session_append_default_cgroup, "s", 0, }, { "VTNr", bus_property_append_uint32, "u", offsetof(Session, vtnr) }, { "Seat", bus_session_append_seat, "(so)", 0 }, { "TTY", bus_property_append_string, "s", offsetof(Session, tty), true }, @@ -269,16 +247,13 @@ static const BusProperty bus_login_session_properties[] = { { "RemoteUser", bus_property_append_string, "s", offsetof(Session, remote_user), true }, { "RemoteHost", bus_property_append_string, "s", offsetof(Session, remote_host), true }, { "Service", bus_property_append_string, "s", offsetof(Session, service), true }, - { "Slice", bus_property_append_string, "s", offsetof(Session, slice), true }, + { "Scope", bus_property_append_string, "s", offsetof(Session, scope), true }, { "Leader", bus_property_append_pid, "u", offsetof(Session, leader) }, { "Audit", bus_property_append_uint32, "u", offsetof(Session, audit_id) }, { "Type", bus_session_append_type, "s", offsetof(Session, type) }, { "Class", bus_session_append_class, "s", offsetof(Session, class) }, { "Active", bus_session_append_active, "b", 0 }, { "State", bus_session_append_state, "s", 0 }, - { "Controllers", bus_property_append_strv, "as", offsetof(Session, controllers), true }, - { "ResetControllers", bus_property_append_strv, "as", offsetof(Session, reset_controllers), true }, - { "KillProcesses", bus_property_append_bool, "b", offsetof(Session, kill_processes) }, { "IdleHint", bus_session_append_idle_hint, "b", 0 }, { "IdleSinceHint", bus_session_append_idle_hint_since, "t", 0 }, { "IdleSinceHintMonotonic", bus_session_append_idle_hint_since, "t", 0 }, @@ -552,3 +527,73 @@ int session_send_lock_all(Manager *m, bool lock) { return r; } + +int session_send_create_reply(Session *s, DBusError *error) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + + assert(s); + + if (!s->create_message) + return 0; + + if (error) { + DBusError buffer; + + dbus_error_init(&buffer); + + if (!dbus_error_is_set(error)) { + dbus_set_error_const(&buffer, DBUS_ERROR_INVALID_ARGS, "Invalid Arguments"); + error = &buffer; + } + + reply = dbus_message_new_error(s->create_message, error->name, error->message); + dbus_error_free(&buffer); + + if (!reply) + return log_oom(); + } else { + _cleanup_close_ int fifo_fd = -1; + _cleanup_free_ char *path = NULL; + const char *cseat; + uint32_t vtnr; + dbus_bool_t exists; + + fifo_fd = session_create_fifo(s); + if (fifo_fd < 0) { + log_error("Failed to create fifo: %s", strerror(-fifo_fd)); + return fifo_fd; + } + + path = session_bus_path(s); + if (!path) + return log_oom(); + + reply = dbus_message_new_method_return(s->create_message); + if (!reply) + return log_oom(); + + cseat = s->seat ? s->seat->id : ""; + vtnr = s->vtnr; + exists = false; + + if (!dbus_message_append_args( + reply, + DBUS_TYPE_STRING, &s->id, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_STRING, &s->user->runtime_path, + DBUS_TYPE_UNIX_FD, &fifo_fd, + DBUS_TYPE_STRING, &cseat, + DBUS_TYPE_UINT32, &vtnr, + DBUS_TYPE_BOOLEAN, &exists, + DBUS_TYPE_INVALID)) + return log_oom(); + } + + if (!dbus_connection_send(s->manager->bus, reply, NULL)) + return log_oom(); + + dbus_message_unref(s->create_message); + s->create_message = NULL; + + return 0; +} diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 760425329b..93e4037231 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -25,15 +25,17 @@ #include #include -#include "systemd/sd-id128.h" -#include "systemd/sd-messages.h" +#include +#include + #include "strv.h" #include "util.h" #include "mkdir.h" #include "path-util.h" #include "cgroup-util.h" -#include "logind-session.h" #include "fileio.h" +#include "dbus-common.h" +#include "logind-session.h" Session* session_new(Manager *m, const char *id) { Session *s; @@ -85,18 +87,21 @@ void session_free(Session *s) { LIST_REMOVE(Session, sessions_by_seat, s->seat->sessions, s); } - if (s->cgroup_path) - hashmap_remove(s->manager->session_cgroups, s->cgroup_path); + if (s->scope) { + hashmap_remove(s->manager->session_units, s->scope); + free(s->scope); + } + + free(s->scope_job); - free(s->cgroup_path); - strv_free(s->controllers); + if (s->create_message) + dbus_message_unref(s->create_message); free(s->tty); free(s->display); free(s->remote_host); free(s->remote_user); free(s->service); - free(s->slice); hashmap_remove(s->manager->sessions, s->id); session_remove_fifo(s); @@ -144,14 +149,12 @@ int session_save(Session *s) { "USER=%s\n" "ACTIVE=%i\n" "STATE=%s\n" - "REMOTE=%i\n" - "KILL_PROCESSES=%i\n", + "REMOTE=%i\n", (unsigned long) s->user->uid, s->user->name, session_is_active(s), session_state_to_string(session_get_state(s)), - s->remote, - s->kill_processes); + s->remote); if (s->type >= 0) fprintf(f, "TYPE=%s\n", session_type_to_string(s->type)); @@ -159,8 +162,11 @@ int session_save(Session *s) { if (s->class >= 0) fprintf(f, "CLASS=%s\n", session_class_to_string(s->class)); - if (s->cgroup_path) - fprintf(f, "CGROUP=%s\n", s->cgroup_path); + if (s->scope) + fprintf(f, "SCOPE=%s\n", s->scope); + + if (s->scope_job) + fprintf(f, "SCOPE_JOB=%s\n", s->scope_job); if (s->fifo_path) fprintf(f, "FIFO=%s\n", s->fifo_path); @@ -183,9 +189,6 @@ int session_save(Session *s) { if (s->service) fprintf(f, "SERVICE=%s\n", s->service); - if (s->seat) - fprintf(f, "SLICE=%s\n", s->slice); - if (s->seat && seat_can_multi_session(s->seat)) fprintf(f, "VTNR=%i\n", s->vtnr); @@ -219,7 +222,6 @@ finish: int session_load(Session *s) { _cleanup_free_ char *remote = NULL, - *kill_processes = NULL, *seat = NULL, *vtnr = NULL, *leader = NULL, @@ -236,8 +238,8 @@ int session_load(Session *s) { r = parse_env_file(s->state_file, NEWLINE, "REMOTE", &remote, - "KILL_PROCESSES", &kill_processes, - "CGROUP", &s->cgroup_path, + "SCOPE", &s->scope, + "SCOPE_JOB", &s->scope_job, "FIFO", &s->fifo_path, "SEAT", &seat, "TTY", &s->tty, @@ -245,7 +247,6 @@ int session_load(Session *s) { "REMOTE_HOST", &s->remote_host, "REMOTE_USER", &s->remote_user, "SERVICE", &s->service, - "SLICE", &s->slice, "VTNR", &vtnr, "LEADER", &leader, "TYPE", &type, @@ -290,12 +291,6 @@ int session_load(Session *s) { s->remote = k; } - if (kill_processes) { - k = parse_boolean(kill_processes); - if (k >= 0) - s->kill_processes = k; - } - if (seat && !s->seat) { Seat *o; @@ -459,124 +454,39 @@ done: return 0; } -static int session_create_one_group(Session *s, const char *controller, const char *path) { +static int session_start_scope(Session *s) { + _cleanup_free_ char *description = NULL; + DBusError error; + char *job; int r; assert(s); assert(s->user); - assert(path); + assert(s->user->slice); - if (s->leader > 0) - r = cg_create_and_attach(controller, path, s->leader); - else - r = -EINVAL; - - if (r < 0) { - r = cg_create(controller, path); - if (r < 0) - return r; - } - - r = cg_set_task_access(controller, path, 0644, s->user->uid, s->user->gid); - if (r >= 0) - r = cg_set_group_access(controller, path, 0755, s->user->uid, s->user->gid); - - return r; -} - -static int session_create_cgroup(Session *s) { - char **k; - int r; - - assert(s); - assert(s->user); - assert(s->user->cgroup_path); - - if (!s->cgroup_path) { - _cleanup_free_ char *name = NULL, *escaped = NULL; - - name = strappend(s->id, ".session"); - if (!name) - return log_oom(); + dbus_error_init(&error); - escaped = cg_escape(name); - if (!escaped) + if (!s->scope) { + s->scope = strjoin("session.", s->id, ".scope", NULL); + if (!s->scope) return log_oom(); - if (s->slice) { - _cleanup_free_ char *slice = NULL; - - r = cg_slice_to_path(s->slice, &slice); - if (r < 0) - return r; - - s->cgroup_path = strjoin(s->manager->cgroup_root, "/", slice, "/", escaped, NULL); - } else - s->cgroup_path = strjoin(s->user->cgroup_path, "/", escaped, NULL); - - if (!s->cgroup_path) - return log_oom(); - } - - if (!s->slice) { - s->slice = strdup(s->user->slice); - if (!s->slice) - return log_oom(); - } - - r = session_create_one_group(s, SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path); - if (r < 0) { - log_error("Failed to create "SYSTEMD_CGROUP_CONTROLLER":%s: %s", s->cgroup_path, strerror(-r)); - return r; - } - - STRV_FOREACH(k, s->controllers) { - - if (strv_contains(s->reset_controllers, *k)) - continue; - - r = session_create_one_group(s, *k, s->cgroup_path); + r = hashmap_put(s->manager->session_units, s->scope, s); if (r < 0) - log_warning("Failed to create %s:%s: %s", *k, s->cgroup_path, strerror(-r)); + log_warning("Failed to create mapping between unit and session"); } - STRV_FOREACH(k, s->manager->controllers) { - - if (strv_contains(s->reset_controllers, *k) || - strv_contains(s->manager->reset_controllers, *k) || - strv_contains(s->controllers, *k)) - continue; - - r = session_create_one_group(s, *k, s->cgroup_path); - if (r < 0) - log_warning("Failed to create %s:%s: %s", *k, s->cgroup_path, strerror(-r)); - } - - if (s->leader > 0) { - - STRV_FOREACH(k, s->reset_controllers) { - r = cg_attach(*k, "/", s->leader); - if (r < 0) - log_warning("Failed to reset controller %s: %s", *k, strerror(-r)); - - } - - STRV_FOREACH(k, s->manager->reset_controllers) { + description = strjoin("Session ", s->id, " of user ", s->user->name, NULL); - if (strv_contains(s->reset_controllers, *k) || - strv_contains(s->controllers, *k)) - continue; - - r = cg_attach(*k, "/", s->leader); - if (r < 0) - log_warning("Failed to reset controller %s: %s", *k, strerror(-r)); - } + r = manager_start_scope(s->manager, s->scope, s->leader, s->user->slice, description, &error, &job); + if (r < 0) { + log_error("Failed to start session scope: %s %s", bus_error(&error, r), error.name); + dbus_error_free(&error); + } else { + free(s->scope_job); + s->scope_job = job; } - r = hashmap_put(s->manager->session_cgroups, s->cgroup_path, s); - if (r < 0) - log_warning("Failed to create mapping between cgroup and session"); - return 0; } @@ -595,6 +505,11 @@ int session_start(Session *s) { if (r < 0) return r; + /* Create cgroup */ + r = session_start_scope(s); + if (r < 0) + return r; + log_struct(s->type == SESSION_TTY || s->type == SESSION_X11 ? LOG_INFO : LOG_DEBUG, MESSAGE_ID(SD_MESSAGE_SESSION_START), "SESSION_ID=%s", s->id, @@ -603,11 +518,6 @@ int session_start(Session *s) { "MESSAGE=New session %s of user %s.", s->id, s->user->name, NULL); - /* Create cgroup */ - r = session_create_cgroup(s); - if (r < 0) - return r; - /* Create X11 symlink */ session_link_x11_socket(s); @@ -639,73 +549,42 @@ int session_start(Session *s) { return 0; } -static bool session_shall_kill(Session *s) { - assert(s); +/* static bool session_shall_kill(Session *s) { */ +/* assert(s); */ - if (!s->kill_processes) - return false; +/* if (!s->kill_processes) */ +/* return false; */ - if (strv_contains(s->manager->kill_exclude_users, s->user->name)) - return false; +/* if (strv_contains(s->manager->kill_exclude_users, s->user->name)) */ +/* return false; */ - if (strv_isempty(s->manager->kill_only_users)) - return true; +/* if (strv_isempty(s->manager->kill_only_users)) */ +/* return true; */ - return strv_contains(s->manager->kill_only_users, s->user->name); -} +/* return strv_contains(s->manager->kill_only_users, s->user->name); */ +/* } */ -static int session_terminate_cgroup(Session *s) { +static int session_stop_scope(Session *s) { + DBusError error; + char *job; int r; - char **k; assert(s); - if (!s->cgroup_path) - return 0; + dbus_error_init(&error); - cg_trim(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, false); - - if (session_shall_kill(s)) { - - r = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, true); - if (r < 0) - log_error("Failed to kill session cgroup: %s", strerror(-r)); - - } else { - if (s->leader > 0) { - Session *t; - - /* We still send a HUP to the leader process, - * even if we are not supposed to kill the - * whole cgroup. But let's first check the - * leader still exists and belongs to our - * session... */ - - r = manager_get_session_by_pid(s->manager, s->leader, &t); - if (r > 0 && t == s) { - kill(s->leader, SIGTERM); /* for normal processes */ - kill(s->leader, SIGHUP); /* for shells */ - kill(s->leader, SIGCONT); /* in case they are stopped */ - } - } + if (!s->scope) + return 0; - r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, true); - if (r < 0) - log_error("Failed to check session cgroup: %s", strerror(-r)); - else if (r > 0) { - r = cg_delete(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path); - if (r < 0) - log_error("Failed to delete session cgroup: %s", strerror(-r)); - } + r = manager_stop_unit(s->manager, s->scope, &error, &job); + if (r < 0) { + log_error("Failed to stop session scope: %s", bus_error(&error, r)); + dbus_error_free(&error); + return r; } - STRV_FOREACH(k, s->user->manager->controllers) - cg_trim(*k, s->cgroup_path, true); - - hashmap_remove(s->manager->session_cgroups, s->cgroup_path); - - free(s->cgroup_path); - s->cgroup_path = NULL; + free(s->scope_job); + s->scope_job = job; return 0; } @@ -750,7 +629,7 @@ int session_stop(Session *s) { NULL); /* Kill cgroup */ - k = session_terminate_cgroup(s); + k = session_stop_scope(s); if (k < 0) r = k; @@ -861,28 +740,6 @@ int session_get_idle_hint(Session *s, dual_timestamp *t) { goto found_atime; } - /* For other TTY sessions, let's find the most recent atime of - * the ttys of any of the processes of the session */ - if (s->cgroup_path) { - _cleanup_fclose_ FILE *f = NULL; - - if (cg_enumerate_processes(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, &f) >= 0) { - pid_t pid; - - atime = 0; - while (cg_read_pid(f, &pid) > 0) { - usec_t a; - - if (get_process_ctty_atime(pid, &a) >= 0) - if (atime == 0 || atime < a) - atime = a; - } - - if (atime != 0) - goto found_atime; - } - } - dont_know: if (t) *t = s->idle_hint_timestamp; @@ -1018,15 +875,11 @@ int session_check_gc(Session *s, bool drop_not_started) { return 1; } - if (s->cgroup_path) { + if (s->scope_job) + return 1; - r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, false); - if (r < 0) - return r; - - if (r <= 0) - return 1; - } + if (s->scope) + return manager_unit_is_active(s->manager, s->scope) != 0; return 0; } @@ -1044,6 +897,9 @@ void session_add_to_gc_queue(Session *s) { SessionState session_get_state(Session *s) { assert(s); + if (s->scope_job) + return s->started ? SESSION_OPENING : SESSION_CLOSING; + if (s->fifo_fd < 0) return SESSION_CLOSING; @@ -1054,44 +910,16 @@ SessionState session_get_state(Session *s) { } int session_kill(Session *s, KillWho who, int signo) { - _cleanup_set_free_ Set *pid_set = NULL; - int r = 0; - assert(s); - if (!s->cgroup_path) - return -ESRCH; - - if (s->leader <= 0 && who == KILL_LEADER) + if (!s->scope) return -ESRCH; - if (s->leader > 0) - if (kill(s->leader, signo) < 0) - r = -errno; - - if (who == KILL_ALL) { - int q; - - pid_set = set_new(trivial_hash_func, trivial_compare_func); - if (!pid_set) - return log_oom(); - - if (s->leader > 0) { - q = set_put(pid_set, LONG_TO_PTR(s->leader)); - if (q < 0) - r = q; - } - - q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, signo, false, true, false, pid_set); - if (q < 0) - if (q != -EAGAIN && q != -ESRCH && q != -ENOENT) - r = q; - } - - return r; + return manager_kill_unit(s->manager, s->scope, who, signo, NULL); } -static const char* const session_state_table[_SESSION_TYPE_MAX] = { +static const char* const session_state_table[_SESSION_STATE_MAX] = { + [SESSION_OPENING] = "opening", [SESSION_ONLINE] = "online", [SESSION_ACTIVE] = "active", [SESSION_CLOSING] = "closing" diff --git a/src/login/logind-session.h b/src/login/logind-session.h index 60597c2362..e2a46d5907 100644 --- a/src/login/logind-session.h +++ b/src/login/logind-session.h @@ -31,9 +31,10 @@ typedef enum KillWho KillWho; #include "logind-user.h" typedef enum SessionState { + SESSION_OPENING, /* Session scope is being created */ SESSION_ONLINE, /* Logged in */ SESSION_ACTIVE, /* Logged in and in the fg */ - SESSION_CLOSING, /* Logged out, but processes still remain */ + SESSION_CLOSING, /* Logged out, but scope is still there */ _SESSION_STATE_MAX, _SESSION_STATE_INVALID = -1 } SessionState; @@ -81,9 +82,10 @@ struct Session { bool remote; char *remote_user; char *remote_host; - char *service; - char *slice; + + char *scope; + char *scope_job; int vtnr; Seat *seat; @@ -94,16 +96,14 @@ struct Session { int fifo_fd; char *fifo_path; - char *cgroup_path; - char **controllers, **reset_controllers; - bool idle_hint; dual_timestamp idle_hint_timestamp; - bool kill_processes; bool in_gc_queue:1; bool started:1; + DBusMessage *create_message; + LIST_FIELDS(Session, sessions_by_user); LIST_FIELDS(Session, sessions_by_seat); @@ -138,6 +138,8 @@ int session_send_changed(Session *s, const char *properties); int session_send_lock(Session *s, bool lock); int session_send_lock_all(Manager *m, bool lock); +int session_send_create_reply(Session *s, DBusError *error); + const char* session_state_to_string(SessionState t) _const_; SessionState session_state_from_string(const char *s) _pure_; diff --git a/src/login/logind-user-dbus.c b/src/login/logind-user-dbus.c index 2a2825308d..fa2ecba53c 100644 --- a/src/login/logind-user-dbus.c +++ b/src/login/logind-user-dbus.c @@ -38,7 +38,6 @@ " \n" \ " \n" \ " \n" \ - " \n" \ " \n" \ " \n" \ " \n" \ @@ -186,24 +185,6 @@ static int bus_user_append_idle_hint_since(DBusMessageIter *i, const char *prope return 0; } -static int bus_user_append_default_cgroup(DBusMessageIter *i, const char *property, void *data) { - User *u = data; - _cleanup_free_ char *t = NULL; - int r; - bool success; - - assert(i); - assert(property); - assert(u); - - r = cg_join_spec(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, &t); - if (r < 0) - return r; - - success = dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t); - return success ? 0 : -ENOMEM; -} - static int get_user_for_path(Manager *m, const char *path, User **_u) { User *u; unsigned long lu; @@ -235,7 +216,6 @@ static const BusProperty bus_login_user_properties[] = { { "Timestamp", bus_property_append_usec, "t", offsetof(User, timestamp.realtime) }, { "TimestampMonotonic", bus_property_append_usec, "t", offsetof(User, timestamp.monotonic) }, { "RuntimePath", bus_property_append_string, "s", offsetof(User, runtime_path), true }, - { "DefaultControlGroup", bus_user_append_default_cgroup, "s", 0 }, { "Service", bus_property_append_string, "s", offsetof(User, service), true }, { "Slice", bus_property_append_string, "s", offsetof(User, slice), true }, { "Display", bus_user_append_display, "(so)", 0 }, diff --git a/src/login/logind-user.c b/src/login/logind-user.c index 9f7b924a24..316c4cd095 100644 --- a/src/login/logind-user.c +++ b/src/login/logind-user.c @@ -23,7 +23,6 @@ #include #include -#include "logind-user.h" #include "util.h" #include "mkdir.h" #include "cgroup-util.h" @@ -31,6 +30,9 @@ #include "strv.h" #include "fileio.h" #include "special.h" +#include "unit-name.h" +#include "dbus-common.h" +#include "logind-user.h" User* user_new(Manager *m, uid_t uid, gid_t gid, const char *name) { User *u; @@ -75,19 +77,25 @@ void user_free(User *u) { while (u->sessions) session_free(u->sessions); - if (u->cgroup_path) { - hashmap_remove(u->manager->user_cgroups, u->cgroup_path); - free(u->cgroup_path); + if (u->slice) { + hashmap_remove(u->manager->user_units, u->slice); + free(u->slice); } - free(u->service); + if (u->service) { + hashmap_remove(u->manager->user_units, u->service); + free(u->service); + } + + free(u->slice_job); + free(u->service_job); + free(u->runtime_path); hashmap_remove(u->manager->users, ULONG_TO_PTR((unsigned long) u->uid)); free(u->name); free(u->state_file); - free(u->slice); free(u); } @@ -119,17 +127,18 @@ int user_save(User *u) { u->name, user_state_to_string(user_get_state(u))); - if (u->cgroup_path) - fprintf(f, "CGROUP=%s\n", u->cgroup_path); - if (u->runtime_path) fprintf(f, "RUNTIME=%s\n", u->runtime_path); if (u->service) fprintf(f, "SERVICE=%s\n", u->service); + if (u->service_job) + fprintf(f, "SERVICE_JOB=%s\n", u->service_job); if (u->slice) fprintf(f, "SLICE=%s\n", u->slice); + if (u->slice_job) + fprintf(f, "SLICE_JOB=%s\n", u->slice_job); if (u->display) fprintf(f, "DISPLAY=%s\n", u->display->id); @@ -251,13 +260,14 @@ int user_load(User *u) { assert(u); r = parse_env_file(u->state_file, NEWLINE, - "CGROUP", &u->cgroup_path, - "RUNTIME", &u->runtime_path, - "SERVICE", &u->service, - "DISPLAY", &display, - "SLICE", &u->slice, - "REALTIME", &realtime, - "MONOTONIC", &monotonic, + "RUNTIME", &u->runtime_path, + "SERVICE", &u->service, + "SERVICE_JOB", &u->service_job, + "SLICE", &u->slice, + "SLICE_JOB", &u->slice_job, + "DISPLAY", &display, + "REALTIME", &realtime, + "MONOTONIC", &monotonic, NULL); if (r < 0) { if (r == -ENOENT) @@ -318,64 +328,70 @@ static int user_mkdir_runtime_path(User *u) { return 0; } -static int user_create_cgroup(User *u) { - char **k; +static int user_start_slice(User *u) { + DBusError error; + char *job; int r; assert(u); - if (!u->slice) { - u->slice = strdup(SPECIAL_USER_SLICE); - if (!u->slice) - return log_oom(); - } - - if (!u->cgroup_path) { - _cleanup_free_ char *name = NULL, *escaped = NULL, *slice = NULL; + dbus_error_init(&error); - if (asprintf(&name, "%lu.user", (unsigned long) u->uid) < 0) - return log_oom(); - - escaped = cg_escape(name); - if (!escaped) - return log_oom(); + if (!u->slice) { + char lu[DECIMAL_STR_MAX(unsigned long) + 1]; + sprintf(lu, "%lu", (unsigned long) u->uid); - r = cg_slice_to_path(u->slice, &slice); + r = build_subslice(SPECIAL_USER_SLICE, lu, &u->slice); if (r < 0) return r; - u->cgroup_path = strjoin(u->manager->cgroup_root, "/", slice, "/", escaped, NULL); - if (!u->cgroup_path) - return log_oom(); + r = hashmap_put(u->manager->user_units, u->slice, u); + if (r < 0) + log_warning("Failed to create mapping between unit and user"); } - r = cg_create(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path); + r = manager_start_unit(u->manager, u->slice, &error, &job); if (r < 0) { - log_error("Failed to create cgroup "SYSTEMD_CGROUP_CONTROLLER":%s: %s", u->cgroup_path, strerror(-r)); - return r; + log_error("Failed to start user slice: %s", bus_error(&error, r)); + dbus_error_free(&error); } - STRV_FOREACH(k, u->manager->controllers) { - - if (strv_contains(u->manager->reset_controllers, *k)) - continue; - - r = cg_create(*k, u->cgroup_path); - if (r < 0) - log_warning("Failed to create cgroup %s:%s: %s", *k, u->cgroup_path, strerror(-r)); - } - - r = hashmap_put(u->manager->user_cgroups, u->cgroup_path, u); - if (r < 0) - log_warning("Failed to create mapping between cgroup and user"); + free(u->slice_job); + u->slice_job = job; return 0; } static int user_start_service(User *u) { + DBusError error; + char *job; + int r; + assert(u); - /* FIXME: Fill me in later ... */ + dbus_error_init(&error); + + if (!u->service) { + char lu[DECIMAL_STR_MAX(unsigned long) + 1]; + sprintf(lu, "%lu", (unsigned long) u->uid); + + u->service = unit_name_build("user", lu, ".service"); + if (!u->service) + return log_oom(); + + r = hashmap_put(u->manager->user_units, u->service, u); + if (r < 0) + log_warning("Failed to create mapping between service and user"); + } + + r = manager_start_unit(u->manager, u->service, &error, &job); + if (r < 0) { + log_error("Failed to start user service: %s", bus_error(&error, r)); + dbus_error_free(&error); + } + + free(u->service_job); + u->service_job = job; return 0; } @@ -396,7 +412,7 @@ int user_start(User *u) { return r; /* Create cgroup */ - r = user_create_cgroup(u); + r = user_start_slice(u); if (r < 0) return r; @@ -418,69 +434,70 @@ int user_start(User *u) { return 0; } -static int user_stop_service(User *u) { - assert(u); - - if (!u->service) - return 0; - - return 0; -} +static int user_stop_slice(User *u) { + DBusError error; + char *job; + int r; -static int user_shall_kill(User *u) { assert(u); - if (!u->manager->kill_user_processes) - return false; + dbus_error_init(&error); - if (strv_contains(u->manager->kill_exclude_users, u->name)) - return false; + if (!u->slice) + return 0; + + r = manager_stop_unit(u->manager, u->slice, &error, &job); + if (r < 0) { + log_error("Failed to stop user slice: %s", bus_error(&error, r)); + dbus_error_free(&error); + return r; + } - if (strv_isempty(u->manager->kill_only_users)) - return true; + free(u->slice_job); + u->slice_job = job; - return strv_contains(u->manager->kill_only_users, u->name); + return r; } -static int user_terminate_cgroup(User *u) { +static int user_stop_service(User *u) { + DBusError error; + char *job; int r; - char **k; assert(u); - if (!u->cgroup_path) + dbus_error_init(&error); + + if (!u->service) return 0; - cg_trim(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, false); + r = manager_stop_unit(u->manager, u->service, &error, &job); + if (r < 0) { + log_error("Failed to stop user service: %s", bus_error(&error, r)); + dbus_error_free(&error); + return r; + } - if (user_shall_kill(u)) { + free(u->service_job); + u->service_job = job; - r = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, true); - if (r < 0) - log_error("Failed to kill user cgroup: %s", strerror(-r)); - } else { + return r; +} - r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, true); - if (r < 0) - log_error("Failed to check user cgroup: %s", strerror(-r)); - else if (r > 0) { - r = cg_delete(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path); - if (r < 0) - log_error("Failed to delete user cgroup: %s", strerror(-r)); - } else - r = -EBUSY; - } +/* static int user_shall_kill(User *u) { */ +/* assert(u); */ - STRV_FOREACH(k, u->manager->controllers) - cg_trim(*k, u->cgroup_path, true); +/* if (!u->manager->kill_user_processes) */ +/* return false; */ - hashmap_remove(u->manager->user_cgroups, u->cgroup_path); +/* if (strv_contains(u->manager->kill_exclude_users, u->name)) */ +/* return false; */ - free(u->cgroup_path); - u->cgroup_path = NULL; +/* if (strv_isempty(u->manager->kill_only_users)) */ +/* return true; */ - return r; -} +/* return strv_contains(u->manager->kill_only_users, u->name); */ +/* } */ static int user_remove_runtime_path(User *u) { int r; @@ -520,7 +537,7 @@ int user_stop(User *u) { r = k; /* Kill cgroup */ - k = user_terminate_cgroup(u); + k = user_stop_slice(u); if (k < 0) r = k; @@ -590,8 +607,6 @@ static int user_check_linger_file(User *u) { } int user_check_gc(User *u, bool drop_not_started) { - int r; - assert(u); if (drop_not_started && !u->started) @@ -603,15 +618,6 @@ int user_check_gc(User *u, bool drop_not_started) { if (user_check_linger_file(u) > 0) return 1; - if (u->cgroup_path) { - r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, false); - if (r < 0) - return r; - - if (r <= 0) - return 1; - } - return 0; } @@ -631,6 +637,8 @@ UserState user_get_state(User *u) { assert(u); + if (u->slice_job || u->service_job) + return u->started ? USER_OPENING : USER_CLOSING; LIST_FOREACH(sessions_by_user, i, u->sessions) { if (session_is_active(i)) @@ -649,27 +657,17 @@ UserState user_get_state(User *u) { } int user_kill(User *u, int signo) { - _cleanup_set_free_ Set *pid_set = NULL; - int r; - assert(u); - if (!u->cgroup_path) + if (!u->slice) return -ESRCH; - pid_set = set_new(trivial_hash_func, trivial_compare_func); - if (!pid_set) - return -ENOMEM; - - r = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, signo, false, true, false, pid_set); - if (r < 0 && (r != -EAGAIN && r != -ESRCH && r != -ENOENT)) - return r; - - return 0; + return manager_kill_unit(u->manager, u->slice, KILL_ALL, signo, NULL); } static const char* const user_state_table[_USER_STATE_MAX] = { [USER_OFFLINE] = "offline", + [USER_OPENING] = "opening", [USER_LINGERING] = "lingering", [USER_ONLINE] = "online", [USER_ACTIVE] = "active", diff --git a/src/login/logind-user.h b/src/login/logind-user.h index 16d798541a..889f828c42 100644 --- a/src/login/logind-user.h +++ b/src/login/logind-user.h @@ -30,6 +30,7 @@ typedef struct User User; typedef enum UserState { USER_OFFLINE, /* Not logged in at all */ + USER_OPENING, /* Is logging in */ USER_LINGERING, /* Lingering has been enabled by the admin for this user */ USER_ONLINE, /* User logged in */ USER_ACTIVE, /* User logged in and has a session in the fg */ @@ -47,16 +48,21 @@ struct User { char *state_file; char *runtime_path; + char *service; - char *cgroup_path; char *slice; + char *service_job; + char *slice_job; + Session *display; dual_timestamp timestamp; bool in_gc_queue:1; bool started:1; + bool slice_created:1; + bool service_created:1; LIST_HEAD(Session, sessions); LIST_FIELDS(User, gc_queue); diff --git a/src/login/logind.c b/src/login/logind.c index ea74254b28..7040ac9e8a 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -76,24 +76,23 @@ Manager *manager_new(void) { m->buttons = hashmap_new(string_hash_func, string_compare_func); m->machines = hashmap_new(string_hash_func, string_compare_func); - m->user_cgroups = hashmap_new(string_hash_func, string_compare_func); - m->session_cgroups = hashmap_new(string_hash_func, string_compare_func); - m->machine_cgroups = hashmap_new(string_hash_func, string_compare_func); + m->user_units = hashmap_new(string_hash_func, string_compare_func); + m->session_units = hashmap_new(string_hash_func, string_compare_func); + m->machine_units = hashmap_new(string_hash_func, string_compare_func); m->session_fds = hashmap_new(trivial_hash_func, trivial_compare_func); m->inhibitor_fds = hashmap_new(trivial_hash_func, trivial_compare_func); m->button_fds = hashmap_new(trivial_hash_func, trivial_compare_func); if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || !m->machines || - !m->user_cgroups || !m->session_cgroups || !m->machine_cgroups || + !m->user_units || !m->session_units || !m->machine_units || !m->session_fds || !m->inhibitor_fds || !m->button_fds) { manager_free(m); return NULL; } - m->reset_controllers = strv_new("cpu", NULL); m->kill_exclude_users = strv_new("root", NULL); - if (!m->reset_controllers || !m->kill_exclude_users) { + if (!m->kill_exclude_users) { manager_free(m); return NULL; } @@ -104,14 +103,6 @@ Manager *manager_new(void) { return NULL; } - if (cg_get_root_path(&m->cgroup_root) < 0) { - manager_free(m); - return NULL; - } - - if (streq(m->cgroup_root, "/")) - m->cgroup_root[0] = 0; - return m; } @@ -155,9 +146,9 @@ void manager_free(Manager *m) { hashmap_free(m->buttons); hashmap_free(m->machines); - hashmap_free(m->user_cgroups); - hashmap_free(m->session_cgroups); - hashmap_free(m->machine_cgroups); + hashmap_free(m->user_units); + hashmap_free(m->session_units); + hashmap_free(m->machine_units); hashmap_free(m->session_fds); hashmap_free(m->inhibitor_fds); @@ -194,14 +185,10 @@ void manager_free(Manager *m) { if (m->idle_action_fd >= 0) close_nointr_nofail(m->idle_action_fd); - strv_free(m->controllers); - strv_free(m->reset_controllers); strv_free(m->kill_only_users); strv_free(m->kill_exclude_users); free(m->action_job); - - free(m->cgroup_root); free(m); } @@ -989,177 +976,67 @@ static int manager_reserve_vt(Manager *m) { return 0; } -int manager_get_session_by_cgroup(Manager *m, const char *cgroup, Session **session) { - Session *s; - char *p; - - assert(m); - assert(cgroup); - assert(session); - - s = hashmap_get(m->session_cgroups, cgroup); - if (s) { - *session = s; - return 1; - } - - p = strdupa(cgroup); - - for (;;) { - char *e; - - e = strrchr(p, '/'); - if (!e || e == p) { - *session = NULL; - return 0; - } - - *e = 0; - - s = hashmap_get(m->session_cgroups, p); - if (s) { - *session = s; - return 1; - } - } -} - -int manager_get_user_by_cgroup(Manager *m, const char *cgroup, User **user) { - User *u; - char *p; - - assert(m); - assert(cgroup); - assert(user); - - u = hashmap_get(m->user_cgroups, cgroup); - if (u) { - *user = u; - return 1; - } - - p = strdupa(cgroup); - if (!p) - return log_oom(); - - for (;;) { - char *e; - - e = strrchr(p, '/'); - if (!e || e == p) { - *user = NULL; - return 0; - } - - *e = 0; - - u = hashmap_get(m->user_cgroups, p); - if (u) { - *user = u; - return 1; - } - } -} - -int manager_get_machine_by_cgroup(Manager *m, const char *cgroup, Machine **machine) { - Machine *u; - char *p; - - assert(m); - assert(cgroup); - assert(machine); - - u = hashmap_get(m->machine_cgroups, cgroup); - if (u) { - *machine = u; - return 1; - } - - p = strdupa(cgroup); - if (!p) - return log_oom(); - - for (;;) { - char *e; - - e = strrchr(p, '/'); - if (!e || e == p) { - *machine = NULL; - return 0; - } - - *e = 0; - - u = hashmap_get(m->machine_cgroups, p); - if (u) { - *machine = u; - return 1; - } - } -} - int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) { - _cleanup_free_ char *p = NULL; + _cleanup_free_ char *unit = NULL; + Session *s; int r; assert(m); assert(pid >= 1); assert(session); - r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &p); + r = cg_pid_get_unit(pid, &unit); if (r < 0) return r; - return manager_get_session_by_cgroup(m, p, session); + s = hashmap_get(m->session_units, unit); + if (!s) + return 0; + + *session = s; + return 1; } int manager_get_user_by_pid(Manager *m, pid_t pid, User **user) { - _cleanup_free_ char *p = NULL; + _cleanup_free_ char *unit = NULL; + User *u; int r; assert(m); assert(pid >= 1); assert(user); - r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &p); + r = cg_pid_get_slice(pid, &unit); if (r < 0) return r; - return manager_get_user_by_cgroup(m, p, user); + u = hashmap_get(m->user_units, unit); + if (!u) + return 0; + + *user = u; + return 1; } int manager_get_machine_by_pid(Manager *m, pid_t pid, Machine **machine) { - _cleanup_free_ char *p = NULL; + _cleanup_free_ char *unit = NULL; + Machine *mm; int r; assert(m); assert(pid >= 1); assert(machine); - r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &p); + r = cg_pid_get_unit(pid, &unit); if (r < 0) return r; - return manager_get_machine_by_cgroup(m, p, machine); -} - -void manager_cgroup_notify_empty(Manager *m, const char *cgroup) { - Machine *machine; - Session *s; - User *u; - int r; - - r = manager_get_session_by_cgroup(m, cgroup, &s); - if (r > 0) - session_add_to_gc_queue(s); - - r = manager_get_user_by_cgroup(m, cgroup, &u); - if (r > 0) - user_add_to_gc_queue(u); + mm = hashmap_get(m->machine_units, unit); + if (!mm) + return 0; - r = manager_get_machine_by_cgroup(m, cgroup, &machine); - if (r > 0) - machine_add_to_gc_queue(machine); + *machine = mm; + return 1; } static void manager_dispatch_other(Manager *m, int fd) { @@ -1229,15 +1106,40 @@ static int manager_connect_bus(Manager *m) { dbus_bus_add_match(m->bus, "type='signal'," - "interface='org.freedesktop.systemd1.Agent'," - "member='Released'," - "path='/org/freedesktop/systemd1/agent'", + "sender='org.freedesktop.systemd1'," + "interface='org.freedesktop.systemd1.Manager'," + "member='JobRemoved'," + "path='/org/freedesktop/systemd1'", + &error); + if (dbus_error_is_set(&error)) { + log_error("Failed to add match for JobRemoved: %s", bus_error_message(&error)); + dbus_error_free(&error); + } + + dbus_bus_add_match(m->bus, + "type='signal'," + "sender='org.freedesktop.systemd1'," + "interface='org.freedesktop.DBus.Properties'," + "member='PropertiesChanged'", &error); if (dbus_error_is_set(&error)) { - log_error("Failed to register match: %s", bus_error_message(&error)); - r = -EIO; - goto fail; + log_error("Failed to add match for PropertiesChanged: %s", bus_error_message(&error)); + dbus_error_free(&error); + } + + r = bus_method_call_with_reply( + m->bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "Subscribe", + NULL, + &error, + DBUS_TYPE_INVALID); + if (r < 0) { + log_error("Failed to enable subscription: %s", bus_error(&error, r)); + dbus_error_free(&error); } r = dbus_bus_request_name(m->bus, "org.freedesktop.login1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error); @@ -1563,9 +1465,6 @@ int manager_startup(Manager *m) { assert(m); assert(m->epoll_fd <= 0); - cg_shorten_controllers(m->reset_controllers); - cg_shorten_controllers(m->controllers); - m->epoll_fd = epoll_create1(EPOLL_CLOEXEC); if (m->epoll_fd < 0) return -errno; diff --git a/src/login/logind.conf b/src/login/logind.conf index 0861d73e0b..c0abf01b0c 100644 --- a/src/login/logind.conf +++ b/src/login/logind.conf @@ -13,8 +13,6 @@ #KillUserProcesses=no #KillOnlyUsers= #KillExcludeUsers=root -#Controllers= -#ResetControllers=cpu #InhibitDelayMaxSec=5 #HandlePowerKey=poweroff #HandleSuspendKey=suspend diff --git a/src/login/logind.h b/src/login/logind.h index ce25211878..b7277af73d 100644 --- a/src/login/logind.h +++ b/src/login/logind.h @@ -77,19 +77,15 @@ struct Manager { Seat *vtconsole; - char *cgroup_root; - char **controllers, **reset_controllers; - char **kill_only_users, **kill_exclude_users; - bool kill_user_processes; unsigned long session_counter; unsigned long inhibit_counter; - Hashmap *session_cgroups; - Hashmap *user_cgroups; - Hashmap *machine_cgroups; + Hashmap *session_units; + Hashmap *user_units; + Hashmap *machine_units; Hashmap *session_fds; Hashmap *inhibitor_fds; @@ -171,17 +167,12 @@ int manager_startup(Manager *m); int manager_run(Manager *m); int manager_spawn_autovt(Manager *m, int vtnr); -void manager_cgroup_notify_empty(Manager *m, const char *cgroup); - void manager_gc(Manager *m, bool drop_not_started); int manager_get_idle_hint(Manager *m, dual_timestamp *t); -int manager_get_user_by_cgroup(Manager *m, const char *cgroup, User **user); int manager_get_user_by_pid(Manager *m, pid_t pid, User **user); -int manager_get_session_by_cgroup(Manager *m, const char *cgroup, Session **session); int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session); -int manager_get_machine_by_cgroup(Manager *m, const char *cgroup, Machine **machine); int manager_get_machine_by_pid(Manager *m, pid_t pid, Machine **machine); extern const DBusObjectPathVTable bus_manager_vtable; @@ -194,5 +185,11 @@ int manager_send_changed(Manager *manager, const char *properties); int manager_dispatch_delayed(Manager *manager); +int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, DBusError *error, char **job); +int manager_start_unit(Manager *manager, const char *unit, DBusError *error, char **job); +int manager_stop_unit(Manager *manager, const char *unit, DBusError *error, char **job); +int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, DBusError *error); +int manager_unit_is_active(Manager *manager, const char *unit); + /* gperf lookup function */ const struct ConfigPerfItem* logind_gperf_lookup(const char *key, unsigned length); diff --git a/src/login/pam-module.c b/src/login/pam-module.c index 13290fd8ea..8c5b3a10f3 100644 --- a/src/login/pam-module.c +++ b/src/login/pam-module.c @@ -43,11 +43,6 @@ static int parse_argv(pam_handle_t *handle, int argc, const char **argv, - char ***controllers, - char ***reset_controllers, - bool *kill_processes, - char ***kill_only_users, - char ***kill_exclude_users, const char **class, bool *debug) { @@ -59,89 +54,15 @@ static int parse_argv(pam_handle_t *handle, for (i = 0; i < (unsigned) argc; i++) { int k; - if (startswith(argv[i], "kill-session-processes=")) { - if ((k = parse_boolean(argv[i] + 23)) < 0) { - pam_syslog(handle, LOG_ERR, "Failed to parse kill-session-processes= argument."); - return k; - } - - if (kill_processes) - *kill_processes = k; - - } else if (startswith(argv[i], "kill-session=")) { - /* As compatibility for old versions */ - - if ((k = parse_boolean(argv[i] + 13)) < 0) { - pam_syslog(handle, LOG_ERR, "Failed to parse kill-session= argument."); - return k; - } - - if (kill_processes) - *kill_processes = k; - - } else if (startswith(argv[i], "controllers=")) { - - if (controllers) { - char **l; - - if (!(l = strv_split(argv[i] + 12, ","))) { - pam_syslog(handle, LOG_ERR, "Out of memory."); - return -ENOMEM; - } - - strv_free(*controllers); - *controllers = l; - } - - } else if (startswith(argv[i], "reset-controllers=")) { - - if (reset_controllers) { - char **l; - - if (!(l = strv_split(argv[i] + 18, ","))) { - pam_syslog(handle, LOG_ERR, "Out of memory."); - return -ENOMEM; - } - - strv_free(*reset_controllers); - *reset_controllers = l; - } - - } else if (startswith(argv[i], "kill-only-users=")) { - - if (kill_only_users) { - char **l; - - if (!(l = strv_split(argv[i] + 16, ","))) { - pam_syslog(handle, LOG_ERR, "Out of memory."); - return -ENOMEM; - } - - strv_free(*kill_only_users); - *kill_only_users = l; - } - - } else if (startswith(argv[i], "kill-exclude-users=")) { - - if (kill_exclude_users) { - char **l; - - if (!(l = strv_split(argv[i] + 19, ","))) { - pam_syslog(handle, LOG_ERR, "Out of memory."); - return -ENOMEM; - } - - strv_free(*kill_exclude_users); - *kill_exclude_users = l; - } - - } else if (startswith(argv[i], "class=")) { + if (startswith(argv[i], "class=")) { if (class) *class = argv[i] + 6; } else if (startswith(argv[i], "debug=")) { - if ((k = parse_boolean(argv[i] + 6)) < 0) { + k = parse_boolean(argv[i] + 6); + + if (k < 0) { pam_syslog(handle, LOG_ERR, "Failed to parse debug= argument."); return k; } @@ -149,14 +70,9 @@ static int parse_argv(pam_handle_t *handle, if (debug) *debug = k; - } else if (startswith(argv[i], "create-session=") || - startswith(argv[i], "kill-user=")) { - - pam_syslog(handle, LOG_WARNING, "Option %s not supported anymore, ignoring.", argv[i]); - } else { - pam_syslog(handle, LOG_ERR, "Unknown parameter '%s'.", argv[i]); - return -EINVAL; + pam_syslog(handle, LOG_WARNING, "Unknown parameter '%s', ignoring", argv[i]); + return 0; } } @@ -206,55 +122,6 @@ static int get_user_data( return PAM_SUCCESS; } -static bool check_user_lists( - pam_handle_t *handle, - uid_t uid, - char **kill_only_users, - char **kill_exclude_users) { - - const char *name = NULL; - char **l; - - assert(handle); - - if (uid == 0) - name = "root"; /* Avoid obvious NSS requests, to suppress network traffic */ - else { - struct passwd *pw; - - pw = pam_modutil_getpwuid(handle, uid); - if (pw) - name = pw->pw_name; - } - - STRV_FOREACH(l, kill_exclude_users) { - uid_t u; - - if (parse_uid(*l, &u) >= 0) - if (u == uid) - return false; - - if (name && streq(name, *l)) - return false; - } - - if (strv_isempty(kill_only_users)) - return true; - - STRV_FOREACH(l, kill_only_users) { - uid_t u; - - if (parse_uid(*l, &u) >= 0) - if (u == uid) - return true; - - if (name && streq(name, *l)) - return true; - } - - return false; -} - static int get_seat_from_display(const char *display, const char **seat, uint32_t *vtnr) { _cleanup_free_ char *p = NULL; int r; @@ -316,13 +183,11 @@ _public_ PAM_EXTERN int pam_sm_open_session( int argc, const char **argv) { struct passwd *pw; - bool kill_processes = false, debug = false; + bool debug = false; const char *username, *id, *object_path, *runtime_path, *service = NULL, *tty = NULL, *display = NULL, *remote_user = NULL, *remote_host = NULL, *seat = NULL, *type = NULL, *class = NULL, *class_pam = NULL, *cvtnr = NULL; - char **controllers = NULL, **reset_controllers = NULL, **kill_only_users = NULL, **kill_exclude_users = NULL; DBusError error; uint32_t uid, pid; DBusMessageIter iter; - dbus_bool_t kp; int session_fd = -1; DBusConnection *bus = NULL; DBusMessage *m = NULL, *reply = NULL; @@ -342,9 +207,8 @@ _public_ PAM_EXTERN int pam_sm_open_session( if (parse_argv(handle, argc, argv, - &controllers, &reset_controllers, - &kill_processes, &kill_only_users, &kill_exclude_users, - &class_pam, &debug) < 0) { + &class_pam, + &debug) < 0) { r = PAM_SESSION_ERR; goto finish; } @@ -393,9 +257,6 @@ _public_ PAM_EXTERN int pam_sm_open_session( goto finish; } - if (kill_processes) - kill_processes = check_user_lists(handle, pw->pw_uid, kill_only_users, kill_exclude_users); - dbus_connection_set_change_sigpipe(FALSE); bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); @@ -510,27 +371,6 @@ _public_ PAM_EXTERN int pam_sm_open_session( dbus_message_iter_init_append(m, &iter); - r = bus_append_strv_iter(&iter, controllers); - if (r < 0) { - pam_syslog(handle, LOG_ERR, "Could not attach parameter to message."); - r = PAM_BUF_ERR; - goto finish; - } - - r = bus_append_strv_iter(&iter, reset_controllers); - if (r < 0) { - pam_syslog(handle, LOG_ERR, "Could not attach parameter to message."); - r = PAM_BUF_ERR; - goto finish; - } - - kp = kill_processes; - if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &kp)) { - pam_syslog(handle, LOG_ERR, "Could not attach parameter to message."); - r = PAM_BUF_ERR; - goto finish; - } - if (debug) pam_syslog(handle, LOG_DEBUG, "Asking logind to create session: " "uid=%u pid=%u service=%s type=%s class=%s seat=%s vtnr=%u tty=%s display=%s remote=%s remote_user=%s remote_host=%s", @@ -613,11 +453,6 @@ _public_ PAM_EXTERN int pam_sm_open_session( r = PAM_SUCCESS; finish: - strv_free(controllers); - strv_free(reset_controllers); - strv_free(kill_only_users); - strv_free(kill_exclude_users); - dbus_error_free(&error); if (bus) { diff --git a/src/shared/unit-name.c b/src/shared/unit-name.c index 7733aae0e7..1baa6eb7e5 100644 --- a/src/shared/unit-name.c +++ b/src/shared/unit-name.c @@ -565,3 +565,30 @@ UnitType unit_name_to_type(const char *n) { return unit_type_from_string(e + 1); } + +int build_subslice(const char *slice, const char*name, char **subslice) { + char *ret; + + assert(slice); + assert(name); + assert(subslice); + + if (streq(slice, "-.slice")) + ret = strappend(name, ".slice"); + else { + char *e; + + e = endswith(slice, ".slice"); + if (!e) + return -EINVAL; + + ret = new(char, (e - slice) + 1 + strlen(name) + 6 + 1); + if (!ret) + return -ENOMEM; + + stpcpy(stpcpy(stpcpy(mempcpy(ret, slice, e - slice), "-"), name), ".slice"); + } + + *subslice = ret; + return 0; +} diff --git a/src/shared/unit-name.h b/src/shared/unit-name.h index 7f4ae56433..20138df089 100644 --- a/src/shared/unit-name.h +++ b/src/shared/unit-name.h @@ -99,3 +99,5 @@ int unit_name_from_dbus_path(const char *path, char **name); char *unit_name_mangle(const char *name); char *unit_name_mangle_with_suffix(const char *name, const char *suffix); + +int build_subslice(const char *slice, const char*name, char **subslice); diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index fde3f43a17..7ecd8d2cfb 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -3806,7 +3806,7 @@ static int snapshot(DBusConnection *bus, char **args) { if (!n) return log_oom(); - r = bus_method_call_with_reply ( + r = bus_method_call_with_reply( bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", diff --git a/units/user@.service.in b/units/user@.service.in index ece671d448..d2d24f10bc 100644 --- a/units/user@.service.in +++ b/units/user@.service.in @@ -12,12 +12,10 @@ After=systemd-user-sessions.service [Service] User=%I PAMName=systemd-shared -# in order to allow MEM_CG features to work, add "memory:/" here -ControlGroup=%R/user/%U.user/shared cpu:/ -ControlGroupModify=yes Type=notify ExecStart=-@rootlibexecdir@/systemd --user -Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%U/dbus/user_bus_socket +Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%I/dbus/user_bus_socket +Slice=user-%i.slice [Install] Alias=user@%i.service -- cgit v1.2.1 From efffb13e0055b9f4749f85dedfbf3ef91cf89fe1 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 2 Jul 2013 02:13:30 +0200 Subject: keymap: Asus -- do not overwrite explicitely kernel driver defined keys If key mappings are defined in the kernel driver, userspace must not overwrite them. If something is wrong with the kernel-provided values, the kernel driver shold be fixed instead. Some of the matches are not the input device name but the kernel driver name, which will not match anything. --- src/udev/keymap/95-keymap.rules | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/udev/keymap/95-keymap.rules b/src/udev/keymap/95-keymap.rules index 60d39a85dd..60f0bf7ac2 100644 --- a/src/udev/keymap/95-keymap.rules +++ b/src/udev/keymap/95-keymap.rules @@ -47,13 +47,6 @@ ENV{DMI_VENDOR}=="", GOTO="keyboard_end" ENV{DMI_VENDOR}=="LENOVO*", KERNELS=="input*", ATTRS{name}=="ThinkPad Extra Buttons", RUN+="keymap $name module-lenovo" ENV{DMI_VENDOR}=="LENOVO*", KERNELS=="input*", ATTRS{name}=="Ideapad extra buttons", RUN+="keymap $name 0x42 f23 0x43 f22" -ENV{DMI_VENDOR}=="ASUS*", KERNELS=="input*", ATTRS{name}=="Asus Laptop extra buttons", RUN+="keymap $name 0x6B f21" -ENV{DMI_VENDOR}=="ASUS*", KERNELS=="input*", ATTRS{name}=="Asus Laptop Support", RUN+="keymap $name 0x6B f21" -ENV{DMI_VENDOR}=="ASUS*", KERNELS=="input*", ATTRS{name}=="Asus WMI hotkeys", RUN+="keymap $name 0x6B f21" -ENV{DMI_VENDOR}=="ASUS*", KERNELS=="input*", ATTRS{name}=="Asus Notebooks WMI Hotkey Driver", RUN+="keymap $name 0x6B f21" -ENV{DMI_VENDOR}=="ASUS*", KERNELS=="input*", ATTRS{name}=="Eee PC WMI hotkeys|Asus Laptop Support|Asus*WMI*", RUN+="keymap $name 0x6B f21" -ENV{DMI_VENDOR}=="ASUS*", KERNELS=="input*", ATTRS{name}=="Eee PC Hotkey Driver", RUN+="keymap $name 0x37 f21" - ENV{DMI_VENDOR}=="IBM*", KERNELS=="input*", ATTRS{name}=="ThinkPad Extra Buttons", RUN+="keymap $name module-ibm" ENV{DMI_VENDOR}=="Sony*", KERNELS=="input*", ATTRS{name}=="Sony Vaio Keys", RUN+="keymap $name module-sony" ENV{DMI_VENDOR}=="Acer*", KERNELS=="input*", ATTRS{name}=="Acer WMI hotkeys", RUN+="keymap $name 0x82 f21" -- cgit v1.2.1 From 374ec6abf31ada6ca554cc8ea99b282373fac010 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 2 Jul 2013 02:32:24 +0200 Subject: libsystemd-logind: fix detection of session/user/machine of a PID --- TODO | 2 +- src/login/logind-machine.c | 2 +- src/login/logind-session.c | 2 +- src/shared/cgroup-util.c | 102 ++++++++++++++++++-------------------------- src/test/test-cgroup-util.c | 32 +++++++------- 5 files changed, 61 insertions(+), 79 deletions(-) diff --git a/TODO b/TODO index cde2ced312..96ed2c06d8 100644 --- a/TODO +++ b/TODO @@ -28,7 +28,7 @@ Fedora 19: Features: -* libsystemd-logind: recognize new session/user/machine units +* fix killing spree logic in systemd-user-sessions * logind: implement session kill exceptions diff --git a/src/login/logind-machine.c b/src/login/logind-machine.c index e4edd40dba..a1342c155e 100644 --- a/src/login/logind-machine.c +++ b/src/login/logind-machine.c @@ -235,7 +235,7 @@ static int machine_start_scope(Machine *m) { if (!escaped) return log_oom(); - m->scope = strjoin("machine.", m->name, ".scope", NULL); + m->scope = strjoin("machine-", m->name, ".scope", NULL); if (!m->scope) return log_oom(); diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 93e4037231..6e1bf6d560 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -467,7 +467,7 @@ static int session_start_scope(Session *s) { dbus_error_init(&error); if (!s->scope) { - s->scope = strjoin("session.", s->id, ".scope", NULL); + s->scope = strjoin("session-", s->id, ".scope", NULL); if (!s->scope) return log_oom(); diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index 0e5da23ecd..390259e3e4 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -1178,23 +1178,6 @@ int cg_pid_get_unit(pid_t pid, char **unit) { return cg_path_get_unit(cgroup, unit); } -static const char *skip_user(const char *p) { - size_t n; - - assert(p); - - p += strspn(p, "/"); - - n = strcspn(p, "/"); - if (n <= 5 || memcmp(p + n - 5, ".user", 5) != 0) - return p; - - p += n; - p += strspn(p, "/"); - - return p; -} - static const char *skip_session(const char *p) { size_t n; @@ -1203,7 +1186,7 @@ static const char *skip_session(const char *p) { p += strspn(p, "/"); n = strcspn(p, "/"); - if (n <= 8 || memcmp(p + n - 8, ".session", 8) != 0) + if (n <= 12 || memcmp(p, "session-", 8) != 0 || memcmp(p + n - 6, ".scope", 6) != 0) return NULL; p += n; @@ -1212,23 +1195,6 @@ static const char *skip_session(const char *p) { return p; } -static const char *skip_systemd_label(const char *p) { - size_t n; - - assert(p); - - p += strspn(p, "/"); - - n = strcspn(p, "/"); - if (n < 8 || memcmp(p, "systemd-", 8) != 0) - return p; - - p += n; - p += strspn(p, "/"); - - return p; -} - int cg_path_get_user_unit(const char *path, char **unit) { const char *e; @@ -1242,16 +1208,13 @@ int cg_path_get_user_unit(const char *path, char **unit) { /* Skip slices, if there are any */ e = skip_slices(path); - /* Skip the user name, if there is one */ - e = skip_user(e); - - /* Skip the session ID, require that there is one */ + /* Skip the session scope, require that there is one */ e = skip_session(e); if (!e) return -ENOENT; - /* Skip the systemd cgroup, if there is one */ - e = skip_systemd_label(e); + /* And skip more slices */ + e = skip_slices(e); return cg_path_decode_unit(e, unit); } @@ -1272,6 +1235,7 @@ int cg_pid_get_user_unit(pid_t pid, char **unit) { int cg_path_get_machine_name(const char *path, char **machine) { const char *e, *n, *x; char *s, *r; + size_t l; assert(path); assert(machine); @@ -1286,11 +1250,17 @@ int cg_path_get_machine_name(const char *path, char **machine) { s = strndupa(e, n - e); s = cg_unescape(s); - x = endswith(s, ".machine"); + x = startswith(s, "machine-"); if (!x) return -ENOENT; + if (!endswith(x, ".scope")) + return -ENOENT; + + l = strlen(x); + if (l <= 6) + return -ENOENT; - r = strndup(s, x - s); + r = strndup(x, l - 6); if (!r) return -ENOMEM; @@ -1312,8 +1282,9 @@ int cg_pid_get_machine_name(pid_t pid, char **machine) { } int cg_path_get_session(const char *path, char **session) { - const char *e, *n; - char *s; + const char *e, *n, *x; + char *s, *r; + size_t l; assert(path); assert(session); @@ -1321,20 +1292,28 @@ int cg_path_get_session(const char *path, char **session) { /* Skip slices, if there are any */ e = skip_slices(path); - /* Skip the user name, if there is one */ - e = skip_user(e); - n = strchrnul(e, '/'); - if (n - e < 8) + if (e == n) return -ENOENT; - if (memcmp(n - 8, ".session", 8) != 0) + + s = strndupa(e, n - e); + s = cg_unescape(s); + + x = startswith(s, "session-"); + if (!x) + return -ENOENT; + if (!endswith(x, ".scope")) return -ENOENT; - s = strndup(e, n - e - 8); - if (!s) + l = strlen(x); + if (l <= 6) + return -ENOENT; + + r = strndup(x, l - 6); + if (!r) return -ENOMEM; - *session = s; + *session = r; return 0; } @@ -1352,22 +1331,25 @@ int cg_pid_get_session(pid_t pid, char **session) { } int cg_path_get_owner_uid(const char *path, uid_t *uid) { - const char *e, *n; + _cleanup_free_ char *slice = NULL; + const char *e; char *s; + int r; assert(path); assert(uid); - /* Skip slices, if there are any */ - e = skip_slices(path); + r = cg_path_get_slice(path, &slice); + if (r < 0) + return r; - n = strchrnul(e, '/'); - if (n - e < 5) + e = startswith(slice, "user-"); + if (!e) return -ENOENT; - if (memcmp(n - 5, ".user", 5) != 0) + if (!endswith(slice, ".slice")) return -ENOENT; - s = strndupa(e, n - e - 5); + s = strndupa(e, strlen(e) - 6); if (!s) return -ENOMEM; diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c index f6317e5d33..ed2c6aeeae 100644 --- a/src/test/test-cgroup-util.c +++ b/src/test/test-cgroup-util.c @@ -66,14 +66,14 @@ static void check_p_g_u_u(const char *path, int code, const char *result) { } static void test_path_get_user_unit(void) { - check_p_g_u_u("/user.slice/1000.user/2.session/systemd-21548/foobar.service", 0, "foobar.service"); - check_p_g_u_u("/user.slice/1002.user/2.session/systemd-21548/foobar.service/waldo", 0, "foobar.service"); - check_p_g_u_u("/user.slice/1000.user/2.session/systemd-21548/foobar.service/waldo/uuuux", 0, "foobar.service"); - check_p_g_u_u("/user.slice/1000.user/2.session/systemd-21548/waldo/waldo/uuuux", -EINVAL, NULL); - check_p_g_u_u("/user.slice/1000.user/2.session/foobar.service", 0, "foobar.service"); - check_p_g_u_u("/user.slice/1000.user/2.session/systemd-21548/foobar@.service/foobar@pie.service/pa/po", 0, "foobar@pie.service"); - check_p_g_u_u("/2.session/systemd-21548/foobar@.service/foobar@pie.service/pa/po", 0, "foobar@pie.service"); - check_p_g_u_u("/xyz.slice/xyz-waldo.slice/77.session/systemd-21548/foobar@.service/foobar@pie.service/pa/po", 0, "foobar@pie.service"); + check_p_g_u_u("/user.slice/user-1000.slice/session-2.scope/foobar.service", 0, "foobar.service"); + check_p_g_u_u("/user.slice/user-1000.slice/session-2.scope/waldo.slice/foobar.service", 0, "foobar.service"); + check_p_g_u_u("/user.slice/user-1002.slice/session-2.scope/foobar.service/waldo", 0, "foobar.service"); + check_p_g_u_u("/user.slice/user-1000.slice/session-2.scope/foobar.service/waldo/uuuux", 0, "foobar.service"); + check_p_g_u_u("/user.slice/user-1000.slice/session-2.scope/waldo/waldo/uuuux", -EINVAL, NULL); + check_p_g_u_u("/user.slice/user-1000.slice/session-2.scope/foobar@.service/foobar@pie.service/pa/po", 0, "foobar@pie.service"); + check_p_g_u_u("/session-2.scope/foobar@.service/foobar@pie.service/pa/po", 0, "foobar@pie.service"); + check_p_g_u_u("/xyz.slice/xyz-waldo.slice/session-77.scope/foobar@.service/foobar@pie.service/pa/po", 0, "foobar@pie.service"); check_p_g_u_u("/meh.service", -ENOENT, NULL); } @@ -85,8 +85,8 @@ static void check_p_g_s(const char *path, int code, const char *result) { } static void test_path_get_session(void) { - check_p_g_s("/user.slice/1000.user/2.session/systemd-21548/foobar.service", 0, "2"); - check_p_g_s("/3.session", 0, "3"); + check_p_g_s("/user.slice/user-1000.slice/session-2.scope/foobar.service", 0, "2"); + check_p_g_s("/session-3.scope", 0, "3"); check_p_g_s("", -ENOENT, 0); } @@ -98,8 +98,8 @@ static void check_p_g_o_u(const char *path, int code, uid_t result) { } static void test_path_get_owner_uid(void) { - check_p_g_o_u("/user.slice/1000.user/2.session/systemd-21548/foobar.service", 0, 1000); - check_p_g_o_u("/1006.user", 0, 1006); + check_p_g_o_u("/user.slice/user-1000.slice/session-2.scope/foobar.service", 0, 1000); + check_p_g_o_u("/user.slice/user-1006.slice", 0, 1006); check_p_g_o_u("", -ENOENT, 0); } @@ -111,10 +111,10 @@ static void check_p_g_m_n(const char *path, int code, const char *result) { } static void test_path_get_machine_name(void) { - check_p_g_m_n("/user.slice/foobar.machine", 0, "foobar"); - check_p_g_m_n("/foobar.machine", 0, "foobar"); - check_p_g_m_n("/user.slice/user-kuux.slice/foobar.machine", 0, "foobar"); - check_p_g_m_n("/user.slice/user-kuux.slice/foobar.machine/asjhdkj", 0, "foobar"); + check_p_g_m_n("/user.slice/machine-foobar.scope", 0, "foobar"); + check_p_g_m_n("/machine-foobar.scope", 0, "foobar"); + check_p_g_m_n("/user.slice/user-kuux.slice/machine-foobar.scope", 0, "foobar"); + check_p_g_m_n("/user.slice/user-kuux.slice/machine-foobar.scope/asjhdkj", 0, "foobar"); check_p_g_m_n("", -ENOENT, NULL); } -- cgit v1.2.1 From 1ee306e1248866617c96ed9f4263f375588ad838 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 2 Jul 2013 03:47:23 +0200 Subject: machined: split out machine registration stuff from logind Embedded folks don't need the machine registration stuff, hence it's nice to make this optional. Also, I'd expect that machinectl will grow additional commands quickly, for example to join existing containers and suchlike, hence it's better keeping that separate from loginctl. --- .gitignore | 2 + Makefile.am | 70 ++- configure.ac | 10 + src/login/loginctl.c | 309 +--------- src/login/logind-dbus.c | 378 ------------ src/login/logind-machine-dbus.c | 360 ------------ src/login/logind-machine.c | 403 ------------- src/login/logind-machine.h | 99 ---- src/login/logind-user.c | 12 +- src/login/logind.c | 117 +--- src/login/logind.h | 7 - src/machine/Makefile | 1 + src/machine/machine-dbus.c | 359 ++++++++++++ src/machine/machine.c | 411 +++++++++++++ src/machine/machine.h | 109 ++++ src/machine/machinectl.c | 764 +++++++++++++++++++++++++ src/machine/machined-dbus.c | 824 +++++++++++++++++++++++++++ src/machine/machined.c | 408 +++++++++++++ src/machine/machined.h | 73 +++ src/machine/org.freedesktop.machine1.conf | 46 ++ src/machine/org.freedesktop.machine1.service | 12 + src/nspawn/nspawn.c | 6 +- tmpfiles.d/systemd.conf | 1 + units/.gitignore | 1 + units/systemd-logind.service.in | 4 +- units/systemd-machined.service.in | 19 + 26 files changed, 3122 insertions(+), 1683 deletions(-) delete mode 100644 src/login/logind-machine-dbus.c delete mode 100644 src/login/logind-machine.c delete mode 100644 src/login/logind-machine.h create mode 120000 src/machine/Makefile create mode 100644 src/machine/machine-dbus.c create mode 100644 src/machine/machine.c create mode 100644 src/machine/machine.h create mode 100644 src/machine/machinectl.c create mode 100644 src/machine/machined-dbus.c create mode 100644 src/machine/machined.c create mode 100644 src/machine/machined.h create mode 100644 src/machine/org.freedesktop.machine1.conf create mode 100644 src/machine/org.freedesktop.machine1.service create mode 100644 units/systemd-machined.service.in diff --git a/.gitignore b/.gitignore index 53b1597f4a..ae756c49ef 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ /libtool /localectl /loginctl +/machinectl /mtd_probe /org.freedesktop.hostname1.xml /org.freedesktop.locale1.xml @@ -54,6 +55,7 @@ /systemd-localed /systemd-logind /systemd-machine-id-setup +/systemd-machined /systemd-modules-load /systemd-multi-seat-x /systemd-notify diff --git a/Makefile.am b/Makefile.am index e79756e30b..02cd7e2d25 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3568,6 +3568,70 @@ lib_LTLIBRARIES += \ libnss_myhostname.la endif +# ------------------------------------------------------------------------------ +if ENABLE_MACHINED +systemd_machined_SOURCES = \ + src/machine/machined.c \ + src/machine/machined.h \ + src/machine/machined-dbus.c \ + src/machine/machine.c \ + src/machine/machine.h \ + src/machine/machine-dbus.c + +systemd_machined_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +systemd_machined_LDADD = \ + libsystemd-label.la \ + libsystemd-audit.la \ + libsystemd-shared.la \ + libsystemd-daemon.la \ + libsystemd-dbus.la \ + libsystemd-id128-internal.la \ + libudev.la + +rootlibexec_PROGRAMS += \ + systemd-machined + +machinectl_SOURCES = \ + src/machine/machinectl.c + +machinectl_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +machinectl_LDADD = \ + libsystemd-shared.la \ + libsystemd-dbus.la \ + libudev.la + +rootbin_PROGRAMS += \ + machinectl + +nodist_systemunit_DATA += \ + units/systemd-machined.service + +dist_systemunit_DATA += \ + units/machine.slice + +dist_dbussystemservice_DATA += \ + src/machine/org.freedesktop.machine1.service + +dist_dbuspolicy_DATA += \ + src/machine/org.freedesktop.machine1.conf + +SYSTEM_UNIT_ALIASES += \ + systemd-machined.service dbus-org.freedesktop.machine1.service + +polkitpolicy_in_files += \ + src/machine/org.freedesktop.machine1.policy.in + +EXTRA_DIST += \ + units/systemd-machine.service.in + +endif + # ------------------------------------------------------------------------------ if ENABLE_LOGIND systemd_logind_SOURCES = \ @@ -3584,8 +3648,6 @@ systemd_logind_SOURCES = \ src/login/logind-seat.h \ src/login/logind-session.c \ src/login/logind-session.h \ - src/login/logind-machine.c \ - src/login/logind-machine.h \ src/login/logind-user.c \ src/login/logind-user.h \ src/login/logind-inhibit.c \ @@ -3593,7 +3655,6 @@ systemd_logind_SOURCES = \ src/login/logind-session-dbus.c \ src/login/logind-seat-dbus.c \ src/login/logind-user-dbus.c \ - src/login/logind-machine-dbus.c \ src/login/logind-acl.h nodist_systemd_logind_SOURCES = \ @@ -3748,8 +3809,7 @@ nodist_systemunit_DATA += \ units/systemd-user-sessions.service dist_systemunit_DATA += \ - units/user.slice \ - units/machine.slice + units/user.slice dist_dbussystemservice_DATA += \ src/login/org.freedesktop.login1.service diff --git a/configure.ac b/configure.ac index fc71b74c96..0881e47365 100644 --- a/configure.ac +++ b/configure.ac @@ -644,6 +644,15 @@ fi AM_CONDITIONAL(ENABLE_LOGIND, [test "$have_logind" = "yes"]) AS_IF([test "$have_logind" = "yes"], [ AC_DEFINE(HAVE_LOGIND, [1], [Logind support available]) ]) +# ------------------------------------------------------------------------------ +have_machined=no +AC_ARG_ENABLE(machined, AS_HELP_STRING([--disable-machined], [disable machine daemon])) +if test "x$enable_machined" != "xno"; then + have_machined=yes +fi +AM_CONDITIONAL(ENABLE_MACHINED, [test "$have_machined" = "yes"]) +AS_IF([test "$have_machined" = "yes"], [ AC_DEFINE(HAVE_MACHINED, [1], [Machined support available]) ]) + # ------------------------------------------------------------------------------ have_hostnamed=no AC_ARG_ENABLE(hostnamed, AS_HELP_STRING([--disable-hostnamed], [disable hostname daemon])) @@ -968,6 +977,7 @@ AC_MSG_RESULT([ tmpfiles: ${have_tmpfiles} randomseed: ${have_randomseed} logind: ${have_logind} + machined: ${have_machined} hostnamed: ${have_hostnamed} timedated: ${have_timedated} localed: ${have_localed} diff --git a/src/login/loginctl.c b/src/login/loginctl.c index 3637a408dc..e118deffda 100644 --- a/src/login/loginctl.c +++ b/src/login/loginctl.c @@ -261,69 +261,6 @@ static int list_seats(DBusConnection *bus, char **args, unsigned n) { return 0; } -static int list_machines(DBusConnection *bus, char **args, unsigned n) { - _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; - DBusMessageIter iter, sub, sub2; - unsigned k = 0; - int r; - - pager_open_if_enabled(); - - r = bus_method_call_with_reply ( - bus, - "org.freedesktop.login1", - "/org/freedesktop/login1", - "org.freedesktop.login1.Manager", - "ListMachines", - &reply, - NULL, - DBUS_TYPE_INVALID); - if (r) - return r; - - if (!dbus_message_iter_init(reply, &iter) || - dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || - dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT) { - log_error("Failed to parse reply."); - return -EIO; - } - - dbus_message_iter_recurse(&iter, &sub); - - if (on_tty()) - printf("%-32s %-9s %-16s\n", "MACHINE", "CONTAINER", "SERVICE"); - - while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { - const char *name, *class, *service, *object; - - if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) { - log_error("Failed to parse reply."); - return -EIO; - } - - dbus_message_iter_recurse(&sub, &sub2); - - if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0 || - bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &class, true) < 0 || - bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &service, true) < 0 || - bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &object, false) < 0) { - log_error("Failed to parse reply."); - return -EIO; - } - - printf("%-32s %-9s %-16s\n", name, class, service); - - k++; - - dbus_message_iter_next(&sub); - } - - if (on_tty()) - printf("\n%u machines listed.\n", k); - - return 0; -} - typedef struct SessionStatusInfo { const char *id; uid_t uid; @@ -362,18 +299,6 @@ typedef struct SeatStatusInfo { char **sessions; } SeatStatusInfo; -typedef struct MachineStatusInfo { - const char *name; - sd_id128_t id; - const char *default_control_group; - const char *class; - const char *service; - const char *slice; - const char *root_directory; - pid_t leader; - usec_t timestamp; -} MachineStatusInfo; - static void print_session_status_info(SessionStatusInfo *i) { char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1; char since2[FORMAT_TIMESTAMP_MAX], *s2; @@ -569,76 +494,6 @@ static void print_seat_status_info(SeatStatusInfo *i) { } } -static void print_machine_status_info(MachineStatusInfo *i) { - char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1; - char since2[FORMAT_TIMESTAMP_MAX], *s2; - assert(i); - - fputs(strna(i->name), stdout); - - if (!sd_id128_equal(i->id, SD_ID128_NULL)) - printf("(" SD_ID128_FORMAT_STR ")\n", SD_ID128_FORMAT_VAL(i->id)); - else - putchar('\n'); - - s1 = format_timestamp_relative(since1, sizeof(since1), i->timestamp); - s2 = format_timestamp(since2, sizeof(since2), i->timestamp); - - if (s1) - printf("\t Since: %s; %s\n", s2, s1); - else if (s2) - printf("\t Since: %s\n", s2); - - if (i->leader > 0) { - _cleanup_free_ char *t = NULL; - - printf("\t Leader: %u", (unsigned) i->leader); - - get_process_comm(i->leader, &t); - if (t) - printf(" (%s)", t); - - putchar('\n'); - } - - if (i->service) { - printf("\t Service: %s", i->service); - - if (i->class) - printf("; class %s", i->class); - - putchar('\n'); - } else if (i->class) - printf("\t Class: %s\n", i->class); - - if (i->slice) - printf("\t Slice: %s\n", i->slice); - if (i->root_directory) - printf("\t Root: %s\n", i->root_directory); - - if (i->default_control_group) { - unsigned c; - int output_flags = - arg_all * OUTPUT_SHOW_ALL | - arg_full * OUTPUT_FULL_WIDTH; - - printf("\t CGroup: %s\n", i->default_control_group); - - if (arg_transport != TRANSPORT_SSH) { - c = columns(); - if (c > 18) - c -= 18; - else - c = 0; - - show_cgroup_and_extra_by_spec(i->default_control_group, - "\t\t ", c, false, &i->leader, - i->leader > 0 ? 1 : 0, - output_flags); - } - } -} - static int status_property_session(const char *name, DBusMessageIter *iter, SessionStatusInfo *i) { assert(name); assert(iter); @@ -912,80 +767,6 @@ static int status_property_seat(const char *name, DBusMessageIter *iter, SeatSta return 0; } -static int status_property_machine(const char *name, DBusMessageIter *iter, MachineStatusInfo *i) { - assert(name); - assert(iter); - assert(i); - - switch (dbus_message_iter_get_arg_type(iter)) { - - case DBUS_TYPE_STRING: { - const char *s; - - dbus_message_iter_get_basic(iter, &s); - - if (!isempty(s)) { - if (streq(name, "Name")) - i->name = s; - else if (streq(name, "DefaultControlGroup")) - i->default_control_group = s; - else if (streq(name, "Class")) - i->class = s; - else if (streq(name, "Service")) - i->service = s; - else if (streq(name, "Slice")) - i->slice = s; - else if (streq(name, "RootDirectory")) - i->root_directory = s; - } - break; - } - - case DBUS_TYPE_UINT32: { - uint32_t u; - - dbus_message_iter_get_basic(iter, &u); - - if (streq(name, "Leader")) - i->leader = (pid_t) u; - - break; - } - - case DBUS_TYPE_UINT64: { - uint64_t u; - - dbus_message_iter_get_basic(iter, &u); - - if (streq(name, "Timestamp")) - i->timestamp = (usec_t) u; - - break; - } - - case DBUS_TYPE_ARRAY: { - DBusMessageIter sub; - - dbus_message_iter_recurse(iter, &sub); - - if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_BYTE && streq(name, "Id")) { - void *v; - int n; - - dbus_message_iter_get_fixed_array(&sub, &v, &n); - if (n == 0) - i->id = SD_ID128_NULL; - else if (n == 16) - memcpy(&i->id, v, n); - } - - break; - } - } - - return 0; -} - static int print_property(const char *name, DBusMessageIter *iter) { assert(name); assert(iter); @@ -1067,7 +848,6 @@ static int show_one(const char *verb, DBusConnection *bus, const char *path, boo SessionStatusInfo session_info = {}; UserStatusInfo user_info = {}; SeatStatusInfo seat_info = {}; - MachineStatusInfo machine_info = {}; assert(path); assert(new_line); @@ -1131,10 +911,8 @@ static int show_one(const char *verb, DBusConnection *bus, const char *path, boo r = status_property_session(name, &sub3, &session_info); else if (strstr(verb, "user")) r = status_property_user(name, &sub3, &user_info); - else if (strstr(verb, "seat")) - r = status_property_seat(name, &sub3, &seat_info); else - r = status_property_machine(name, &sub3, &machine_info); + r = status_property_seat(name, &sub3, &seat_info); if (r < 0) { log_error("Failed to parse reply."); @@ -1149,10 +927,8 @@ static int show_one(const char *verb, DBusConnection *bus, const char *path, boo print_session_status_info(&session_info); else if (strstr(verb, "user")) print_user_status_info(&user_info); - else if (strstr(verb, "seat")) - print_seat_status_info(&seat_info); else - print_machine_status_info(&machine_info); + print_seat_status_info(&seat_info); } r = 0; @@ -1226,7 +1002,7 @@ static int show(DBusConnection *bus, char **args, unsigned n) { DBUS_TYPE_UINT32, &u, DBUS_TYPE_INVALID); - } else if (strstr(args[0], "seat")) { + } else { ret = bus_method_call_with_reply( bus, @@ -1239,18 +1015,6 @@ static int show(DBusConnection *bus, char **args, unsigned n) { DBUS_TYPE_STRING, &args[i], DBUS_TYPE_INVALID); - } else { - - ret = bus_method_call_with_reply( - bus, - "org.freedesktop.login1", - "/org/freedesktop/login1", - "org.freedesktop.login1.Manager", - "GetMachine", - &reply, - NULL, - DBUS_TYPE_STRING, &args[i], - DBUS_TYPE_INVALID); } if (ret < 0) @@ -1334,36 +1098,6 @@ static int kill_session(DBusConnection *bus, char **args, unsigned n) { return 0; } -static int kill_machine(DBusConnection *bus, char **args, unsigned n) { - unsigned i; - - assert(args); - - if (!arg_kill_who) - arg_kill_who = "all"; - - for (i = 1; i < n; i++) { - int r; - - r = bus_method_call_with_reply ( - bus, - "org.freedesktop.login1", - "/org/freedesktop/login1", - "org.freedesktop.login1.Manager", - "KillMachine", - NULL, - NULL, - DBUS_TYPE_STRING, &args[i], - DBUS_TYPE_STRING, &arg_kill_who, - DBUS_TYPE_INT32, &arg_signal, - DBUS_TYPE_INVALID); - if (r) - return r; - } - - return 0; -} - static int enable_linger(DBusConnection *bus, char **args, unsigned n) { unsigned i; dbus_bool_t b, interactive = true; @@ -1567,31 +1301,6 @@ static int terminate_seat(DBusConnection *bus, char **args, unsigned n) { return 0; } -static int terminate_machine(DBusConnection *bus, char **args, unsigned n) { - unsigned i; - - assert(args); - - for (i = 1; i < n; i++) { - int r; - - r = bus_method_call_with_reply ( - bus, - "org.freedesktop.login1", - "/org/freedesktop/login1", - "org.freedesktop.login1.Manager", - "TerminateMachine", - NULL, - NULL, - DBUS_TYPE_STRING, &args[i], - DBUS_TYPE_INVALID); - if (r) - return r; - } - - return 0; -} - static int help(void) { printf("%s [OPTIONS...] {COMMAND} ...\n\n" @@ -1630,12 +1339,7 @@ static int help(void) { " show-seat [NAME...] Show properties of one or more seats\n" " attach [NAME] [DEVICE...] Attach one or more devices to a seat\n" " flush-devices Flush all device associations\n" - " terminate-seat [NAME...] Terminate all sessions on one or more seats\n" - " list-machines List running VMs and containers\n" - " machine-status [NAME...] Show VM/container status\n" - " show-machine [NAME...] Show properties of one or more VMs/containers\n" - " terminate-machine [NAME...] Terminate one or more VMs/containers\n" - " kill-machine [NAME...] Send signal to processes of a VM/container\n", + " terminate-seat [NAME...] Terminate all sessions on one or more seats\n", program_invocation_short_name); return 0; @@ -1784,11 +1488,6 @@ static int loginctl_main(DBusConnection *bus, int argc, char *argv[], DBusError { "attach", MORE, 3, attach }, { "flush-devices", EQUAL, 1, flush_devices }, { "terminate-seat", MORE, 2, terminate_seat }, - { "list-machines", EQUAL, 1, list_machines }, - { "machine-status", MORE, 2, show }, - { "show-machine", MORE, 1, show }, - { "terminate-machine", MORE, 2, terminate_machine }, - { "kill-machine", MORE, 2, kill_machine }, }; int left; diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index d8d25b0041..9a19932af4 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -63,14 +63,6 @@ " \n" \ " \n" \ " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ " \n" \ " \n" \ " \n" \ @@ -80,9 +72,6 @@ " \n" \ " \n" \ " \n" \ - " \n" \ - " \n" \ - " \n" \ " \n" \ " \n" \ " \n" \ @@ -108,16 +97,6 @@ " \n" \ " \n" \ " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ " \n" \ " \n" \ " \n" \ @@ -151,9 +130,6 @@ " \n" \ " \n" \ " \n" \ - " \n" \ - " \n" \ - " \n" \ " \n" \ " \n" \ " \n" \ @@ -231,22 +207,12 @@ " \n" \ " \n" \ " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ - " \n" \ - " \n" \ " \n" \ " \n" \ " \n" \ @@ -689,148 +655,6 @@ fail: return r; } -static bool valid_machine_name(const char *p) { - size_t l; - - if (!filename_is_safe(p)) - return false; - - if (!ascii_is_valid(p)) - return false; - - l = strlen(p); - - if (l < 1 || l> 64) - return false; - - return true; -} - -static int bus_manager_create_machine(Manager *manager, DBusMessage *message) { - - const char *name, *service, *class, *slice, *root_directory; - _cleanup_free_ char *p = NULL; - DBusMessageIter iter, sub; - MachineClass c; - uint32_t leader; - sd_id128_t id; - Machine *m; - int n, r; - void *v; - - assert(manager); - assert(message); - - if (!dbus_message_iter_init(message, &iter) || - dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) - return -EINVAL; - - dbus_message_iter_get_basic(&iter, &name); - - if (!valid_machine_name(name) || - !dbus_message_iter_next(&iter) || - dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || - dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_BYTE) - return -EINVAL; - - dbus_message_iter_recurse(&iter, &sub); - dbus_message_iter_get_fixed_array(&sub, &v, &n); - - if (n == 0) - id = SD_ID128_NULL; - else if (n == 16) - memcpy(&id, v, n); - else - return -EINVAL; - - if (!dbus_message_iter_next(&iter) || - dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) - return -EINVAL; - - dbus_message_iter_get_basic(&iter, &service); - - if (!dbus_message_iter_next(&iter) || - dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) - return -EINVAL; - - dbus_message_iter_get_basic(&iter, &class); - - if (isempty(class)) - c = _MACHINE_CLASS_INVALID; - else { - c = machine_class_from_string(class); - if (c < 0) - return -EINVAL; - } - - if (!dbus_message_iter_next(&iter) || - dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) - return -EINVAL; - - dbus_message_iter_get_basic(&iter, &leader); - if (!dbus_message_iter_next(&iter) || - dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) - return -EINVAL; - - dbus_message_iter_get_basic(&iter, &slice); - if (!(isempty(slice) || (unit_name_is_valid(slice, false) && endswith(slice, ".slice"))) || - !dbus_message_iter_next(&iter) || - dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) - return -EINVAL; - - dbus_message_iter_get_basic(&iter, &root_directory); - - if (!(isempty(root_directory) || path_is_absolute(root_directory))) - return -EINVAL; - - if (hashmap_get(manager->machines, name)) - return -EEXIST; - - if (leader <= 0) { - leader = bus_get_unix_process_id(manager->bus, dbus_message_get_sender(message), NULL); - if (leader == 0) - return -EINVAL; - } - - r = manager_add_machine(manager, name, &m); - if (r < 0) - goto fail; - - m->leader = leader; - m->class = c; - m->id = id; - - if (!isempty(service)) { - m->service = strdup(service); - if (!m->service) { - r = -ENOMEM; - goto fail; - } - } - - if (!isempty(root_directory)) { - m->root_directory = strdup(root_directory); - if (!m->root_directory) { - r = -ENOMEM; - goto fail; - } - } - - r = machine_start(m); - if (r < 0) - goto fail; - - m->create_message = dbus_message_ref(message); - - return 0; - -fail: - if (m) - machine_add_to_gc_queue(m); - - return r; -} - static int bus_manager_inhibit( Manager *m, DBusConnection *connection, @@ -1671,73 +1495,6 @@ static DBusHandlerResult manager_message_handler( DBUS_TYPE_INVALID); free(p); - if (!b) - goto oom; - } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "GetMachine")) { - Machine *machine; - const char *name; - char *p; - bool b; - - if (!dbus_message_get_args( - message, - &error, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_INVALID)) - return bus_send_error_reply(connection, message, &error, -EINVAL); - - machine = hashmap_get(m->machines, name); - if (!machine) - return bus_send_error_reply(connection, message, &error, -ENOENT); - - reply = dbus_message_new_method_return(message); - if (!reply) - goto oom; - - p = machine_bus_path(machine); - if (!p) - goto oom; - - b = dbus_message_append_args( - reply, - DBUS_TYPE_OBJECT_PATH, &p, - DBUS_TYPE_INVALID); - free(p); - - if (!b) - goto oom; - - } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "GetMachineByPID")) { - uint32_t pid; - char *p; - Machine *machine; - bool b; - - if (!dbus_message_get_args( - message, - &error, - DBUS_TYPE_UINT32, &pid, - DBUS_TYPE_INVALID)) - return bus_send_error_reply(connection, message, &error, -EINVAL); - - r = manager_get_machine_by_pid(m, pid, &machine); - if (r <= 0) - return bus_send_error_reply(connection, message, NULL, r < 0 ? r : -ENOENT); - - reply = dbus_message_new_method_return(message); - if (!reply) - goto oom; - - p = machine_bus_path(machine); - if (!p) - goto oom; - - b = dbus_message_append_args( - reply, - DBUS_TYPE_OBJECT_PATH, &p, - DBUS_TYPE_INVALID); - free(p); - if (!b) goto oom; @@ -1946,48 +1703,6 @@ static DBusHandlerResult manager_message_handler( if (!dbus_message_iter_close_container(&iter, &sub)) goto oom; - } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ListMachines")) { - Machine *machine; - Iterator i; - DBusMessageIter iter, sub; - - reply = dbus_message_new_method_return(message); - if (!reply) - goto oom; - - dbus_message_iter_init_append(reply, &iter); - - if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(ssso)", &sub)) - goto oom; - - HASHMAP_FOREACH(machine, m->machines, i) { - _cleanup_free_ char *p = NULL; - DBusMessageIter sub2; - const char *class; - - if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2)) - goto oom; - - p = machine_bus_path(machine); - if (!p) - goto oom; - - class = strempty(machine_class_to_string(machine->class)); - - if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &machine->name) || - !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &class) || - !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &machine->service) || - !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &p)) { - free(p); - goto oom; - } - - if (!dbus_message_iter_close_container(&sub, &sub2)) - goto oom; - } - - if (!dbus_message_iter_close_container(&iter, &sub)) - goto oom; } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "Inhibit")) { @@ -2009,12 +1724,6 @@ static DBusHandlerResult manager_message_handler( if (r < 0) return bus_send_error_reply(connection, message, NULL, r); - } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "CreateMachine")) { - - r = bus_manager_create_machine(m, message); - if (r < 0) - return bus_send_error_reply(connection, message, NULL, r); - } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ReleaseSession")) { const char *name; Session *session; @@ -2201,45 +1910,6 @@ static DBusHandlerResult manager_message_handler( if (!reply) goto oom; - } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "KillMachine")) { - const char *swho; - int32_t signo; - KillWho who; - const char *name; - Machine *machine; - - if (!dbus_message_get_args( - message, - &error, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_STRING, &swho, - DBUS_TYPE_INT32, &signo, - DBUS_TYPE_INVALID)) - return bus_send_error_reply(connection, message, &error, -EINVAL); - - if (isempty(swho)) - who = KILL_ALL; - else { - who = kill_who_from_string(swho); - if (who < 0) - return bus_send_error_reply(connection, message, &error, -EINVAL); - } - - if (signo <= 0 || signo >= _NSIG) - return bus_send_error_reply(connection, message, &error, -EINVAL); - - machine = hashmap_get(m->machines, name); - if (!machine) - return bus_send_error_reply(connection, message, &error, -ENOENT); - - r = machine_kill(machine, who, signo); - if (r < 0) - return bus_send_error_reply(connection, message, NULL, r); - - reply = dbus_message_new_method_return(message); - if (!reply) - goto oom; - } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "TerminateSession")) { const char *name; Session *session; @@ -2309,29 +1979,6 @@ static DBusHandlerResult manager_message_handler( if (!reply) goto oom; - } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "TerminateMachine")) { - const char *name; - Machine *machine; - - if (!dbus_message_get_args( - message, - &error, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_INVALID)) - return bus_send_error_reply(connection, message, &error, -EINVAL); - - machine = hashmap_get(m->machines, name); - if (!machine) - return bus_send_error_reply(connection, message, &error, -ENOENT); - - r = machine_stop(machine); - if (r < 0) - return bus_send_error_reply(connection, message, NULL, r); - - reply = dbus_message_new_method_return(message); - if (!reply) - goto oom; - } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "SetUserLinger")) { uint32_t uid; struct passwd *pw; @@ -2701,7 +2348,6 @@ DBusHandlerResult bus_message_filter( m->action_what = 0; } else { - Machine *mm; Session *s; User *u; @@ -2738,25 +2384,6 @@ DBusHandlerResult bus_message_filter( user_add_to_gc_queue(u); } - - mm = hashmap_get(m->machine_units, unit); - if (mm) { - if (streq_ptr(path, mm->scope_job)) { - free(mm->scope_job); - mm->scope_job = NULL; - - if (mm->started) { - if (streq(result, "done")) - machine_send_create_reply(mm, NULL); - else { - dbus_set_error(&error, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result); - machine_send_create_reply(mm, &error); - } - } - } - - machine_add_to_gc_queue(mm); - } } } else if (dbus_message_is_signal(message, "org.freedesktop.DBus.Properties", "PropertiesChanged")) { @@ -2771,7 +2398,6 @@ DBusHandlerResult bus_message_filter( unit_name_from_dbus_path(path, &unit); if (unit) { - Machine *mm; Session *s; User *u; @@ -2782,10 +2408,6 @@ DBusHandlerResult bus_message_filter( u = hashmap_get(m->user_units, unit); if (u) user_add_to_gc_queue(u); - - mm = hashmap_get(m->machine_units, unit); - if (mm) - machine_add_to_gc_queue(mm); } } diff --git a/src/login/logind-machine-dbus.c b/src/login/logind-machine-dbus.c deleted file mode 100644 index ae8c5d720a..0000000000 --- a/src/login/logind-machine-dbus.c +++ /dev/null @@ -1,360 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2011 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see . -***/ - -#include -#include - -#include "logind.h" -#include "logind-machine.h" -#include "dbus-common.h" - -#define BUS_MACHINE_INTERFACE \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" - -#define INTROSPECTION \ - DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ - "\n" \ - BUS_MACHINE_INTERFACE \ - BUS_PROPERTIES_INTERFACE \ - BUS_PEER_INTERFACE \ - BUS_INTROSPECTABLE_INTERFACE \ - "\n" - -#define INTERFACES_LIST \ - BUS_GENERIC_INTERFACES_LIST \ - "org.freedesktop.login1.Machine\0" - -static int bus_machine_append_id(DBusMessageIter *i, const char *property, void *data) { - DBusMessageIter sub; - Machine *m = data; - dbus_bool_t b; - void *p; - - assert(i); - assert(property); - assert(m); - - if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "y", &sub)) - return -ENOMEM; - - p = &m->id; - b = dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_BYTE, &p, 16); - if (!b) - return -ENOMEM; - - if (!dbus_message_iter_close_container(i, &sub)) - return -ENOMEM; - - return 0; -} - -static int bus_machine_append_state(DBusMessageIter *i, const char *property, void *data) { - Machine *m = data; - const char *state; - - assert(i); - assert(property); - assert(m); - - state = machine_state_to_string(machine_get_state(m)); - - if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &state)) - return -ENOMEM; - - return 0; -} - -static int get_machine_for_path(Manager *m, const char *path, Machine **_machine) { - _cleanup_free_ char *e = NULL; - Machine *machine; - - assert(m); - assert(path); - assert(_machine); - - if (!startswith(path, "/org/freedesktop/login1/machine/")) - return -EINVAL; - - e = bus_path_unescape(path + 32); - if (!e) - return -ENOMEM; - - machine = hashmap_get(m->machines, e); - if (!machine) - return -ENOENT; - - *_machine = machine; - return 0; -} - -static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_machine_append_class, machine_class, MachineClass); - -static const BusProperty bus_login_machine_properties[] = { - { "Name", bus_property_append_string, "s", offsetof(Machine, name), true }, - { "Id", bus_machine_append_id, "ay", 0 }, - { "Timestamp", bus_property_append_usec, "t", offsetof(Machine, timestamp.realtime) }, - { "TimestampMonotonic", bus_property_append_usec, "t", offsetof(Machine, timestamp.monotonic) }, - { "Service", bus_property_append_string, "s", offsetof(Machine, service), true }, - { "Scope", bus_property_append_string, "s", offsetof(Machine, scope), true }, - { "Leader", bus_property_append_pid, "u", offsetof(Session, leader) }, - { "Class", bus_machine_append_class, "s", offsetof(Machine, class) }, - { "State", bus_machine_append_state, "s", 0 }, - { "RootDirectory", bus_property_append_string, "s", offsetof(Machine, root_directory), true }, - { NULL, } -}; - -static DBusHandlerResult machine_message_dispatch( - Machine *m, - DBusConnection *connection, - DBusMessage *message) { - - DBusError error; - _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; - int r; - - assert(m); - assert(connection); - assert(message); - - if (dbus_message_is_method_call(message, "org.freedesktop.login1.Machine", "Terminate")) { - - r = machine_stop(m); - if (r < 0) - return bus_send_error_reply(connection, message, NULL, r); - - reply = dbus_message_new_method_return(message); - if (!reply) - goto oom; - - } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Machine", "Kill")) { - const char *swho; - int32_t signo; - KillWho who; - - if (!dbus_message_get_args( - message, - &error, - DBUS_TYPE_STRING, &swho, - DBUS_TYPE_INT32, &signo, - DBUS_TYPE_INVALID)) - return bus_send_error_reply(connection, message, &error, -EINVAL); - - if (isempty(swho)) - who = KILL_ALL; - else { - who = kill_who_from_string(swho); - if (who < 0) - return bus_send_error_reply(connection, message, &error, -EINVAL); - } - - if (signo <= 0 || signo >= _NSIG) - return bus_send_error_reply(connection, message, &error, -EINVAL); - - r = machine_kill(m, who, signo); - if (r < 0) - return bus_send_error_reply(connection, message, NULL, r); - - reply = dbus_message_new_method_return(message); - if (!reply) - goto oom; - - } else { - const BusBoundProperties bps[] = { - { "org.freedesktop.login1.Machine", bus_login_machine_properties, m }, - { NULL, } - }; - - return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps); - } - - if (reply) { - if (!bus_maybe_send_reply(connection, message, reply)) - goto oom; - } - - return DBUS_HANDLER_RESULT_HANDLED; - -oom: - dbus_error_free(&error); - - return DBUS_HANDLER_RESULT_NEED_MEMORY; -} - -static DBusHandlerResult machine_message_handler( - DBusConnection *connection, - DBusMessage *message, - void *userdata) { - - Manager *manager = userdata; - Machine *m; - int r; - - r = get_machine_for_path(manager, dbus_message_get_path(message), &m); - if (r < 0) { - - if (r == -ENOMEM) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - if (r == -ENOENT) { - DBusError e; - - dbus_error_init(&e); - dbus_set_error_const(&e, DBUS_ERROR_UNKNOWN_OBJECT, "Unknown machine"); - return bus_send_error_reply(connection, message, &e, r); - } - - return bus_send_error_reply(connection, message, NULL, r); - } - - return machine_message_dispatch(m, connection, message); -} - -const DBusObjectPathVTable bus_machine_vtable = { - .message_function = machine_message_handler -}; - -char *machine_bus_path(Machine *m) { - _cleanup_free_ char *e = NULL; - - assert(m); - - e = bus_path_escape(m->name); - if (!e) - return NULL; - - return strappend("/org/freedesktop/login1/machine/", e); -} - -int machine_send_signal(Machine *m, bool new_machine) { - _cleanup_dbus_message_unref_ DBusMessage *msg = NULL; - _cleanup_free_ char *p = NULL; - - assert(m); - - msg = dbus_message_new_signal("/org/freedesktop/login1", - "org.freedesktop.login1.Manager", - new_machine ? "MachineNew" : "MachineRemoved"); - - if (!m) - return -ENOMEM; - - p = machine_bus_path(m); - if (!p) - return -ENOMEM; - - if (!dbus_message_append_args( - msg, - DBUS_TYPE_STRING, &m->name, - DBUS_TYPE_OBJECT_PATH, &p, - DBUS_TYPE_INVALID)) - return -ENOMEM; - - if (!dbus_connection_send(m->manager->bus, msg, NULL)) - return -ENOMEM; - - return 0; -} - -int machine_send_changed(Machine *m, const char *properties) { - _cleanup_dbus_message_unref_ DBusMessage *msg = NULL; - _cleanup_free_ char *p = NULL; - - assert(m); - - if (!m->started) - return 0; - - p = machine_bus_path(m); - if (!p) - return -ENOMEM; - - msg = bus_properties_changed_new(p, "org.freedesktop.login1.Machine", properties); - if (!msg) - return -ENOMEM; - - if (!dbus_connection_send(m->manager->bus, msg, NULL)) - return -ENOMEM; - - return 0; -} - -int machine_send_create_reply(Machine *m, DBusError *error) { - _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; - - assert(m); - - if (!m->create_message) - return 0; - - if (error) { - DBusError buffer; - - dbus_error_init(&buffer); - - if (!error || !dbus_error_is_set(error)) { - dbus_set_error_const(&buffer, DBUS_ERROR_INVALID_ARGS, "Invalid Arguments"); - error = &buffer; - } - - reply = dbus_message_new_error(m->create_message, error->name, error->message); - dbus_error_free(&buffer); - - if (!reply) - return log_oom(); - } else { - _cleanup_free_ char *p = NULL; - - p = machine_bus_path(m); - if (!p) - return log_oom(); - - reply = dbus_message_new_method_return(m->create_message); - if (!reply) - return log_oom(); - - if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &p, DBUS_TYPE_INVALID)) - return log_oom(); - } - - if (!dbus_connection_send(m->manager->bus, reply, NULL)) - return log_oom(); - - dbus_message_unref(m->create_message); - m->create_message = NULL; - - return 0; -} diff --git a/src/login/logind-machine.c b/src/login/logind-machine.c deleted file mode 100644 index a1342c155e..0000000000 --- a/src/login/logind-machine.c +++ /dev/null @@ -1,403 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2011 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see . -***/ - -#include -#include -#include - -#include - -#include "util.h" -#include "mkdir.h" -#include "cgroup-util.h" -#include "hashmap.h" -#include "strv.h" -#include "fileio.h" -#include "special.h" -#include "unit-name.h" -#include "dbus-common.h" -#include "logind-machine.h" - -Machine* machine_new(Manager *manager, const char *name) { - Machine *m; - - assert(manager); - assert(name); - - m = new0(Machine, 1); - if (!m) - return NULL; - - m->name = strdup(name); - if (!m->name) - goto fail; - - m->state_file = strappend("/run/systemd/machines/", m->name); - if (!m->state_file) - goto fail; - - if (hashmap_put(manager->machines, m->name, m) < 0) - goto fail; - - m->class = _MACHINE_CLASS_INVALID; - m->manager = manager; - - return m; - -fail: - free(m->state_file); - free(m->name); - free(m); - - return NULL; -} - -void machine_free(Machine *m) { - assert(m); - - if (m->in_gc_queue) - LIST_REMOVE(Machine, gc_queue, m->manager->machine_gc_queue, m); - - if (m->scope) { - hashmap_remove(m->manager->machine_units, m->scope); - free(m->scope); - } - - free(m->scope_job); - - hashmap_remove(m->manager->machines, m->name); - - if (m->create_message) - dbus_message_unref(m->create_message); - - free(m->name); - free(m->state_file); - free(m->service); - free(m->root_directory); - free(m); -} - -int machine_save(Machine *m) { - _cleanup_free_ char *temp_path = NULL; - _cleanup_fclose_ FILE *f = NULL; - int r; - - assert(m); - assert(m->state_file); - - if (!m->started) - return 0; - - r = mkdir_safe_label("/run/systemd/machines", 0755, 0, 0); - if (r < 0) - goto finish; - - r = fopen_temporary(m->state_file, &f, &temp_path); - if (r < 0) - goto finish; - - fchmod(fileno(f), 0644); - - fprintf(f, - "# This is private data. Do not parse.\n" - "NAME=%s\n", - m->name); - - if (m->scope) - fprintf(f, "SCOPE=%s\n", m->scope); - - if (m->scope_job) - fprintf(f, "SCOPE_JOB=%s\n", m->scope_job); - - if (m->service) - fprintf(f, "SERVICE=%s\n", m->service); - - if (m->root_directory) - fprintf(f, "ROOT=%s\n", m->root_directory); - - if (!sd_id128_equal(m->id, SD_ID128_NULL)) - fprintf(f, "ID=" SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(m->id)); - - if (m->leader != 0) - fprintf(f, "LEADER=%lu\n", (unsigned long) m->leader); - - if (m->class != _MACHINE_CLASS_INVALID) - fprintf(f, "CLASS=%s\n", machine_class_to_string(m->class)); - - if (dual_timestamp_is_set(&m->timestamp)) - fprintf(f, - "REALTIME=%llu\n" - "MONOTONIC=%llu\n", - (unsigned long long) m->timestamp.realtime, - (unsigned long long) m->timestamp.monotonic); - - fflush(f); - - if (ferror(f) || rename(temp_path, m->state_file) < 0) { - r = -errno; - unlink(m->state_file); - unlink(temp_path); - } - -finish: - if (r < 0) - log_error("Failed to save machine data for %s: %s", m->name, strerror(-r)); - - return r; -} - -int machine_load(Machine *m) { - _cleanup_free_ char *realtime = NULL, *monotonic = NULL, *id = NULL, *leader = NULL, *class = NULL; - int r; - - assert(m); - - r = parse_env_file(m->state_file, NEWLINE, - "SCOPE", &m->scope, - "SCOPE_JOB", &m->scope_job, - "SERVICE", &m->service, - "ROOT", &m->root_directory, - "ID", &id, - "LEADER", &leader, - "CLASS", &class, - "REALTIME", &realtime, - "MONOTONIC", &monotonic, - NULL); - if (r < 0) { - if (r == -ENOENT) - return 0; - - log_error("Failed to read %s: %s", m->state_file, strerror(-r)); - return r; - } - - if (id) - sd_id128_from_string(id, &m->id); - - if (leader) - parse_pid(leader, &m->leader); - - if (class) { - MachineClass c; - - c = machine_class_from_string(class); - if (c >= 0) - m->class = c; - } - - if (realtime) { - unsigned long long l; - if (sscanf(realtime, "%llu", &l) > 0) - m->timestamp.realtime = l; - } - - if (monotonic) { - unsigned long long l; - if (sscanf(monotonic, "%llu", &l) > 0) - m->timestamp.monotonic = l; - } - - return r; -} - -static int machine_start_scope(Machine *m) { - _cleanup_free_ char *description = NULL; - DBusError error; - char *job; - int r; - - assert(m); - - dbus_error_init(&error); - - if (!m->scope) { - _cleanup_free_ char *escaped = NULL; - - escaped = unit_name_escape(m->name); - if (!escaped) - return log_oom(); - - m->scope = strjoin("machine-", m->name, ".scope", NULL); - if (!m->scope) - return log_oom(); - - r = hashmap_put(m->manager->machine_units, m->scope, m); - if (r < 0) - log_warning("Failed to create mapping between unit and machine"); - } - - description = strappend(m->class == MACHINE_VM ? "Virtual Machine " : "Container ", m->name); - - r = manager_start_scope(m->manager, m->scope, m->leader, SPECIAL_MACHINE_SLICE, description, &error, &job); - if (r < 0) { - log_error("Failed to start machine scope: %s", bus_error(&error, r)); - dbus_error_free(&error); - } - - free(m->scope_job); - m->scope_job = job; - - return r; -} - -int machine_start(Machine *m) { - int r; - - assert(m); - - if (m->started) - return 0; - - /* Create cgroup */ - r = machine_start_scope(m); - if (r < 0) - return r; - - log_struct(LOG_INFO, - MESSAGE_ID(SD_MESSAGE_MACHINE_START), - "NAME=%s", m->name, - "LEADER=%lu", (unsigned long) m->leader, - "MESSAGE=New machine %s.", m->name, - NULL); - - if (!dual_timestamp_is_set(&m->timestamp)) - dual_timestamp_get(&m->timestamp); - - m->started = true; - - /* Save new machine data */ - machine_save(m); - - machine_send_signal(m, true); - - return 0; -} - -static int machine_stop_scope(Machine *m) { - DBusError error; - char *job; - int r; - - assert(m); - - dbus_error_init(&error); - - if (!m->scope) - return 0; - - r = manager_stop_unit(m->manager, m->scope, &error, &job); - if (r < 0) { - log_error("Failed to stop machine scope: %s", bus_error(&error, r)); - dbus_error_free(&error); - return r; - } - - free(m->scope_job); - m->scope_job = job; - - return r; -} - -int machine_stop(Machine *m) { - int r = 0, k; - assert(m); - - if (m->started) - log_struct(LOG_INFO, - MESSAGE_ID(SD_MESSAGE_MACHINE_STOP), - "NAME=%s", m->name, - "LEADER=%lu", (unsigned long) m->leader, - "MESSAGE=Machine %s terminated.", m->name, - NULL); - - /* Kill cgroup */ - k = machine_stop_scope(m); - if (k < 0) - r = k; - - unlink(m->state_file); - machine_add_to_gc_queue(m); - - if (m->started) - machine_send_signal(m, false); - - m->started = false; - - return r; -} - -int machine_check_gc(Machine *m, bool drop_not_started) { - assert(m); - - if (drop_not_started && !m->started) - return 0; - - if (m->scope_job) - return 1; - - if (m->scope) - return manager_unit_is_active(m->manager, m->scope) != 0; - - return 0; -} - -void machine_add_to_gc_queue(Machine *m) { - assert(m); - - if (m->in_gc_queue) - return; - - LIST_PREPEND(Machine, gc_queue, m->manager->machine_gc_queue, m); - m->in_gc_queue = true; -} - -MachineState machine_get_state(Machine *s) { - assert(s); - - if (s->scope_job) - return s->started ? MACHINE_OPENING : MACHINE_CLOSING; - - return MACHINE_RUNNING; -} - -int machine_kill(Machine *m, KillWho who, int signo) { - assert(m); - - if (!m->scope) - return -ESRCH; - - return manager_kill_unit(m->manager, m->scope, who, signo, NULL); -} - -static const char* const machine_class_table[_MACHINE_CLASS_MAX] = { - [MACHINE_CONTAINER] = "container", - [MACHINE_VM] = "vm" -}; - -DEFINE_STRING_TABLE_LOOKUP(machine_class, MachineClass); - -static const char* const machine_state_table[_MACHINE_STATE_MAX] = { - [MACHINE_OPENING] = "opening", - [MACHINE_RUNNING] = "running", - [MACHINE_CLOSING] = "closing" -}; - -DEFINE_STRING_TABLE_LOOKUP(machine_state, MachineState); diff --git a/src/login/logind-machine.h b/src/login/logind-machine.h deleted file mode 100644 index a09f07195a..0000000000 --- a/src/login/logind-machine.h +++ /dev/null @@ -1,99 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -#pragma once - -/*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see . -***/ - -typedef struct Machine Machine; - -#include "list.h" -#include "util.h" -#include "logind.h" -#include "logind-session.h" - -typedef enum MachineState { - MACHINE_OPENING, /* Machine is being registered */ - MACHINE_RUNNING, /* Machine is running */ - MACHINE_CLOSING, /* Machine is terminating */ - _MACHINE_STATE_MAX, - _MACHINE_STATE_INVALID = -1 -} MachineState; - -typedef enum MachineClass { - MACHINE_CONTAINER, - MACHINE_VM, - _MACHINE_CLASS_MAX, - _MACHINE_CLASS_INVALID = -1 -} MachineClass; - -struct Machine { - Manager *manager; - - char *name; - sd_id128_t id; - - MachineState state; - MachineClass class; - - char *state_file; - char *service; - char *root_directory; - - char *scope; - char *scope_job; - - pid_t leader; - - dual_timestamp timestamp; - - bool in_gc_queue:1; - bool started:1; - - DBusMessage *create_message; - - LIST_FIELDS(Machine, gc_queue); -}; - -Machine* machine_new(Manager *manager, const char *name); -void machine_free(Machine *m); -int machine_check_gc(Machine *m, bool drop_not_started); -void machine_add_to_gc_queue(Machine *m); -int machine_start(Machine *m); -int machine_stop(Machine *m); -int machine_save(Machine *m); -int machine_load(Machine *m); -int machine_kill(Machine *m, KillWho who, int signo); - -char *machine_bus_path(Machine *s); - -MachineState machine_get_state(Machine *u); - -extern const DBusObjectPathVTable bus_machine_vtable; - -int machine_send_signal(Machine *m, bool new_machine); -int machine_send_changed(Machine *m, const char *properties); - -int machine_send_create_reply(Machine *m, DBusError *error); - -const char* machine_class_to_string(MachineClass t) _const_; -MachineClass machine_class_from_string(const char *s) _pure_; - -const char* machine_state_to_string(MachineState t) _const_; -MachineState machine_state_from_string(const char *s) _pure_; diff --git a/src/login/logind-user.c b/src/login/logind-user.c index 316c4cd095..fb961bf64b 100644 --- a/src/login/logind-user.c +++ b/src/login/logind-user.c @@ -354,11 +354,11 @@ static int user_start_slice(User *u) { if (r < 0) { log_error("Failed to start user slice: %s", bus_error(&error, r)); dbus_error_free(&error); + } else { + free(u->slice_job); + u->slice_job = job; } - free(u->slice_job); - u->slice_job = job; - return 0; } @@ -388,11 +388,11 @@ static int user_start_service(User *u) { if (r < 0) { log_error("Failed to start user service: %s", bus_error(&error, r)); dbus_error_free(&error); + } else { + free(u->service_job); + u->service_job = job; } - free(u->service_job); - u->service_job = job; - return 0; } diff --git a/src/login/logind.c b/src/login/logind.c index 7040ac9e8a..e37a1071a2 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -74,18 +74,16 @@ Manager *manager_new(void) { m->users = hashmap_new(trivial_hash_func, trivial_compare_func); m->inhibitors = hashmap_new(string_hash_func, string_compare_func); m->buttons = hashmap_new(string_hash_func, string_compare_func); - m->machines = hashmap_new(string_hash_func, string_compare_func); m->user_units = hashmap_new(string_hash_func, string_compare_func); m->session_units = hashmap_new(string_hash_func, string_compare_func); - m->machine_units = hashmap_new(string_hash_func, string_compare_func); m->session_fds = hashmap_new(trivial_hash_func, trivial_compare_func); m->inhibitor_fds = hashmap_new(trivial_hash_func, trivial_compare_func); m->button_fds = hashmap_new(trivial_hash_func, trivial_compare_func); - if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || !m->machines || - !m->user_units || !m->session_units || !m->machine_units || + if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || + !m->user_units || !m->session_units || !m->session_fds || !m->inhibitor_fds || !m->button_fds) { manager_free(m); return NULL; @@ -113,7 +111,6 @@ void manager_free(Manager *m) { Seat *s; Inhibitor *i; Button *b; - Machine *machine; assert(m); @@ -135,20 +132,15 @@ void manager_free(Manager *m) { while ((b = hashmap_first(m->buttons))) button_free(b); - while ((machine = hashmap_first(m->machines))) - machine_free(machine); - hashmap_free(m->devices); hashmap_free(m->seats); hashmap_free(m->sessions); hashmap_free(m->users); hashmap_free(m->inhibitors); hashmap_free(m->buttons); - hashmap_free(m->machines); hashmap_free(m->user_units); hashmap_free(m->session_units); - hashmap_free(m->machine_units); hashmap_free(m->session_fds); hashmap_free(m->inhibitor_fds); @@ -364,30 +356,6 @@ int manager_add_button(Manager *m, const char *name, Button **_button) { return 0; } -int manager_add_machine(Manager *m, const char *name, Machine **_machine) { - Machine *machine; - - assert(m); - assert(name); - - machine = hashmap_get(m->machines, name); - if (machine) { - if (_machine) - *_machine = machine; - - return 0; - } - - machine = machine_new(m, name); - if (!m) - return -ENOMEM; - - if (_machine) - *_machine = machine; - - return 0; -} - int manager_process_seat_device(Manager *m, struct udev_device *d) { Device *device; int r; @@ -772,48 +740,6 @@ int manager_enumerate_inhibitors(Manager *m) { return r; } -int manager_enumerate_machines(Manager *m) { - _cleanup_closedir_ DIR *d = NULL; - struct dirent *de; - int r = 0; - - assert(m); - - /* Read in machine data stored on disk */ - d = opendir("/run/systemd/machines"); - if (!d) { - if (errno == ENOENT) - return 0; - - log_error("Failed to open /run/systemd/machines: %m"); - return -errno; - } - - FOREACH_DIRENT(de, d, return -errno) { - struct Machine *machine; - int k; - - if (!dirent_is_file(de)) - continue; - - k = manager_add_machine(m, de->d_name, &machine); - if (k < 0) { - log_error("Failed to add machine by file name %s: %s", de->d_name, strerror(-k)); - - r = k; - continue; - } - - machine_add_to_gc_queue(machine); - - k = machine_load(machine); - if (k < 0) - r = k; - } - - return r; -} - int manager_dispatch_seat_udev(Manager *m) { struct udev_device *d; int r; @@ -1018,27 +944,6 @@ int manager_get_user_by_pid(Manager *m, pid_t pid, User **user) { return 1; } -int manager_get_machine_by_pid(Manager *m, pid_t pid, Machine **machine) { - _cleanup_free_ char *unit = NULL; - Machine *mm; - int r; - - assert(m); - assert(pid >= 1); - assert(machine); - - r = cg_pid_get_unit(pid, &unit); - if (r < 0) - return r; - - mm = hashmap_get(m->machine_units, unit); - if (!mm) - return 0; - - *machine = mm; - return 1; -} - static void manager_dispatch_other(Manager *m, int fd) { Session *s; Inhibitor *i; @@ -1098,7 +1003,6 @@ static int manager_connect_bus(Manager *m) { !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/seat", &bus_seat_vtable, m) || !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/session", &bus_session_vtable, m) || !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/user", &bus_user_vtable, m) || - !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/machine", &bus_machine_vtable, m) || !dbus_connection_add_filter(m->bus, bus_message_filter, m, NULL)) { r = log_oom(); goto fail; @@ -1298,7 +1202,6 @@ void manager_gc(Manager *m, bool drop_not_started) { Seat *seat; Session *session; User *user; - Machine *machine; assert(m); @@ -1331,16 +1234,6 @@ void manager_gc(Manager *m, bool drop_not_started) { user_free(user); } } - - while ((machine = m->machine_gc_queue)) { - LIST_REMOVE(Machine, gc_queue, m->machine_gc_queue, machine); - machine->in_gc_queue = false; - - if (machine_check_gc(machine, drop_not_started) == 0) { - machine_stop(machine); - machine_free(machine); - } - } } int manager_get_idle_hint(Manager *m, dual_timestamp *t) { @@ -1459,7 +1352,6 @@ int manager_startup(Manager *m) { Session *session; User *user; Inhibitor *inhibitor; - Machine *machine; Iterator i; assert(m); @@ -1496,7 +1388,6 @@ int manager_startup(Manager *m) { manager_enumerate_sessions(m); manager_enumerate_inhibitors(m); manager_enumerate_buttons(m); - manager_enumerate_machines(m); /* Remove stale objects before we start them */ manager_gc(m, false); @@ -1517,9 +1408,6 @@ int manager_startup(Manager *m) { HASHMAP_FOREACH(inhibitor, m->inhibitors, i) inhibitor_start(inhibitor); - HASHMAP_FOREACH(machine, m->machines, i) - machine_start(machine); - manager_dispatch_idle_action(m); return 0; @@ -1671,7 +1559,6 @@ int main(int argc, char *argv[]) { mkdir_label("/run/systemd/seats", 0755); mkdir_label("/run/systemd/users", 0755); mkdir_label("/run/systemd/sessions", 0755); - mkdir_label("/run/systemd/machines", 0755); m = manager_new(); if (!m) { diff --git a/src/login/logind.h b/src/login/logind.h index b7277af73d..f7457c0537 100644 --- a/src/login/logind.h +++ b/src/login/logind.h @@ -41,7 +41,6 @@ typedef struct Manager Manager; #include "logind-inhibit.h" #include "logind-button.h" #include "logind-action.h" -#include "logind-machine.h" struct Manager { DBusConnection *bus; @@ -52,12 +51,10 @@ struct Manager { Hashmap *users; Hashmap *inhibitors; Hashmap *buttons; - Hashmap *machines; LIST_HEAD(Seat, seat_gc_queue); LIST_HEAD(Session, session_gc_queue); LIST_HEAD(User, user_gc_queue); - LIST_HEAD(Machine, machine_gc_queue); struct udev *udev; struct udev_monitor *udev_seat_monitor, *udev_vcsa_monitor, *udev_button_monitor; @@ -85,7 +82,6 @@ struct Manager { Hashmap *session_units; Hashmap *user_units; - Hashmap *machine_units; Hashmap *session_fds; Hashmap *inhibitor_fds; @@ -144,7 +140,6 @@ int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User ** int manager_add_user_by_name(Manager *m, const char *name, User **_user); int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user); int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **_inhibitor); -int manager_add_machine(Manager *m, const char *name, Machine **_machine); int manager_process_seat_device(Manager *m, struct udev_device *d); int manager_process_button_device(Manager *m, struct udev_device *d); @@ -161,7 +156,6 @@ int manager_enumerate_seats(Manager *m); int manager_enumerate_sessions(Manager *m); int manager_enumerate_users(Manager *m); int manager_enumerate_inhibitors(Manager *m); -int manager_enumerate_machines(Manager *m); int manager_startup(Manager *m); int manager_run(Manager *m); @@ -173,7 +167,6 @@ int manager_get_idle_hint(Manager *m, dual_timestamp *t); int manager_get_user_by_pid(Manager *m, pid_t pid, User **user); int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session); -int manager_get_machine_by_pid(Manager *m, pid_t pid, Machine **machine); extern const DBusObjectPathVTable bus_manager_vtable; diff --git a/src/machine/Makefile b/src/machine/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/machine/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c new file mode 100644 index 0000000000..424f98edd5 --- /dev/null +++ b/src/machine/machine-dbus.c @@ -0,0 +1,359 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include "machined.h" +#include "machine.h" +#include "dbus-common.h" + +#define BUS_MACHINE_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_MACHINE_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.machine1.Machine\0" + +static int bus_machine_append_id(DBusMessageIter *i, const char *property, void *data) { + DBusMessageIter sub; + Machine *m = data; + dbus_bool_t b; + void *p; + + assert(i); + assert(property); + assert(m); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "y", &sub)) + return -ENOMEM; + + p = &m->id; + b = dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_BYTE, &p, 16); + if (!b) + return -ENOMEM; + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_machine_append_state(DBusMessageIter *i, const char *property, void *data) { + Machine *m = data; + const char *state; + + assert(i); + assert(property); + assert(m); + + state = machine_state_to_string(machine_get_state(m)); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &state)) + return -ENOMEM; + + return 0; +} + +static int get_machine_for_path(Manager *m, const char *path, Machine **_machine) { + _cleanup_free_ char *e = NULL; + Machine *machine; + + assert(m); + assert(path); + assert(_machine); + + if (!startswith(path, "/org/freedesktop/machine1/machine/")) + return -EINVAL; + + e = bus_path_unescape(path + 32); + if (!e) + return -ENOMEM; + + machine = hashmap_get(m->machines, e); + if (!machine) + return -ENOENT; + + *_machine = machine; + return 0; +} + +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_machine_append_class, machine_class, MachineClass); + +static const BusProperty bus_machine_machine_properties[] = { + { "Name", bus_property_append_string, "s", offsetof(Machine, name), true }, + { "Id", bus_machine_append_id, "ay", 0 }, + { "Timestamp", bus_property_append_usec, "t", offsetof(Machine, timestamp.realtime) }, + { "TimestampMonotonic", bus_property_append_usec, "t", offsetof(Machine, timestamp.monotonic) }, + { "Service", bus_property_append_string, "s", offsetof(Machine, service), true }, + { "Scope", bus_property_append_string, "s", offsetof(Machine, scope), true }, + { "Class", bus_machine_append_class, "s", offsetof(Machine, class) }, + { "State", bus_machine_append_state, "s", 0 }, + { "RootDirectory", bus_property_append_string, "s", offsetof(Machine, root_directory), true }, + { NULL, } +}; + +static DBusHandlerResult machine_message_dispatch( + Machine *m, + DBusConnection *connection, + DBusMessage *message) { + + DBusError error; + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + int r; + + assert(m); + assert(connection); + assert(message); + + if (dbus_message_is_method_call(message, "org.freedesktop.machine1.Machine", "Terminate")) { + + r = machine_stop(m); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.machine1.Machine", "Kill")) { + const char *swho; + int32_t signo; + KillWho who; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &swho, + DBUS_TYPE_INT32, &signo, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (isempty(swho)) + who = KILL_ALL; + else { + who = kill_who_from_string(swho); + if (who < 0) + return bus_send_error_reply(connection, message, &error, -EINVAL); + } + + if (signo <= 0 || signo >= _NSIG) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + r = machine_kill(m, who, signo); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else { + const BusBoundProperties bps[] = { + { "org.freedesktop.machine1.Machine", bus_machine_machine_properties, m }, + { NULL, } + }; + + return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps); + } + + if (reply) { + if (!bus_maybe_send_reply(connection, message, reply)) + goto oom; + } + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +static DBusHandlerResult machine_message_handler( + DBusConnection *connection, + DBusMessage *message, + void *userdata) { + + Manager *manager = userdata; + Machine *m; + int r; + + r = get_machine_for_path(manager, dbus_message_get_path(message), &m); + if (r < 0) { + + if (r == -ENOMEM) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + if (r == -ENOENT) { + DBusError e; + + dbus_error_init(&e); + dbus_set_error_const(&e, DBUS_ERROR_UNKNOWN_OBJECT, "Unknown machine"); + return bus_send_error_reply(connection, message, &e, r); + } + + return bus_send_error_reply(connection, message, NULL, r); + } + + return machine_message_dispatch(m, connection, message); +} + +const DBusObjectPathVTable bus_machine_vtable = { + .message_function = machine_message_handler +}; + +char *machine_bus_path(Machine *m) { + _cleanup_free_ char *e = NULL; + + assert(m); + + e = bus_path_escape(m->name); + if (!e) + return NULL; + + return strappend("/org/freedesktop/machine1/machine/", e); +} + +int machine_send_signal(Machine *m, bool new_machine) { + _cleanup_dbus_message_unref_ DBusMessage *msg = NULL; + _cleanup_free_ char *p = NULL; + + assert(m); + + msg = dbus_message_new_signal("/org/freedesktop/machine1", + "org.freedesktop.machine1.Manager", + new_machine ? "MachineNew" : "MachineRemoved"); + + if (!m) + return -ENOMEM; + + p = machine_bus_path(m); + if (!p) + return -ENOMEM; + + if (!dbus_message_append_args( + msg, + DBUS_TYPE_STRING, &m->name, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID)) + return -ENOMEM; + + if (!dbus_connection_send(m->manager->bus, msg, NULL)) + return -ENOMEM; + + return 0; +} + +int machine_send_changed(Machine *m, const char *properties) { + _cleanup_dbus_message_unref_ DBusMessage *msg = NULL; + _cleanup_free_ char *p = NULL; + + assert(m); + + if (!m->started) + return 0; + + p = machine_bus_path(m); + if (!p) + return -ENOMEM; + + msg = bus_properties_changed_new(p, "org.freedesktop.machine1.Machine", properties); + if (!msg) + return -ENOMEM; + + if (!dbus_connection_send(m->manager->bus, msg, NULL)) + return -ENOMEM; + + return 0; +} + +int machine_send_create_reply(Machine *m, DBusError *error) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + + assert(m); + + if (!m->create_message) + return 0; + + if (error) { + DBusError buffer; + + dbus_error_init(&buffer); + + if (!error || !dbus_error_is_set(error)) { + dbus_set_error_const(&buffer, DBUS_ERROR_INVALID_ARGS, "Invalid Arguments"); + error = &buffer; + } + + reply = dbus_message_new_error(m->create_message, error->name, error->message); + dbus_error_free(&buffer); + + if (!reply) + return log_oom(); + } else { + _cleanup_free_ char *p = NULL; + + p = machine_bus_path(m); + if (!p) + return log_oom(); + + reply = dbus_message_new_method_return(m->create_message); + if (!reply) + return log_oom(); + + if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &p, DBUS_TYPE_INVALID)) + return log_oom(); + } + + if (!dbus_connection_send(m->manager->bus, reply, NULL)) + return log_oom(); + + dbus_message_unref(m->create_message); + m->create_message = NULL; + + return 0; +} diff --git a/src/machine/machine.c b/src/machine/machine.c new file mode 100644 index 0000000000..7d64abe5dd --- /dev/null +++ b/src/machine/machine.c @@ -0,0 +1,411 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +#include + +#include "util.h" +#include "mkdir.h" +#include "hashmap.h" +#include "strv.h" +#include "fileio.h" +#include "special.h" +#include "unit-name.h" +#include "dbus-common.h" +#include "machine.h" + +Machine* machine_new(Manager *manager, const char *name) { + Machine *m; + + assert(manager); + assert(name); + + m = new0(Machine, 1); + if (!m) + return NULL; + + m->name = strdup(name); + if (!m->name) + goto fail; + + m->state_file = strappend("/run/systemd/machines/", m->name); + if (!m->state_file) + goto fail; + + if (hashmap_put(manager->machines, m->name, m) < 0) + goto fail; + + m->class = _MACHINE_CLASS_INVALID; + m->manager = manager; + + return m; + +fail: + free(m->state_file); + free(m->name); + free(m); + + return NULL; +} + +void machine_free(Machine *m) { + assert(m); + + if (m->in_gc_queue) + LIST_REMOVE(Machine, gc_queue, m->manager->machine_gc_queue, m); + + if (m->scope) { + hashmap_remove(m->manager->machine_units, m->scope); + free(m->scope); + } + + free(m->scope_job); + + hashmap_remove(m->manager->machines, m->name); + + if (m->create_message) + dbus_message_unref(m->create_message); + + free(m->name); + free(m->state_file); + free(m->service); + free(m->root_directory); + free(m); +} + +int machine_save(Machine *m) { + _cleanup_free_ char *temp_path = NULL; + _cleanup_fclose_ FILE *f = NULL; + int r; + + assert(m); + assert(m->state_file); + + if (!m->started) + return 0; + + r = mkdir_safe_label("/run/systemd/machines", 0755, 0, 0); + if (r < 0) + goto finish; + + r = fopen_temporary(m->state_file, &f, &temp_path); + if (r < 0) + goto finish; + + fchmod(fileno(f), 0644); + + fprintf(f, + "# This is private data. Do not parse.\n" + "NAME=%s\n", + m->name); + + if (m->scope) + fprintf(f, "SCOPE=%s\n", m->scope); + + if (m->scope_job) + fprintf(f, "SCOPE_JOB=%s\n", m->scope_job); + + if (m->service) + fprintf(f, "SERVICE=%s\n", m->service); + + if (m->root_directory) + fprintf(f, "ROOT=%s\n", m->root_directory); + + if (!sd_id128_equal(m->id, SD_ID128_NULL)) + fprintf(f, "ID=" SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(m->id)); + + if (m->leader != 0) + fprintf(f, "LEADER=%lu\n", (unsigned long) m->leader); + + if (m->class != _MACHINE_CLASS_INVALID) + fprintf(f, "CLASS=%s\n", machine_class_to_string(m->class)); + + if (dual_timestamp_is_set(&m->timestamp)) + fprintf(f, + "REALTIME=%llu\n" + "MONOTONIC=%llu\n", + (unsigned long long) m->timestamp.realtime, + (unsigned long long) m->timestamp.monotonic); + + fflush(f); + + if (ferror(f) || rename(temp_path, m->state_file) < 0) { + r = -errno; + unlink(m->state_file); + unlink(temp_path); + } + +finish: + if (r < 0) + log_error("Failed to save machine data for %s: %s", m->name, strerror(-r)); + + return r; +} + +int machine_load(Machine *m) { + _cleanup_free_ char *realtime = NULL, *monotonic = NULL, *id = NULL, *leader = NULL, *class = NULL; + int r; + + assert(m); + + r = parse_env_file(m->state_file, NEWLINE, + "SCOPE", &m->scope, + "SCOPE_JOB", &m->scope_job, + "SERVICE", &m->service, + "ROOT", &m->root_directory, + "ID", &id, + "LEADER", &leader, + "CLASS", &class, + "REALTIME", &realtime, + "MONOTONIC", &monotonic, + NULL); + if (r < 0) { + if (r == -ENOENT) + return 0; + + log_error("Failed to read %s: %s", m->state_file, strerror(-r)); + return r; + } + + if (id) + sd_id128_from_string(id, &m->id); + + if (leader) + parse_pid(leader, &m->leader); + + if (class) { + MachineClass c; + + c = machine_class_from_string(class); + if (c >= 0) + m->class = c; + } + + if (realtime) { + unsigned long long l; + if (sscanf(realtime, "%llu", &l) > 0) + m->timestamp.realtime = l; + } + + if (monotonic) { + unsigned long long l; + if (sscanf(monotonic, "%llu", &l) > 0) + m->timestamp.monotonic = l; + } + + return r; +} + +static int machine_start_scope(Machine *m) { + _cleanup_free_ char *description = NULL; + DBusError error; + char *job; + int r; + + assert(m); + + dbus_error_init(&error); + + if (!m->scope) { + char *escaped = NULL; + + escaped = unit_name_escape(m->name); + if (!escaped) + return log_oom(); + + m->scope = strjoin("machine-", escaped, ".scope", NULL); + free(escaped); + + if (!m->scope) + return log_oom(); + + r = hashmap_put(m->manager->machine_units, m->scope, m); + if (r < 0) + log_warning("Failed to create mapping between unit and machine"); + } + + description = strappend(m->class == MACHINE_VM ? "Virtual Machine " : "Container ", m->name); + + r = manager_start_scope(m->manager, m->scope, m->leader, SPECIAL_MACHINE_SLICE, description, &error, &job); + if (r < 0) { + log_error("Failed to start machine scope: %s", bus_error(&error, r)); + dbus_error_free(&error); + } else { + free(m->scope_job); + m->scope_job = job; + } + + return r; +} + +int machine_start(Machine *m) { + int r; + + assert(m); + + if (m->started) + return 0; + + /* Create cgroup */ + r = machine_start_scope(m); + if (r < 0) + return r; + + log_struct(LOG_INFO, + MESSAGE_ID(SD_MESSAGE_MACHINE_START), + "NAME=%s", m->name, + "LEADER=%lu", (unsigned long) m->leader, + "MESSAGE=New machine %s.", m->name, + NULL); + + if (!dual_timestamp_is_set(&m->timestamp)) + dual_timestamp_get(&m->timestamp); + + m->started = true; + + /* Save new machine data */ + machine_save(m); + + machine_send_signal(m, true); + + return 0; +} + +static int machine_stop_scope(Machine *m) { + DBusError error; + char *job; + int r; + + assert(m); + + dbus_error_init(&error); + + if (!m->scope) + return 0; + + r = manager_stop_unit(m->manager, m->scope, &error, &job); + if (r < 0) { + log_error("Failed to stop machine scope: %s", bus_error(&error, r)); + dbus_error_free(&error); + return r; + } + + free(m->scope_job); + m->scope_job = job; + + return r; +} + +int machine_stop(Machine *m) { + int r = 0, k; + assert(m); + + if (m->started) + log_struct(LOG_INFO, + MESSAGE_ID(SD_MESSAGE_MACHINE_STOP), + "NAME=%s", m->name, + "LEADER=%lu", (unsigned long) m->leader, + "MESSAGE=Machine %s terminated.", m->name, + NULL); + + /* Kill cgroup */ + k = machine_stop_scope(m); + if (k < 0) + r = k; + + unlink(m->state_file); + machine_add_to_gc_queue(m); + + if (m->started) + machine_send_signal(m, false); + + m->started = false; + + return r; +} + +int machine_check_gc(Machine *m, bool drop_not_started) { + assert(m); + + if (drop_not_started && !m->started) + return 0; + + if (m->scope_job) + return 1; + + if (m->scope) + return manager_unit_is_active(m->manager, m->scope) != 0; + + return 0; +} + +void machine_add_to_gc_queue(Machine *m) { + assert(m); + + if (m->in_gc_queue) + return; + + LIST_PREPEND(Machine, gc_queue, m->manager->machine_gc_queue, m); + m->in_gc_queue = true; +} + +MachineState machine_get_state(Machine *s) { + assert(s); + + if (s->scope_job) + return s->started ? MACHINE_OPENING : MACHINE_CLOSING; + + return MACHINE_RUNNING; +} + +int machine_kill(Machine *m, KillWho who, int signo) { + assert(m); + + if (!m->scope) + return -ESRCH; + + return manager_kill_unit(m->manager, m->scope, who, signo, NULL); +} + +static const char* const machine_class_table[_MACHINE_CLASS_MAX] = { + [MACHINE_CONTAINER] = "container", + [MACHINE_VM] = "vm" +}; + +DEFINE_STRING_TABLE_LOOKUP(machine_class, MachineClass); + +static const char* const machine_state_table[_MACHINE_STATE_MAX] = { + [MACHINE_OPENING] = "opening", + [MACHINE_RUNNING] = "running", + [MACHINE_CLOSING] = "closing" +}; + +DEFINE_STRING_TABLE_LOOKUP(machine_state, MachineState); + +static const char* const kill_who_table[_KILL_WHO_MAX] = { + [KILL_LEADER] = "leader", + [KILL_ALL] = "all" +}; + +DEFINE_STRING_TABLE_LOOKUP(kill_who, KillWho); diff --git a/src/machine/machine.h b/src/machine/machine.h new file mode 100644 index 0000000000..7501fa372e --- /dev/null +++ b/src/machine/machine.h @@ -0,0 +1,109 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +typedef struct Machine Machine; +typedef enum KillWho KillWho; + +#include "list.h" +#include "util.h" +#include "machined.h" + +typedef enum MachineState { + MACHINE_OPENING, /* Machine is being registered */ + MACHINE_RUNNING, /* Machine is running */ + MACHINE_CLOSING, /* Machine is terminating */ + _MACHINE_STATE_MAX, + _MACHINE_STATE_INVALID = -1 +} MachineState; + +typedef enum MachineClass { + MACHINE_CONTAINER, + MACHINE_VM, + _MACHINE_CLASS_MAX, + _MACHINE_CLASS_INVALID = -1 +} MachineClass; + +enum KillWho { + KILL_LEADER, + KILL_ALL, + _KILL_WHO_MAX, + _KILL_WHO_INVALID = -1 +}; + +struct Machine { + Manager *manager; + + char *name; + sd_id128_t id; + + MachineState state; + MachineClass class; + + char *state_file; + char *service; + char *root_directory; + + char *scope; + char *scope_job; + + pid_t leader; + + dual_timestamp timestamp; + + bool in_gc_queue:1; + bool started:1; + + DBusMessage *create_message; + + LIST_FIELDS(Machine, gc_queue); +}; + +Machine* machine_new(Manager *manager, const char *name); +void machine_free(Machine *m); +int machine_check_gc(Machine *m, bool drop_not_started); +void machine_add_to_gc_queue(Machine *m); +int machine_start(Machine *m); +int machine_stop(Machine *m); +int machine_save(Machine *m); +int machine_load(Machine *m); +int machine_kill(Machine *m, KillWho who, int signo); + +char *machine_bus_path(Machine *s); + +MachineState machine_get_state(Machine *u); + +extern const DBusObjectPathVTable bus_machine_vtable; + +int machine_send_signal(Machine *m, bool new_machine); +int machine_send_changed(Machine *m, const char *properties); + +int machine_send_create_reply(Machine *m, DBusError *error); + +const char* machine_class_to_string(MachineClass t) _const_; +MachineClass machine_class_from_string(const char *s) _pure_; + +const char* machine_state_to_string(MachineState t) _const_; +MachineState machine_state_from_string(const char *s) _pure_; + +const char *kill_who_to_string(KillWho k) _const_; +KillWho kill_who_from_string(const char *s) _pure_; diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c new file mode 100644 index 0000000000..5d107f360a --- /dev/null +++ b/src/machine/machinectl.c @@ -0,0 +1,764 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "macro.h" +#include "pager.h" +#include "dbus-common.h" +#include "build.h" +#include "strv.h" +#include "cgroup-show.h" +#include "spawn-polkit-agent.h" + +static char **arg_property = NULL; +static bool arg_all = false; +static bool arg_full = false; +static bool arg_no_pager = false; +static const char *arg_kill_who = NULL; +static int arg_signal = SIGTERM; +static enum transport { + TRANSPORT_NORMAL, + TRANSPORT_SSH, + TRANSPORT_POLKIT +} arg_transport = TRANSPORT_NORMAL; +static bool arg_ask_password = true; +static char *arg_host = NULL; +static char *arg_user = NULL; + +static void pager_open_if_enabled(void) { + + /* Cache result before we open the pager */ + if (arg_no_pager) + return; + + pager_open(false); +} + +static int list_machines(DBusConnection *bus, char **args, unsigned n) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + DBusMessageIter iter, sub, sub2; + unsigned k = 0; + int r; + + pager_open_if_enabled(); + + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.machine1", + "/org/freedesktop/machine1", + "org.freedesktop.machine1.Manager", + "ListMachines", + &reply, + NULL, + DBUS_TYPE_INVALID); + if (r) + return r; + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + return -EIO; + } + + dbus_message_iter_recurse(&iter, &sub); + + if (on_tty()) + printf("%-32s %-9s %-16s\n", "MACHINE", "CONTAINER", "SERVICE"); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *name, *class, *service, *object; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + return -EIO; + } + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &class, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &service, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &object, false) < 0) { + log_error("Failed to parse reply."); + return -EIO; + } + + printf("%-32s %-9s %-16s\n", name, class, service); + + k++; + + dbus_message_iter_next(&sub); + } + + if (on_tty()) + printf("\n%u machines listed.\n", k); + + return 0; +} + +typedef struct MachineStatusInfo { + const char *name; + sd_id128_t id; + const char *default_control_group; + const char *class; + const char *service; + const char *slice; + const char *root_directory; + pid_t leader; + usec_t timestamp; +} MachineStatusInfo; + +static void print_machine_status_info(MachineStatusInfo *i) { + char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1; + char since2[FORMAT_TIMESTAMP_MAX], *s2; + assert(i); + + fputs(strna(i->name), stdout); + + if (!sd_id128_equal(i->id, SD_ID128_NULL)) + printf("(" SD_ID128_FORMAT_STR ")\n", SD_ID128_FORMAT_VAL(i->id)); + else + putchar('\n'); + + s1 = format_timestamp_relative(since1, sizeof(since1), i->timestamp); + s2 = format_timestamp(since2, sizeof(since2), i->timestamp); + + if (s1) + printf("\t Since: %s; %s\n", s2, s1); + else if (s2) + printf("\t Since: %s\n", s2); + + if (i->leader > 0) { + _cleanup_free_ char *t = NULL; + + printf("\t Leader: %u", (unsigned) i->leader); + + get_process_comm(i->leader, &t); + if (t) + printf(" (%s)", t); + + putchar('\n'); + } + + if (i->service) { + printf("\t Service: %s", i->service); + + if (i->class) + printf("; class %s", i->class); + + putchar('\n'); + } else if (i->class) + printf("\t Class: %s\n", i->class); + + if (i->slice) + printf("\t Slice: %s\n", i->slice); + if (i->root_directory) + printf("\t Root: %s\n", i->root_directory); + + if (i->default_control_group) { + unsigned c; + int output_flags = + arg_all * OUTPUT_SHOW_ALL | + arg_full * OUTPUT_FULL_WIDTH; + + printf("\t CGroup: %s\n", i->default_control_group); + + if (arg_transport != TRANSPORT_SSH) { + c = columns(); + if (c > 18) + c -= 18; + else + c = 0; + + show_cgroup_and_extra_by_spec(i->default_control_group, + "\t\t ", c, false, &i->leader, + i->leader > 0 ? 1 : 0, + output_flags); + } + } +} + +static int status_property_machine(const char *name, DBusMessageIter *iter, MachineStatusInfo *i) { + assert(name); + assert(iter); + assert(i); + + switch (dbus_message_iter_get_arg_type(iter)) { + + case DBUS_TYPE_STRING: { + const char *s; + + dbus_message_iter_get_basic(iter, &s); + + if (!isempty(s)) { + if (streq(name, "Name")) + i->name = s; + else if (streq(name, "DefaultControlGroup")) + i->default_control_group = s; + else if (streq(name, "Class")) + i->class = s; + else if (streq(name, "Service")) + i->service = s; + else if (streq(name, "Slice")) + i->slice = s; + else if (streq(name, "RootDirectory")) + i->root_directory = s; + } + break; + } + + case DBUS_TYPE_UINT32: { + uint32_t u; + + dbus_message_iter_get_basic(iter, &u); + + if (streq(name, "Leader")) + i->leader = (pid_t) u; + + break; + } + + case DBUS_TYPE_UINT64: { + uint64_t u; + + dbus_message_iter_get_basic(iter, &u); + + if (streq(name, "Timestamp")) + i->timestamp = (usec_t) u; + + break; + } + + case DBUS_TYPE_ARRAY: { + DBusMessageIter sub; + + dbus_message_iter_recurse(iter, &sub); + + if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_BYTE && streq(name, "Id")) { + void *v; + int n; + + dbus_message_iter_get_fixed_array(&sub, &v, &n); + if (n == 0) + i->id = SD_ID128_NULL; + else if (n == 16) + memcpy(&i->id, v, n); + } + + break; + } + } + + return 0; +} + +static int print_property(const char *name, DBusMessageIter *iter) { + assert(name); + assert(iter); + + if (arg_property && !strv_find(arg_property, name)) + return 0; + + if (generic_print_property(name, iter, arg_all) > 0) + return 0; + + if (arg_all) + printf("%s=[unprintable]\n", name); + + return 0; +} + +static int show_one(const char *verb, DBusConnection *bus, const char *path, bool show_properties, bool *new_line) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + const char *interface = ""; + int r; + DBusMessageIter iter, sub, sub2, sub3; + MachineStatusInfo machine_info = {}; + + assert(path); + assert(new_line); + + r = bus_method_call_with_reply( + bus, + "org.freedesktop.machine1", + path, + "org.freedesktop.DBus.Properties", + "GetAll", + &reply, + NULL, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_INVALID); + if (r < 0) + goto finish; + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_DICT_ENTRY) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + if (*new_line) + printf("\n"); + + *new_line = true; + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *name; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_DICT_ENTRY) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_VARIANT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub2, &sub3); + + if (show_properties) + r = print_property(name, &sub3); + else + r = status_property_machine(name, &sub3, &machine_info); + + if (r < 0) { + log_error("Failed to parse reply."); + goto finish; + } + + dbus_message_iter_next(&sub); + } + + if (!show_properties) + print_machine_status_info(&machine_info); + + r = 0; + +finish: + + return r; +} + +static int show(DBusConnection *bus, char **args, unsigned n) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + int r, ret = 0; + DBusError error; + unsigned i; + bool show_properties, new_line = false; + + assert(bus); + assert(args); + + dbus_error_init(&error); + + show_properties = !strstr(args[0], "status"); + + pager_open_if_enabled(); + + if (show_properties && n <= 1) { + /* If not argument is specified inspect the manager + * itself */ + + ret = show_one(args[0], bus, "/org/freedesktop/machine1", show_properties, &new_line); + goto finish; + } + + for (i = 1; i < n; i++) { + const char *path = NULL; + + ret = bus_method_call_with_reply( + bus, + "org.freedesktop.machine1", + "/org/freedesktop/machine1", + "org.freedesktop.machine1.Manager", + "GetMachine", + &reply, + NULL, + DBUS_TYPE_STRING, &args[i], + DBUS_TYPE_INVALID); + if (ret < 0) + goto finish; + + if (!dbus_message_get_args(reply, &error, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse reply: %s", bus_error_message(&error)); + ret = -EIO; + goto finish; + } + + r = show_one(args[0], bus, path, show_properties, &new_line); + if (r != 0) + ret = r; + } + +finish: + dbus_error_free(&error); + + return ret; +} + +static int kill_machine(DBusConnection *bus, char **args, unsigned n) { + unsigned i; + + assert(args); + + if (!arg_kill_who) + arg_kill_who = "all"; + + for (i = 1; i < n; i++) { + int r; + + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.machine1", + "/org/freedesktop/machine1", + "org.freedesktop.machine1.Manager", + "KillMachine", + NULL, + NULL, + DBUS_TYPE_STRING, &args[i], + DBUS_TYPE_STRING, &arg_kill_who, + DBUS_TYPE_INT32, &arg_signal, + DBUS_TYPE_INVALID); + if (r) + return r; + } + + return 0; +} + +static int terminate_machine(DBusConnection *bus, char **args, unsigned n) { + unsigned i; + + assert(args); + + for (i = 1; i < n; i++) { + int r; + + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.machine1", + "/org/freedesktop/machine1", + "org.freedesktop.machine1.Manager", + "TerminateMachine", + NULL, + NULL, + DBUS_TYPE_STRING, &args[i], + DBUS_TYPE_INVALID); + if (r) + return r; + } + + return 0; +} + +static int help(void) { + + printf("%s [OPTIONS...] {COMMAND} ...\n\n" + "Send control commands to or query the virtual machine and container registration manager.\n\n" + " -h --help Show this help\n" + " --version Show package version\n" + " -p --property=NAME Show only properties by this name\n" + " -a --all Show all properties, including empty ones\n" + " --kill-who=WHO Who to send signal to\n" + " -l --full Do not ellipsize output\n" + " -s --signal=SIGNAL Which signal to send\n" + " --no-ask-password Don't prompt for password\n" + " -H --host=[USER@]HOST Show information for remote host\n" + " -P --privileged Acquire privileges before execution\n" + " --no-pager Do not pipe output into a pager\n\n" + "Commands:\n" + " list List running VMs and containers\n" + " status [NAME...] Show VM/container status\n" + " show[NAME...] Show properties of one or more VMs/containers\n" + " terminate [NAME...] Terminate one or more VMs/containers\n" + " kill [NAME...] Send signal to processes of a VM/container\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_VERSION = 0x100, + ARG_NO_PAGER, + ARG_KILL_WHO, + ARG_NO_ASK_PASSWORD, + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "property", required_argument, NULL, 'p' }, + { "all", no_argument, NULL, 'a' }, + { "full", no_argument, NULL, 'l' }, + { "no-pager", no_argument, NULL, ARG_NO_PAGER }, + { "kill-who", required_argument, NULL, ARG_KILL_WHO }, + { "signal", required_argument, NULL, 's' }, + { "host", required_argument, NULL, 'H' }, + { "privileged", no_argument, NULL, 'P' }, + { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "hp:als:H:P", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_VERSION: + puts(PACKAGE_STRING); + puts(SYSTEMD_FEATURES); + return 0; + + case 'p': { + char **l; + + l = strv_append(arg_property, optarg); + if (!l) + return -ENOMEM; + + strv_free(arg_property); + arg_property = l; + + /* If the user asked for a particular + * property, show it to him, even if it is + * empty. */ + arg_all = true; + break; + } + + case 'a': + arg_all = true; + break; + + case 'l': + arg_full = true; + break; + + case ARG_NO_PAGER: + arg_no_pager = true; + break; + + case ARG_NO_ASK_PASSWORD: + arg_ask_password = false; + break; + + case ARG_KILL_WHO: + arg_kill_who = optarg; + break; + + case 's': + arg_signal = signal_from_string_try_harder(optarg); + if (arg_signal < 0) { + log_error("Failed to parse signal string %s.", optarg); + return -EINVAL; + } + break; + + case 'P': + arg_transport = TRANSPORT_POLKIT; + break; + + case 'H': + arg_transport = TRANSPORT_SSH; + parse_user_at_host(optarg, &arg_user, &arg_host); + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + return 1; +} + +static int machinectl_main(DBusConnection *bus, int argc, char *argv[], DBusError *error) { + + static const struct { + const char* verb; + const enum { + MORE, + LESS, + EQUAL + } argc_cmp; + const int argc; + int (* const dispatch)(DBusConnection *bus, char **args, unsigned n); + } verbs[] = { + { "list", LESS, 1, list_machines }, + { "status", MORE, 2, show }, + { "show", MORE, 1, show }, + { "terminate", MORE, 2, terminate_machine }, + { "kill", MORE, 2, kill_machine }, + }; + + int left; + unsigned i; + + assert(argc >= 0); + assert(argv); + assert(error); + + left = argc - optind; + + if (left <= 0) + /* Special rule: no arguments means "list-sessions" */ + i = 0; + else { + if (streq(argv[optind], "help")) { + help(); + return 0; + } + + for (i = 0; i < ELEMENTSOF(verbs); i++) + if (streq(argv[optind], verbs[i].verb)) + break; + + if (i >= ELEMENTSOF(verbs)) { + log_error("Unknown operation %s", argv[optind]); + return -EINVAL; + } + } + + switch (verbs[i].argc_cmp) { + + case EQUAL: + if (left != verbs[i].argc) { + log_error("Invalid number of arguments."); + return -EINVAL; + } + + break; + + case MORE: + if (left < verbs[i].argc) { + log_error("Too few arguments."); + return -EINVAL; + } + + break; + + case LESS: + if (left > verbs[i].argc) { + log_error("Too many arguments."); + return -EINVAL; + } + + break; + + default: + assert_not_reached("Unknown comparison operator."); + } + + if (!bus) { + log_error("Failed to get D-Bus connection: %s", error->message); + return -EIO; + } + + return verbs[i].dispatch(bus, argv + optind, left); +} + +int main(int argc, char*argv[]) { + int r, retval = EXIT_FAILURE; + DBusConnection *bus = NULL; + DBusError error; + + dbus_error_init(&error); + + setlocale(LC_ALL, ""); + log_parse_environment(); + log_open(); + + r = parse_argv(argc, argv); + if (r < 0) + goto finish; + else if (r == 0) { + retval = EXIT_SUCCESS; + goto finish; + } + + if (arg_transport == TRANSPORT_NORMAL) + bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); + else if (arg_transport == TRANSPORT_POLKIT) + bus_connect_system_polkit(&bus, &error); + else if (arg_transport == TRANSPORT_SSH) + bus_connect_system_ssh(NULL, arg_host, &bus, &error); + else + assert_not_reached("Uh, invalid transport..."); + + r = machinectl_main(bus, argc, argv, &error); + retval = r < 0 ? EXIT_FAILURE : r; + +finish: + if (bus) { + dbus_connection_flush(bus); + dbus_connection_close(bus); + dbus_connection_unref(bus); + } + + dbus_error_free(&error); + dbus_shutdown(); + + strv_free(arg_property); + + pager_close(); + + return retval; +} diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c new file mode 100644 index 0000000000..a2e00d7102 --- /dev/null +++ b/src/machine/machined-dbus.c @@ -0,0 +1,824 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include + +#include +#include + +#include "machined.h" +#include "dbus-common.h" +#include "strv.h" +#include "mkdir.h" +#include "path-util.h" +#include "special.h" +#include "sleep-config.h" +#include "fileio-label.h" +#include "label.h" +#include "utf8.h" +#include "unit-name.h" +#include "bus-errors.h" +#include "virt.h" + +#define BUS_MANAGER_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION_BEGIN \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_MANAGER_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE + +#define INTROSPECTION_END \ + "\n" + +#define INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.machine1.Manager\0" + +static bool valid_machine_name(const char *p) { + size_t l; + + if (!filename_is_safe(p)) + return false; + + if (!ascii_is_valid(p)) + return false; + + l = strlen(p); + + if (l < 1 || l> 64) + return false; + + return true; +} + +static int bus_manager_create_machine(Manager *manager, DBusMessage *message) { + + const char *name, *service, *class, *slice, *root_directory; + _cleanup_free_ char *p = NULL; + DBusMessageIter iter, sub; + MachineClass c; + uint32_t leader; + sd_id128_t id; + Machine *m; + int n, r; + void *v; + + assert(manager); + assert(message); + + if (!dbus_message_iter_init(message, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &name); + + if (!valid_machine_name(name) || + !dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_BYTE) + return -EINVAL; + + dbus_message_iter_recurse(&iter, &sub); + dbus_message_iter_get_fixed_array(&sub, &v, &n); + + if (n == 0) + id = SD_ID128_NULL; + else if (n == 16) + memcpy(&id, v, n); + else + return -EINVAL; + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &service); + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &class); + + if (isempty(class)) + c = _MACHINE_CLASS_INVALID; + else { + c = machine_class_from_string(class); + if (c < 0) + return -EINVAL; + } + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &leader); + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &slice); + if (!(isempty(slice) || (unit_name_is_valid(slice, false) && endswith(slice, ".slice"))) || + !dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &root_directory); + + if (!(isempty(root_directory) || path_is_absolute(root_directory))) + return -EINVAL; + + if (hashmap_get(manager->machines, name)) + return -EEXIST; + + if (leader <= 0) { + leader = bus_get_unix_process_id(manager->bus, dbus_message_get_sender(message), NULL); + if (leader == 0) + return -EINVAL; + } + + r = manager_add_machine(manager, name, &m); + if (r < 0) + goto fail; + + m->leader = leader; + m->class = c; + m->id = id; + + if (!isempty(service)) { + m->service = strdup(service); + if (!m->service) { + r = -ENOMEM; + goto fail; + } + } + + if (!isempty(root_directory)) { + m->root_directory = strdup(root_directory); + if (!m->root_directory) { + r = -ENOMEM; + goto fail; + } + } + + r = machine_start(m); + if (r < 0) + goto fail; + + m->create_message = dbus_message_ref(message); + + return 0; + +fail: + if (m) + machine_add_to_gc_queue(m); + + return r; +} + +static DBusHandlerResult manager_message_handler( + DBusConnection *connection, + DBusMessage *message, + void *userdata) { + + Manager *m = userdata; + + DBusError error; + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + int r; + + assert(connection); + assert(message); + assert(m); + + dbus_error_init(&error); + + if (dbus_message_is_method_call(message, "org.freedesktop.machine1.Manager", "GetMachine")) { + Machine *machine; + const char *name; + char *p; + bool b; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + machine = hashmap_get(m->machines, name); + if (!machine) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + p = machine_bus_path(machine); + if (!p) + goto oom; + + b = dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID); + free(p); + + if (!b) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.machine1.Manager", "GetMachineByPID")) { + uint32_t pid; + char *p; + Machine *machine; + bool b; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_UINT32, &pid, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + r = manager_get_machine_by_pid(m, pid, &machine); + if (r <= 0) + return bus_send_error_reply(connection, message, NULL, r < 0 ? r : -ENOENT); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + p = machine_bus_path(machine); + if (!p) + goto oom; + + b = dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID); + free(p); + + if (!b) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.machine1.Manager", "ListMachines")) { + Machine *machine; + Iterator i; + DBusMessageIter iter, sub; + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + dbus_message_iter_init_append(reply, &iter); + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(ssso)", &sub)) + goto oom; + + HASHMAP_FOREACH(machine, m->machines, i) { + _cleanup_free_ char *p = NULL; + DBusMessageIter sub2; + const char *class; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2)) + goto oom; + + p = machine_bus_path(machine); + if (!p) + goto oom; + + class = strempty(machine_class_to_string(machine->class)); + + if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &machine->name) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &class) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &machine->service) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &p)) { + free(p); + goto oom; + } + + if (!dbus_message_iter_close_container(&sub, &sub2)) + goto oom; + } + + if (!dbus_message_iter_close_container(&iter, &sub)) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.machine1.Manager", "CreateMachine")) { + + r = bus_manager_create_machine(m, message); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + } else if (dbus_message_is_method_call(message, "org.freedesktop.machine1.Manager", "KillMachine")) { + const char *swho; + int32_t signo; + KillWho who; + const char *name; + Machine *machine; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &swho, + DBUS_TYPE_INT32, &signo, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (isempty(swho)) + who = KILL_ALL; + else { + who = kill_who_from_string(swho); + if (who < 0) + return bus_send_error_reply(connection, message, &error, -EINVAL); + } + + if (signo <= 0 || signo >= _NSIG) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + machine = hashmap_get(m->machines, name); + if (!machine) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + r = machine_kill(machine, who, signo); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.machine1.Manager", "TerminateMachine")) { + const char *name; + Machine *machine; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + machine = hashmap_get(m->machines, name); + if (!machine) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + r = machine_stop(machine); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect")) { + char *introspection = NULL; + FILE *f; + Iterator i; + Machine *machine; + size_t size; + char *p; + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + /* We roll our own introspection code here, instead of + * relying on bus_default_message_handler() because we + * need to generate our introspection string + * dynamically. */ + + f = open_memstream(&introspection, &size); + if (!f) + goto oom; + + fputs(INTROSPECTION_BEGIN, f); + + HASHMAP_FOREACH(machine, m->machines, i) { + p = bus_path_escape(machine->name); + + if (p) { + fprintf(f, "", p); + free(p); + } + } + + fputs(INTROSPECTION_END, f); + + if (ferror(f)) { + fclose(f); + free(introspection); + goto oom; + } + + fclose(f); + + if (!introspection) + goto oom; + + if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection, DBUS_TYPE_INVALID)) { + free(introspection); + goto oom; + } + + free(introspection); + } else + return bus_default_message_handler(connection, message, NULL, INTERFACES_LIST, NULL); + + if (reply) { + if (!bus_maybe_send_reply(connection, message, reply)) + goto oom; + } + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +const DBusObjectPathVTable bus_manager_vtable = { + .message_function = manager_message_handler +}; + +DBusHandlerResult bus_message_filter( + DBusConnection *connection, + DBusMessage *message, + void *userdata) { + + Manager *m = userdata; + DBusError error; + + assert(m); + assert(connection); + assert(message); + + dbus_error_init(&error); + + log_debug("Got message: %s %s %s", strna(dbus_message_get_sender(message)), strna(dbus_message_get_interface(message)), strna(dbus_message_get_member(message))); + + if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Manager", "JobRemoved")) { + const char *path, *result, *unit; + Machine *mm; + uint32_t id; + + if (!dbus_message_get_args(message, &error, + DBUS_TYPE_UINT32, &id, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_STRING, &unit, + DBUS_TYPE_STRING, &result, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse JobRemoved message: %s", bus_error_message(&error)); + goto finish; + } + + + mm = hashmap_get(m->machine_units, unit); + if (mm) { + if (streq_ptr(path, mm->scope_job)) { + free(mm->scope_job); + mm->scope_job = NULL; + + if (mm->started) { + if (streq(result, "done")) + machine_send_create_reply(mm, NULL); + else { + dbus_set_error(&error, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result); + machine_send_create_reply(mm, &error); + } + } + } + + machine_add_to_gc_queue(mm); + } + + } else if (dbus_message_is_signal(message, "org.freedesktop.DBus.Properties", "PropertiesChanged")) { + + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + _cleanup_free_ char *unit = NULL; + const char *path; + + path = dbus_message_get_path(message); + if (!path) + goto finish; + + unit_name_from_dbus_path(path, &unit); + if (unit) { + Machine *mm; + + mm = hashmap_get(m->machine_units, unit); + if (mm) + machine_add_to_gc_queue(mm); + } + } + +finish: + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +int manager_start_scope( + Manager *manager, + const char *scope, + pid_t pid, + const char *slice, + const char *description, + DBusError *error, + char **job) { + + _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL; + DBusMessageIter iter, sub, sub2, sub3, sub4; + const char *timeout_stop_property = "TimeoutStopUSec"; + const char *pids_property = "PIDs"; + uint64_t timeout = 500 * USEC_PER_MSEC; + const char *fail = "fail"; + uint32_t u; + + assert(manager); + assert(scope); + assert(pid > 1); + + if (!slice) + slice = ""; + + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "StartTransientUnit"); + if (!m) + return log_oom(); + + dbus_message_iter_init_append(m, &iter); + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &scope) || + !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &fail) || + !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(sv)", &sub)) + return log_oom(); + + if (!isempty(slice)) { + const char *slice_property = "Slice"; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &slice_property) || + !dbus_message_iter_open_container(&sub2, DBUS_TYPE_VARIANT, "s", &sub3) || + !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, &slice) || + !dbus_message_iter_close_container(&sub2, &sub3) || + !dbus_message_iter_close_container(&sub, &sub2)) + return log_oom(); + } + + if (!isempty(description)) { + const char *description_property = "Description"; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &description_property) || + !dbus_message_iter_open_container(&sub2, DBUS_TYPE_VARIANT, "s", &sub3) || + !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, &description) || + !dbus_message_iter_close_container(&sub2, &sub3) || + !dbus_message_iter_close_container(&sub, &sub2)) + return log_oom(); + } + + /* cgroup empty notification is not available in containers + * currently. To make this less problematic, let's shorten the + * stop timeout for sessions, so that we don't wait + * forever. */ + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &timeout_stop_property) || + !dbus_message_iter_open_container(&sub2, DBUS_TYPE_VARIANT, "t", &sub3) || + !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_UINT64, &timeout) || + !dbus_message_iter_close_container(&sub2, &sub3) || + !dbus_message_iter_close_container(&sub, &sub2)) + return log_oom(); + + u = pid; + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &pids_property) || + !dbus_message_iter_open_container(&sub2, DBUS_TYPE_VARIANT, "au", &sub3) || + !dbus_message_iter_open_container(&sub3, DBUS_TYPE_ARRAY, "u", &sub4) || + !dbus_message_iter_append_basic(&sub4, DBUS_TYPE_UINT32, &u) || + !dbus_message_iter_close_container(&sub3, &sub4) || + !dbus_message_iter_close_container(&sub2, &sub3) || + !dbus_message_iter_close_container(&sub, &sub2) || + !dbus_message_iter_close_container(&iter, &sub)) + return log_oom(); + + reply = dbus_connection_send_with_reply_and_block(manager->bus, m, -1, error); + if (!reply) + return -EIO; + + if (job) { + const char *j; + char *copy; + + if (!dbus_message_get_args(reply, error, DBUS_TYPE_OBJECT_PATH, &j, DBUS_TYPE_INVALID)) + return -EIO; + + copy = strdup(j); + if (!copy) + return -ENOMEM; + + *job = copy; + } + + return 0; +} + +int manager_stop_unit(Manager *manager, const char *unit, DBusError *error, char **job) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + const char *fail = "fail"; + int r; + + assert(manager); + assert(unit); + + r = bus_method_call_with_reply( + manager->bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "StopUnit", + &reply, + error, + DBUS_TYPE_STRING, &unit, + DBUS_TYPE_STRING, &fail, + DBUS_TYPE_INVALID); + if (r < 0) { + log_error("Failed to stop unit %s: %s", unit, bus_error(error, r)); + return r; + } + + if (job) { + const char *j; + char *copy; + + if (!dbus_message_get_args(reply, error, + DBUS_TYPE_OBJECT_PATH, &j, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse reply."); + return -EIO; + } + + copy = strdup(j); + if (!copy) + return -ENOMEM; + + *job = copy; + } + + return 0; +} + +int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, DBusError *error) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + const char *w; + int r; + + assert(manager); + assert(unit); + + w = who == KILL_LEADER ? "process" : "cgroup"; + assert_cc(sizeof(signo) == sizeof(int32_t)); + + r = bus_method_call_with_reply( + manager->bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "KillUnit", + &reply, + error, + DBUS_TYPE_STRING, &unit, + DBUS_TYPE_STRING, &w, + DBUS_TYPE_INT32, &signo, + DBUS_TYPE_INVALID); + if (r < 0) { + log_error("Failed to stop unit %s: %s", unit, bus_error(error, r)); + return r; + } + + return 0; +} + +int manager_unit_is_active(Manager *manager, const char *unit) { + + const char *interface = "org.freedesktop.systemd1.Unit"; + const char *property = "ActiveState"; + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + _cleanup_free_ char *path = NULL; + DBusMessageIter iter, sub; + const char *state; + DBusError error; + int r; + + assert(manager); + assert(unit); + + dbus_error_init(&error); + + path = unit_dbus_path_from_name(unit); + if (!path) + return -ENOMEM; + + r = bus_method_call_with_reply( + manager->bus, + "org.freedesktop.systemd1", + path, + "org.freedesktop.DBus.Properties", + "Get", + &reply, + &error, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_STRING, &property, + DBUS_TYPE_INVALID); + + if (r < 0) { + log_error("Failed to query ActiveState: %s", bus_error(&error, r)); + dbus_error_free(&error); + return r; + } + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) { + log_error("Failed to parse reply."); + return -EINVAL; + } + + dbus_message_iter_recurse(&iter, &sub); + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) { + log_error("Failed to parse reply."); + return -EINVAL; + } + + dbus_message_iter_get_basic(&sub, &state); + + return !streq(state, "inactive") && !streq(state, "failed"); +} diff --git a/src/machine/machined.c b/src/machine/machined.c new file mode 100644 index 0000000000..3cf7f92f96 --- /dev/null +++ b/src/machine/machined.c @@ -0,0 +1,408 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include + +#include + +#include "machined.h" +#include "dbus-common.h" +#include "dbus-loop.h" +#include "strv.h" +#include "conf-parser.h" +#include "mkdir.h" +#include "cgroup-util.h" + +Manager *manager_new(void) { + Manager *m; + + m = new0(Manager, 1); + if (!m) + return NULL; + + m->bus_fd = -1; + m->epoll_fd = -1; + + m->machines = hashmap_new(string_hash_func, string_compare_func); + m->machine_units = hashmap_new(string_hash_func, string_compare_func); + + if (!m->machines || !m->machine_units) { + manager_free(m); + return NULL; + } + + return m; +} + +void manager_free(Manager *m) { + Machine *machine; + + assert(m); + + while ((machine = hashmap_first(m->machines))) + machine_free(machine); + + hashmap_free(m->machines); + hashmap_free(m->machine_units); + + if (m->bus) { + dbus_connection_flush(m->bus); + dbus_connection_close(m->bus); + dbus_connection_unref(m->bus); + } + + if (m->bus_fd >= 0) + close_nointr_nofail(m->bus_fd); + + if (m->epoll_fd >= 0) + close_nointr_nofail(m->epoll_fd); + + free(m); +} + +int manager_add_machine(Manager *m, const char *name, Machine **_machine) { + Machine *machine; + + assert(m); + assert(name); + + machine = hashmap_get(m->machines, name); + if (machine) { + if (_machine) + *_machine = machine; + + return 0; + } + + machine = machine_new(m, name); + if (!m) + return -ENOMEM; + + if (_machine) + *_machine = machine; + + return 0; +} + +int manager_enumerate_machines(Manager *m) { + _cleanup_closedir_ DIR *d = NULL; + struct dirent *de; + int r = 0; + + assert(m); + + /* Read in machine data stored on disk */ + d = opendir("/run/systemd/machines"); + if (!d) { + if (errno == ENOENT) + return 0; + + log_error("Failed to open /run/systemd/machines: %m"); + return -errno; + } + + FOREACH_DIRENT(de, d, return -errno) { + struct Machine *machine; + int k; + + if (!dirent_is_file(de)) + continue; + + k = manager_add_machine(m, de->d_name, &machine); + if (k < 0) { + log_error("Failed to add machine by file name %s: %s", de->d_name, strerror(-k)); + + r = k; + continue; + } + + machine_add_to_gc_queue(machine); + + k = machine_load(machine); + if (k < 0) + r = k; + } + + return r; +} + +int manager_get_machine_by_pid(Manager *m, pid_t pid, Machine **machine) { + _cleanup_free_ char *unit = NULL; + Machine *mm; + int r; + + assert(m); + assert(pid >= 1); + assert(machine); + + r = cg_pid_get_unit(pid, &unit); + if (r < 0) + return r; + + mm = hashmap_get(m->machine_units, unit); + if (!mm) + return 0; + + *machine = mm; + return 1; +} + +static int manager_connect_bus(Manager *m) { + DBusError error; + int r; + struct epoll_event ev = { + .events = EPOLLIN, + .data.u32 = FD_BUS, + }; + + assert(m); + assert(!m->bus); + assert(m->bus_fd < 0); + + dbus_error_init(&error); + + m->bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); + if (!m->bus) { + log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error)); + r = -ECONNREFUSED; + goto fail; + } + + if (!dbus_connection_register_object_path(m->bus, "/org/freedesktop/machine1", &bus_manager_vtable, m) || + !dbus_connection_register_fallback(m->bus, "/org/freedesktop/machine1/machine", &bus_machine_vtable, m) || + !dbus_connection_add_filter(m->bus, bus_message_filter, m, NULL)) { + r = log_oom(); + goto fail; + } + + dbus_bus_add_match(m->bus, + "type='signal'," + "sender='org.freedesktop.systemd1'," + "interface='org.freedesktop.systemd1.Manager'," + "member='JobRemoved'," + "path='/org/freedesktop/systemd1'", + &error); + if (dbus_error_is_set(&error)) { + log_error("Failed to add match for JobRemoved: %s", bus_error_message(&error)); + dbus_error_free(&error); + } + + dbus_bus_add_match(m->bus, + "type='signal'," + "sender='org.freedesktop.systemd1'," + "interface='org.freedesktop.DBus.Properties'," + "member='PropertiesChanged'", + &error); + if (dbus_error_is_set(&error)) { + log_error("Failed to add match for PropertiesChanged: %s", bus_error_message(&error)); + dbus_error_free(&error); + } + + r = bus_method_call_with_reply( + m->bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "Subscribe", + NULL, + &error, + DBUS_TYPE_INVALID); + if (r < 0) { + log_error("Failed to enable subscription: %s", bus_error(&error, r)); + dbus_error_free(&error); + } + + r = dbus_bus_request_name(m->bus, "org.freedesktop.machine1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error); + if (dbus_error_is_set(&error)) { + log_error("Failed to register name on bus: %s", bus_error_message(&error)); + r = -EIO; + goto fail; + } + + if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { + log_error("Failed to acquire name."); + r = -EEXIST; + goto fail; + } + + m->bus_fd = bus_loop_open(m->bus); + if (m->bus_fd < 0) { + r = m->bus_fd; + goto fail; + } + + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->bus_fd, &ev) < 0) + goto fail; + + return 0; + +fail: + dbus_error_free(&error); + + return r; +} + +void manager_gc(Manager *m, bool drop_not_started) { + Machine *machine; + + assert(m); + + while ((machine = m->machine_gc_queue)) { + LIST_REMOVE(Machine, gc_queue, m->machine_gc_queue, machine); + machine->in_gc_queue = false; + + if (machine_check_gc(machine, drop_not_started) == 0) { + machine_stop(machine); + machine_free(machine); + } + } +} + +int manager_startup(Manager *m) { + int r; + Machine *machine; + Iterator i; + + assert(m); + assert(m->epoll_fd <= 0); + + m->epoll_fd = epoll_create1(EPOLL_CLOEXEC); + if (m->epoll_fd < 0) + return -errno; + + /* Connect to the bus */ + r = manager_connect_bus(m); + if (r < 0) + return r; + + /* Deserialize state */ + manager_enumerate_machines(m); + + /* Remove stale objects before we start them */ + manager_gc(m, false); + + /* And start everything */ + HASHMAP_FOREACH(machine, m->machines, i) + machine_start(machine); + + return 0; +} + +int manager_run(Manager *m) { + assert(m); + + for (;;) { + struct epoll_event event; + int n; + + manager_gc(m, true); + + if (dbus_connection_dispatch(m->bus) != DBUS_DISPATCH_COMPLETE) + continue; + + manager_gc(m, true); + + n = epoll_wait(m->epoll_fd, &event, 1, -1); + if (n < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + + log_error("epoll() failed: %m"); + return -errno; + } + + if (n == 0) + continue; + + switch (event.data.u32) { + + case FD_BUS: + bus_loop_dispatch(m->bus_fd); + break; + + default: + assert_not_reached("Unknown fd"); + } + } + + return 0; +} + +int main(int argc, char *argv[]) { + Manager *m = NULL; + int r; + + log_set_target(LOG_TARGET_AUTO); + log_set_facility(LOG_AUTH); + log_parse_environment(); + log_open(); + + umask(0022); + + if (argc != 1) { + log_error("This program takes no arguments."); + r = -EINVAL; + goto finish; + } + + /* Always create the directories people can create inotify + * watches in. Note that some applications might check for the + * existence of /run/systemd/seats/ to determine whether + * machined is available, so please always make sure this check + * stays in. */ + mkdir_label("/run/systemd/machines", 0755); + + m = manager_new(); + if (!m) { + r = log_oom(); + goto finish; + } + + r = manager_startup(m); + if (r < 0) { + log_error("Failed to fully start up daemon: %s", strerror(-r)); + goto finish; + } + + log_debug("systemd-machined running as pid %lu", (unsigned long) getpid()); + + sd_notify(false, + "READY=1\n" + "STATUS=Processing requests..."); + + r = manager_run(m); + + log_debug("systemd-machined stopped as pid %lu", (unsigned long) getpid()); + +finish: + sd_notify(false, + "STATUS=Shutting down..."); + + if (m) + manager_free(m); + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/machine/machined.h b/src/machine/machined.h new file mode 100644 index 0000000000..32a15fe1ab --- /dev/null +++ b/src/machine/machined.h @@ -0,0 +1,73 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +#include "util.h" +#include "list.h" +#include "hashmap.h" + +typedef struct Manager Manager; + +#include "machine.h" + +struct Manager { + DBusConnection *bus; + + int bus_fd; + int epoll_fd; + + Hashmap *machines; + Hashmap *machine_units; + + LIST_HEAD(Machine, machine_gc_queue); +}; + +enum { + FD_BUS +}; + +Manager *manager_new(void); +void manager_free(Manager *m); + +int manager_add_machine(Manager *m, const char *name, Machine **_machine); + +int manager_enumerate_machines(Manager *m); + +int manager_startup(Manager *m); +int manager_run(Manager *m); + +void manager_gc(Manager *m, bool drop_not_started); + +int manager_get_machine_by_pid(Manager *m, pid_t pid, Machine **machine); + +extern const DBusObjectPathVTable bus_manager_vtable; + +DBusHandlerResult bus_message_filter(DBusConnection *c, DBusMessage *message, void *userdata); + +int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, DBusError *error, char **job); +int manager_stop_unit(Manager *manager, const char *unit, DBusError *error, char **job); +int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, DBusError *error); +int manager_unit_is_active(Manager *manager, const char *unit); diff --git a/src/machine/org.freedesktop.machine1.conf b/src/machine/org.freedesktop.machine1.conf new file mode 100644 index 0000000000..2aad42019f --- /dev/null +++ b/src/machine/org.freedesktop.machine1.conf @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/machine/org.freedesktop.machine1.service b/src/machine/org.freedesktop.machine1.service new file mode 100644 index 0000000000..d3dc99852b --- /dev/null +++ b/src/machine/org.freedesktop.machine1.service @@ -0,0 +1,12 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[D-BUS Service] +Name=org.freedesktop.machine1 +Exec=/bin/false +User=root +SystemdService=dbus-org.freedesktop.machine1.service diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 66c2228ca2..913e73673a 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -1162,9 +1162,9 @@ static int register_machine(void) { r = sd_bus_call_method( bus, - "org.freedesktop.login1", - "/org/freedesktop/login1", - "org.freedesktop.login1.Manager", + "org.freedesktop.machine1", + "/org/freedesktop/machine1", + "org.freedesktop.machine1.Manager", "CreateMachine", &error, NULL, diff --git a/tmpfiles.d/systemd.conf b/tmpfiles.d/systemd.conf index ee86f2ebce..4924b4ec70 100644 --- a/tmpfiles.d/systemd.conf +++ b/tmpfiles.d/systemd.conf @@ -19,6 +19,7 @@ d /run/systemd/ask-password 0755 root root - d /run/systemd/seats 0755 root root - d /run/systemd/sessions 0755 root root - d /run/systemd/users 0755 root root - +d /run/systemd/machines 0755 root root - d /run/systemd/shutdown 0755 root root - F /run/nologin 0644 - - - "System is booting up." diff --git a/units/.gitignore b/units/.gitignore index 878cf2ce4c..0bcbb00951 100644 --- a/units/.gitignore +++ b/units/.gitignore @@ -57,3 +57,4 @@ /initrd-switch-root.service /initrd-udevadm-cleanup-db.service /systemd-nspawn@.service +/systemd-machined.service diff --git a/units/systemd-logind.service.in b/units/systemd-logind.service.in index ec05e670f3..c4611e8492 100644 --- a/units/systemd-logind.service.in +++ b/units/systemd-logind.service.in @@ -9,8 +9,8 @@ Description=Login Service Documentation=man:systemd-logind.service(8) man:logind.conf(5) Documentation=http://www.freedesktop.org/wiki/Software/systemd/multiseat -Wants=user.slice machine.slice -After=nss-user-lookup.target user.slice machine.slice +Wants=user.slice +After=nss-user-lookup.target user.slice [Service] ExecStart=@rootlibexecdir@/systemd-logind diff --git a/units/systemd-machined.service.in b/units/systemd-machined.service.in new file mode 100644 index 0000000000..334c622a17 --- /dev/null +++ b/units/systemd-machined.service.in @@ -0,0 +1,19 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Virtual Machine and Container Registration Service +Documentation=man:systemd-machined.service(8) +Documentation=http://www.freedesktop.org/wiki/Software/systemd/machines +Wants=machine.slice +After=machine.slice + +[Service] +ExecStart=@rootlibexecdir@/systemd-machined +Restart=always +RestartSec=0 +BusName=org.freedesktop.machine1 -- cgit v1.2.1 From 51da82a781537b275db3fbce8fab8592dd991758 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 2 Jul 2013 03:58:28 +0200 Subject: machined: fix bus path unescaping --- TODO | 5 ----- src/machine/machine-dbus.c | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/TODO b/TODO index 96ed2c06d8..00f22d592e 100644 --- a/TODO +++ b/TODO @@ -64,11 +64,6 @@ Features: * handle jointly mounted controllers correctly -* split out CreateMachine into systemd-machined - -* make logind's session and machine - registration use Slices to set up cgroups - * journald: make sure ratelimit is actually really per-service with the new cgroup changes * move systemctl dump to systemd-analyze diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c index 424f98edd5..243b8604cd 100644 --- a/src/machine/machine-dbus.c +++ b/src/machine/machine-dbus.c @@ -109,7 +109,7 @@ static int get_machine_for_path(Manager *m, const char *path, Machine **_machine if (!startswith(path, "/org/freedesktop/machine1/machine/")) return -EINVAL; - e = bus_path_unescape(path + 32); + e = bus_path_unescape(path + 34); if (!e) return -ENOMEM; -- cgit v1.2.1 From 6a4e0b13473baed129522310c39f3bb70f46ed42 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 2 Jul 2013 15:02:54 +0200 Subject: nspawn: use the corect method signature for CreateMachine() --- src/machine/machined-dbus.c | 8 +------- src/nspawn/nspawn.c | 8 ++++---- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c index a2e00d7102..83a45b63ba 100644 --- a/src/machine/machined-dbus.c +++ b/src/machine/machined-dbus.c @@ -42,7 +42,7 @@ #include "virt.h" #define BUS_MANAGER_INTERFACE \ - " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ @@ -180,12 +180,6 @@ static int bus_manager_create_machine(Manager *manager, DBusMessage *message) { dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) return -EINVAL; - dbus_message_iter_get_basic(&iter, &slice); - if (!(isempty(slice) || (unit_name_is_valid(slice, false) && endswith(slice, ".slice"))) || - !dbus_message_iter_next(&iter) || - dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) - return -EINVAL; - dbus_message_iter_get_basic(&iter, &root_directory); if (!(isempty(root_directory) || path_is_absolute(root_directory))) diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 913e73673a..cfd88efc9e 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -1168,16 +1168,16 @@ static int register_machine(void) { "CreateMachine", &error, NULL, - "sayssuss", + "sayssusa(sv)", arg_machine, SD_BUS_APPEND_ID128(arg_uuid), "nspawn", "container", (uint32_t) 0, - strempty(arg_slice), - strempty(arg_directory)); + strempty(arg_directory), + 1, "Slice", "s", strempty(arg_slice)); if (r < 0) { - log_error("Failed to register machine: %s", error.message); + log_error("Failed to register machine: %s", error.message ? error.message : strerror(-r)); return r; } -- cgit v1.2.1 From 97e67f1e52ddc0c21a88cfbcab57e83c59ee627d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 2 Jul 2013 15:03:09 +0200 Subject: machined: relax access to GetMachine() --- src/machine/org.freedesktop.machine1.conf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/machine/org.freedesktop.machine1.conf b/src/machine/org.freedesktop.machine1.conf index 2aad42019f..b2d6df3121 100644 --- a/src/machine/org.freedesktop.machine1.conf +++ b/src/machine/org.freedesktop.machine1.conf @@ -40,6 +40,10 @@ send_interface="org.freedesktop.machine1.Manager" send_member="ListMachines"/> + + -- cgit v1.2.1 From 8aec412ff697bc14995746953912ca6fdf2c9ba8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 2 Jul 2013 15:49:27 +0200 Subject: machined: sync to /run after job completed --- src/core/dbus-unit.c | 32 ++++++++++++++++++++------------ src/core/unit.c | 9 +++++++-- src/login/logind-dbus.c | 2 ++ src/machine/machined-dbus.c | 3 ++- 4 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index ad6d5a6038..5831046305 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -778,16 +778,18 @@ static int bus_unit_set_transient_property( assert(i); if (streq(name, "Description")) { - const char *description; - if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_STRING) return -EINVAL; - dbus_message_iter_get_basic(i, &description); + if (mode != UNIT_CHECK) { + const char *description; - r = unit_set_description(u, description); - if (r < 0) - return r; + dbus_message_iter_get_basic(i, &description); + + r = unit_set_description(u, description); + if (r < 0) + return r; + } return 1; @@ -800,14 +802,20 @@ static int bus_unit_set_transient_property( dbus_message_iter_get_basic(i, &s); - r = manager_load_unit(u->manager, s, NULL, error, &slice); - if (r < 0) - return r; + if (isempty(s)) { + if (mode != UNIT_CHECK) + unit_ref_unset(&u->slice); + } else { + r = manager_load_unit(u->manager, s, NULL, error, &slice); + if (r < 0) + return r; - if (slice->type != UNIT_SLICE) - return -EINVAL; + if (slice->type != UNIT_SLICE) + return -EINVAL; - unit_ref_set(&u->slice, slice); + if (mode != UNIT_CHECK) + unit_ref_set(&u->slice, slice); + } return 1; } diff --git a/src/core/unit.c b/src/core/unit.c index 991111ab31..acc575b6e0 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -231,8 +231,13 @@ int unit_set_description(Unit *u, const char *description) { assert(u); - if (!(s = strdup(description))) - return -ENOMEM; + if (isempty(description)) + s = NULL; + else { + s = strdup(description); + if (!s) + return -ENOMEM; + } free(u->description); u->description = s; diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 9a19932af4..e61ec7afd5 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -2356,6 +2356,7 @@ DBusHandlerResult bus_message_filter( if (streq_ptr(path, s->scope_job)) { free(s->scope_job); s->scope_job = NULL; + session_save(s); if (s->started) { if (streq(result, "done")) @@ -2382,6 +2383,7 @@ DBusHandlerResult bus_message_filter( u->slice_job = NULL; } + user_save(u); user_add_to_gc_queue(u); } } diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c index 83a45b63ba..a81f37c5ca 100644 --- a/src/machine/machined-dbus.c +++ b/src/machine/machined-dbus.c @@ -116,7 +116,7 @@ static bool valid_machine_name(const char *p) { static int bus_manager_create_machine(Manager *manager, DBusMessage *message) { - const char *name, *service, *class, *slice, *root_directory; + const char *name, *service, *class, *root_directory; _cleanup_free_ char *p = NULL; DBusMessageIter iter, sub; MachineClass c; @@ -537,6 +537,7 @@ DBusHandlerResult bus_message_filter( if (streq_ptr(path, mm->scope_job)) { free(mm->scope_job); mm->scope_job = NULL; + machine_save(mm); if (mm->started) { if (streq(result, "done")) -- cgit v1.2.1 From 06025d9148036ee4de9866f3f067ffa75e14a751 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 2 Jul 2013 16:24:13 +0200 Subject: core: don't consider a unit's cgroup empty if only a subcgroup runs empty --- src/core/cgroup.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/core/cgroup.c b/src/core/cgroup.c index cdccf3ff15..c7f1e77c6c 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -728,16 +728,15 @@ int manager_notify_cgroup_empty(Manager *m, const char *cgroup) { assert(m); assert(cgroup); - r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, cgroup, true); - if (r == 0) - return 0; - u = manager_get_unit_by_cgroup(m, cgroup); if (u) { - if (UNIT_VTABLE(u)->notify_cgroup_empty) - UNIT_VTABLE(u)->notify_cgroup_empty(u); + r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, true); + if (r > 0) { + if (UNIT_VTABLE(u)->notify_cgroup_empty) + UNIT_VTABLE(u)->notify_cgroup_empty(u); - unit_add_to_gc_queue(u); + unit_add_to_gc_queue(u); + } } return 0; -- cgit v1.2.1 From 294a90cc4af5139e936975a38baaa62771af96ba Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Tue, 2 Jul 2013 10:44:02 -0400 Subject: dbus-scope: initialize variable before accessing --- src/core/dbus-scope.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/dbus-scope.c b/src/core/dbus-scope.c index 0205cfff6e..771820c2d8 100644 --- a/src/core/dbus-scope.c +++ b/src/core/dbus-scope.c @@ -93,7 +93,7 @@ static int bus_scope_set_transient_property( if (streq(name, "PIDs")) { DBusMessageIter sub; - unsigned n; + unsigned n = 0; if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_ARRAY || dbus_message_iter_get_element_type(i) != DBUS_TYPE_UINT32) -- cgit v1.2.1 From 8b6fe8243d6a46d7435fb6789481489c44549cfb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 2 Jul 2013 17:17:25 +0200 Subject: login: pass correct boolean type to libdbus --- src/login/logind-dbus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index e61ec7afd5..a52f020b34 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -489,7 +489,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message) { _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; _cleanup_free_ char *path = NULL; _cleanup_close_ int fifo_fd = -1; - bool exists; + dbus_bool_t exists; /* Session already exists, client is probably * something like "su" which changes uid but is still -- cgit v1.2.1 From d0af76e68a5bab2e4fd9674b1c64a9f38d7afe97 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 2 Jul 2013 17:17:35 +0200 Subject: logind: after deserializatio readd systemd units to unit-to-object hashmap correctly --- src/login/logind-session.c | 36 +++++++++++++++------------- src/login/logind-user.c | 60 +++++++++++++++++++++++++--------------------- src/machine/machine.c | 36 +++++++++++++++------------- 3 files changed, 72 insertions(+), 60 deletions(-) diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 6e1bf6d560..2892c38417 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -455,9 +455,7 @@ done: } static int session_start_scope(Session *s) { - _cleanup_free_ char *description = NULL; DBusError error; - char *job; int r; assert(s); @@ -467,26 +465,32 @@ static int session_start_scope(Session *s) { dbus_error_init(&error); if (!s->scope) { - s->scope = strjoin("session-", s->id, ".scope", NULL); - if (!s->scope) + _cleanup_free_ char *description = NULL; + char *scope, *job; + + scope = strjoin("session-", s->id, ".scope", NULL); + if (!scope) return log_oom(); - r = hashmap_put(s->manager->session_units, s->scope, s); - if (r < 0) - log_warning("Failed to create mapping between unit and session"); - } + description = strjoin("Session ", s->id, " of user ", s->user->name, NULL); - description = strjoin("Session ", s->id, " of user ", s->user->name, NULL); + r = manager_start_scope(s->manager, scope, s->leader, s->user->slice, description, &error, &job); + if (r < 0) { + log_error("Failed to start session scope: %s %s", bus_error(&error, r), error.name); + dbus_error_free(&error); - r = manager_start_scope(s->manager, s->scope, s->leader, s->user->slice, description, &error, &job); - if (r < 0) { - log_error("Failed to start session scope: %s %s", bus_error(&error, r), error.name); - dbus_error_free(&error); - } else { - free(s->scope_job); - s->scope_job = job; + free(scope); + } else { + s->scope = scope; + + free(s->scope_job); + s->scope_job = job; + } } + if (s->scope) + hashmap_put(s->manager->session_units, s->scope, s); + return 0; } diff --git a/src/login/logind-user.c b/src/login/logind-user.c index fb961bf64b..0a985a53ec 100644 --- a/src/login/logind-user.c +++ b/src/login/logind-user.c @@ -338,27 +338,30 @@ static int user_start_slice(User *u) { dbus_error_init(&error); if (!u->slice) { - char lu[DECIMAL_STR_MAX(unsigned long) + 1]; + char lu[DECIMAL_STR_MAX(unsigned long) + 1], *slice; sprintf(lu, "%lu", (unsigned long) u->uid); - r = build_subslice(SPECIAL_USER_SLICE, lu, &u->slice); + r = build_subslice(SPECIAL_USER_SLICE, lu, &slice); if (r < 0) return r; - r = hashmap_put(u->manager->user_units, u->slice, u); - if (r < 0) - log_warning("Failed to create mapping between unit and user"); - } + r = manager_start_unit(u->manager, slice, &error, &job); + if (r < 0) { + log_error("Failed to start user slice: %s", bus_error(&error, r)); + dbus_error_free(&error); - r = manager_start_unit(u->manager, u->slice, &error, &job); - if (r < 0) { - log_error("Failed to start user slice: %s", bus_error(&error, r)); - dbus_error_free(&error); - } else { - free(u->slice_job); - u->slice_job = job; + free(slice); + } else { + u->slice = slice; + + free(u->slice_job); + u->slice_job = job; + } } + if (u->slice) + hashmap_put(u->manager->user_units, u->slice, u); + return 0; } @@ -372,27 +375,30 @@ static int user_start_service(User *u) { dbus_error_init(&error); if (!u->service) { - char lu[DECIMAL_STR_MAX(unsigned long) + 1]; + char lu[DECIMAL_STR_MAX(unsigned long) + 1], *service; sprintf(lu, "%lu", (unsigned long) u->uid); - u->service = unit_name_build("user", lu, ".service"); - if (!u->service) + service = unit_name_build("user", lu, ".service"); + if (!service) return log_oom(); - r = hashmap_put(u->manager->user_units, u->service, u); - if (r < 0) - log_warning("Failed to create mapping between service and user"); - } + r = manager_start_unit(u->manager, service, &error, &job); + if (r < 0) { + log_error("Failed to start user service: %s", bus_error(&error, r)); + dbus_error_free(&error); - r = manager_start_unit(u->manager, u->service, &error, &job); - if (r < 0) { - log_error("Failed to start user service: %s", bus_error(&error, r)); - dbus_error_free(&error); - } else { - free(u->service_job); - u->service_job = job; + free(service); + } else { + u->service = service; + + free(u->service_job); + u->service_job = job; + } } + if (u->service) + hashmap_put(u->manager->user_units, u->service, u); + return 0; } diff --git a/src/machine/machine.c b/src/machine/machine.c index 7d64abe5dd..8e03ff2ec1 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -228,34 +228,36 @@ static int machine_start_scope(Machine *m) { dbus_error_init(&error); if (!m->scope) { - char *escaped = NULL; + _cleanup_free_ char *escaped = NULL; + char *scope; escaped = unit_name_escape(m->name); if (!escaped) return log_oom(); - m->scope = strjoin("machine-", escaped, ".scope", NULL); - free(escaped); - - if (!m->scope) + scope = strjoin("machine-", escaped, ".scope", NULL); + if (scope) return log_oom(); - r = hashmap_put(m->manager->machine_units, m->scope, m); - if (r < 0) - log_warning("Failed to create mapping between unit and machine"); - } + description = strappend(m->class == MACHINE_VM ? "Virtual Machine " : "Container ", m->name); - description = strappend(m->class == MACHINE_VM ? "Virtual Machine " : "Container ", m->name); + r = manager_start_scope(m->manager, m->scope, m->leader, SPECIAL_MACHINE_SLICE, description, &error, &job); + if (r < 0) { + log_error("Failed to start machine scope: %s", bus_error(&error, r)); + dbus_error_free(&error); - r = manager_start_scope(m->manager, m->scope, m->leader, SPECIAL_MACHINE_SLICE, description, &error, &job); - if (r < 0) { - log_error("Failed to start machine scope: %s", bus_error(&error, r)); - dbus_error_free(&error); - } else { - free(m->scope_job); - m->scope_job = job; + free(scope); + } else { + m->scope = scope; + + free(m->scope_job); + m->scope_job = job; + } } + if (m->scope) + hashmap_put(m->manager->machine_units, m->scope, m); + return r; } -- cgit v1.2.1 From cf1265e188e876dda906dca0029248a06dc80c33 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 2 Jul 2013 17:41:57 +0200 Subject: core: make GC more aggressive Since we should allow registering/unregistering transient units with the same name in a tight-loop, we need to make the GC more aggressive, so that dead units are cleaned up immediately instead of later. hence, execute the GC sweep on every event loop iteration and clean up units. This of course, means we need to be careful with adding units to the GC queue, which we already are since we execute check_gc() of each unit type already when adding something to the queue. --- src/core/manager.c | 21 ++++++--------------- src/core/manager.h | 1 - src/core/unit.c | 3 --- 3 files changed, 6 insertions(+), 19 deletions(-) diff --git a/src/core/manager.c b/src/core/manager.c index 080561b5d1..6128194427 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -72,9 +72,6 @@ #include "efivars.h" #include "env-util.h" -/* As soon as 16 units are in our GC queue, make sure to run a gc sweep */ -#define GC_QUEUE_ENTRIES_MAX 16 - /* As soon as 5s passed since a unit was added to our GC queue, make sure to run a gc sweep */ #define GC_QUEUE_USEC_MAX (10*USEC_PER_SEC) @@ -604,12 +601,7 @@ static unsigned manager_dispatch_gc_queue(Manager *m) { assert(m); - if ((m->n_in_gc_queue < GC_QUEUE_ENTRIES_MAX) && - (m->gc_queue_timestamp <= 0 || - (m->gc_queue_timestamp + GC_QUEUE_USEC_MAX) > now(CLOCK_MONOTONIC))) - return 0; - - log_debug("Running GC..."); + /* log_debug("Running GC..."); */ m->gc_marker += _GC_OFFSET_MAX; if (m->gc_marker + _GC_OFFSET_MAX <= _GC_OFFSET_MAX) @@ -636,7 +628,6 @@ static unsigned manager_dispatch_gc_queue(Manager *m) { } m->n_in_gc_queue = 0; - m->gc_queue_timestamp = 0; return n; } @@ -1733,19 +1724,19 @@ int manager_loop(Manager *m) { if (manager_dispatch_load_queue(m) > 0) continue; - if (manager_dispatch_run_queue(m) > 0) + if (manager_dispatch_gc_queue(m) > 0) continue; - if (bus_dispatch(m) > 0) + if (manager_dispatch_cleanup_queue(m) > 0) continue; - if (manager_dispatch_cleanup_queue(m) > 0) + if (manager_dispatch_cgroup_queue(m) > 0) continue; - if (manager_dispatch_gc_queue(m) > 0) + if (manager_dispatch_run_queue(m) > 0) continue; - if (manager_dispatch_cgroup_queue(m) > 0) + if (bus_dispatch(m) > 0) continue; if (manager_dispatch_dbus_queue(m) > 0) diff --git a/src/core/manager.h b/src/core/manager.h index 68cb2e4a3d..57a0a8d251 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -206,7 +206,6 @@ struct Manager { CGroupControllerMask cgroup_supported; char *cgroup_root; - usec_t gc_queue_timestamp; int gc_marker; unsigned n_in_gc_queue; diff --git a/src/core/unit.c b/src/core/unit.c index acc575b6e0..447f2015ab 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -311,9 +311,6 @@ void unit_add_to_gc_queue(Unit *u) { u->in_gc_queue = true; u->manager->n_in_gc_queue ++; - - if (u->manager->gc_queue_timestamp <= 0) - u->manager->gc_queue_timestamp = now(CLOCK_MONOTONIC); } void unit_add_to_dbus_queue(Unit *u) { -- cgit v1.2.1 From f526ab7ef046d0e6d8923d4960903bcc807883fb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 2 Jul 2013 18:38:26 +0200 Subject: machine: fix scope allocation --- src/machine/machine.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/machine/machine.c b/src/machine/machine.c index 8e03ff2ec1..f33ad54db8 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -236,12 +236,12 @@ static int machine_start_scope(Machine *m) { return log_oom(); scope = strjoin("machine-", escaped, ".scope", NULL); - if (scope) + if (!scope) return log_oom(); description = strappend(m->class == MACHINE_VM ? "Virtual Machine " : "Container ", m->name); - r = manager_start_scope(m->manager, m->scope, m->leader, SPECIAL_MACHINE_SLICE, description, &error, &job); + r = manager_start_scope(m->manager, scope, m->leader, SPECIAL_MACHINE_SLICE, description, &error, &job); if (r < 0) { log_error("Failed to start machine scope: %s", bus_error(&error, r)); dbus_error_free(&error); -- cgit v1.2.1 From aba8b84e8d72224445b67646974b9dabc0972187 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Tue, 2 Jul 2013 13:44:50 -0400 Subject: machined: check correct return value for NULL --- src/machine/machined.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machined.c b/src/machine/machined.c index 3cf7f92f96..86f8de9195 100644 --- a/src/machine/machined.c +++ b/src/machine/machined.c @@ -98,7 +98,7 @@ int manager_add_machine(Manager *m, const char *name, Machine **_machine) { } machine = machine_new(m, name); - if (!m) + if (!machine) return -ENOMEM; if (_machine) -- cgit v1.2.1 From 2c4c73b3ffa123cc5c69f5749c58706aafb3f257 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Tue, 2 Jul 2013 13:50:00 -0400 Subject: machine: fix -Wmaybe-uninitialized warning The return value of machine_start_scope might be undefined if m->scope is non-NULL. --- src/machine/machine.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine.c b/src/machine/machine.c index f33ad54db8..d75c338189 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -221,7 +221,7 @@ static int machine_start_scope(Machine *m) { _cleanup_free_ char *description = NULL; DBusError error; char *job; - int r; + int r = 0; assert(m); -- cgit v1.2.1 From 6824690f140f45064157d220a24b9afbeb1d093f Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 3 Jul 2013 00:23:41 +0200 Subject: hwdb: allow to query arbitrary keys --- src/udev/udev-builtin-hwdb.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/udev/udev-builtin-hwdb.c b/src/udev/udev-builtin-hwdb.c index 9895f651c5..36958916c4 100644 --- a/src/udev/udev-builtin-hwdb.c +++ b/src/udev/udev-builtin-hwdb.c @@ -144,6 +144,13 @@ static int builtin_hwdb(struct udev_device *dev, int argc, char *argv[], bool te } } + /* query a specific key given as argument */ + if (argv[optind]) { + if (udev_builtin_hwdb_lookup(dev, argv[optind], filter, test) > 0) + return EXIT_SUCCESS; + return EXIT_FAILURE; + } + /* read data from another device than the device we will store the data */ if (device) { srcdev = udev_device_new_from_device_id(udev_device_get_udev(dev), device); -- cgit v1.2.1 From e9dd9f9547350c7dc0473583b5c2228dc8f0ab76 Mon Sep 17 00:00:00 2001 From: "Jason St. John" Date: Thu, 27 Jun 2013 21:51:44 +0200 Subject: man: improve grammar and word formatting in numerous man pages Use proper grammar, word usage, adjective hyphenation, commas, capitalization, spelling, etc. To improve readability, some run-on sentences or sentence fragments were revised. [zj: remove the space from 'file name', 'host name', and 'time zone'.] --- catalog/systemd.catalog | 2 +- man/binfmt.d.xml | 4 +- man/hostname.xml | 14 +++---- man/hostnamectl.xml | 48 +++++++++++----------- man/kernel-install.xml | 2 +- man/localtime.xml | 12 +++--- man/loginctl.xml | 30 +++++++------- man/logind.conf.xml | 26 ++++++------ man/machine-id.xml | 20 +++++----- man/machine-info.xml | 4 +- man/modules-load.d.xml | 2 +- man/nss-myhostname.xml | 14 +++---- man/os-release.xml | 4 +- man/pam_systemd.xml | 34 ++++++++-------- man/sd-id128.xml | 28 ++++++------- man/sd_id128_get_machine.xml | 10 ++--- man/sd_id128_randomize.xml | 13 +++--- man/sd_id128_to_string.xml | 20 +++++----- man/sd_is_fifo.xml | 20 +++++----- man/sd_journal_get_cutoff_realtime_usec.xml | 6 +-- man/sd_journal_get_realtime_usec.xml | 20 +++++----- man/sd_journal_print.xml | 2 +- man/sd_journal_stream_fd.xml | 2 +- man/sysctl.d.xml | 4 +- man/systemctl.xml | 4 +- man/systemd-analyze.xml | 22 +++++----- man/systemd-hostnamed.service.xml | 8 ++-- man/systemd-inhibit.xml | 16 ++++---- man/systemd-journald.service.xml | 16 ++++---- man/systemd-modules-load.service.xml | 4 +- man/systemd-nspawn.xml | 6 +-- man/systemd-readahead-replay.service.xml | 26 ++++++------ man/systemd-system.conf.xml | 15 ++++--- man/systemd-timedated.service.xml | 4 +- man/systemd-tmpfiles.xml | 2 +- man/systemd.automount.xml | 2 +- man/systemd.exec.xml | 31 +++++++-------- man/systemd.journal-fields.xml | 40 +++++++++---------- man/systemd.mount.xml | 10 ++--- man/systemd.preset.xml | 14 +++---- man/systemd.service.xml | 2 +- man/systemd.socket.xml | 16 ++++---- man/systemd.time.xml | 62 ++++++++++++++--------------- man/systemd.timer.xml | 2 +- man/systemd.unit.xml | 26 ++++++------ man/systemd.xml | 2 +- man/timedatectl.xml | 6 +-- man/tmpfiles.d.xml | 2 +- man/udev.xml | 2 +- src/core/main.c | 4 +- src/shared/hwclock.c | 2 +- src/timedate/timedatectl.c | 2 +- src/timedate/timedated.c | 4 +- 53 files changed, 345 insertions(+), 348 deletions(-) diff --git a/catalog/systemd.catalog b/catalog/systemd.catalog index dbeadb7dea..892b2adf78 100644 --- a/catalog/systemd.catalog +++ b/catalog/systemd.catalog @@ -138,7 +138,7 @@ Subject: Time zone change to @TIMEZONE@ Defined-By: systemd Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel -The system time zone has been changed to @TIMEZONE@. +The system timezone has been changed to @TIMEZONE@. -- b07a249cd024414a82dd00cd181378ff Subject: System start-up is now complete diff --git a/man/binfmt.d.xml b/man/binfmt.d.xml index 762d1fc66e..7f31b76de9 100644 --- a/man/binfmt.d.xml +++ b/man/binfmt.d.xml @@ -94,11 +94,11 @@ with an alphabetically later name. If the administrator wants to disable a - configuration file supplied by the vendor the + configuration file supplied by the vendor, the recommended way is to place a symlink to /dev/null in /etc/binfmt.d/ bearing the - same file name. + same filename. diff --git a/man/hostname.xml b/man/hostname.xml index f89332e983..5971ad4345 100644 --- a/man/hostname.xml +++ b/man/hostname.xml @@ -44,7 +44,7 @@ hostname - Local host name configuration file + Local hostname configuration file @@ -59,17 +59,17 @@ during boot, with the sethostname2 system call. It should contain a single - newline-terminated host name string. The - host name may be a free-form string up to 64 characters - in length, however it is recommended that it consists - only of 7bit ASCII lower-case characters and no spaces or dots, + newline-terminated hostname string. The + hostname may be a free-form string up to 64 characters + in length; however, it is recommended that it consists + only of 7-bit ASCII lower-case characters and no spaces or dots, and limits itself to the format allowed for DNS domain name labels, even though this is not a strict requirement. - Depending on the operating system other + Depending on the operating system, other configuration files might be checked for configuration - of the host name as well, however only as fallback. + of the hostname as well, however only as fallback. You may use hostnamectl1 diff --git a/man/hostnamectl.xml b/man/hostnamectl.xml index 801ab3a7bf..d7a9e92879 100644 --- a/man/hostnamectl.xml +++ b/man/hostnamectl.xml @@ -60,9 +60,9 @@ query and change the system hostname and related settings. - This tool distinguishes three different host - names: the high-level "pretty" hostname which might - include all kinds of special characters + This tool distinguishes three different + hostnames: the high-level "pretty" hostname which + might include all kinds of special characters (e.g. "Lennart's Laptop"), the static hostname which is used to initialize the kernel hostname at boot (e.g. "lennarts-laptop"), and the transient hostname @@ -77,10 +77,10 @@ and transient hostnames are limited to the usually accepted characters of internet domain names. - The static host name is stored in + The static hostname is stored in /etc/hostname, see hostname5 - for more information. The pretty host name, chassis + for more information. The pretty hostname, chassis type and icon name are stored in /etc/machine-info, see machine-id5. @@ -143,8 +143,8 @@ If set-hostname is invoked and one or more of these - options are passed only the selected - hostnames is + options are passed, only the selected + hostname(s) is/are updated. @@ -164,34 +164,34 @@ set-hostname [NAME] Set the system - hostname. By default this will alter + hostname. By default, this will alter the pretty, the static, and the - transient hostname alike, however if + transient hostname alike; however, if one or more of , , - are used + are used, only the selected hostnames are changed. If the pretty hostname is being set, and static or transient are - being set as well the specified host - name will be simplified in regards to - the character set used before the + being set as well, the specified + hostname will be simplified in regards + to the character set used before the latter are updated. This is done by - replacing spaces by "-" and removing + replacing spaces with "-" and removing special characters. This ensures that - the pretty and the static hostname - are always closely related while still + the pretty and the static hostname are + always closely related while still following the validity rules of the specific name. This simplification of the hostname string is not done if - only the transient and/or static host - names are set, and the pretty host - name is left untouched. Pass the empty - string "" as hostname to reset the - selected hostnames to their default - (usually - "localhost"). + only the transient and/or static + hostnames are set, and the pretty + hostname is left untouched. Pass the + empty string "" as the hostname to + reset the selected hostnames to their + default (usually "localhost"). + @@ -206,7 +206,7 @@ Naming Specification. Pass an empty string to this operation to reset the icon name to the default - value which is determined from chassis + value, which is determined from chassis type (see below) and possibly other parameters. diff --git a/man/kernel-install.xml b/man/kernel-install.xml index 8c2abc747c..d21d7579bf 100644 --- a/man/kernel-install.xml +++ b/man/kernel-install.xml @@ -67,7 +67,7 @@ along with systemd; If not, see . located in the directory /usr/lib/kernel/install.d/ and the local administration directory /etc/kernel/install.d/. All files are collectively sorted and executed in lexical order, regardless of the directory in - which they live. However, files with identical file names replace each other. + which they live. However, files with identical filenames replace each other. Files in /etc/kernel/install.d/ take precedence over files with the same name in /usr/lib/kernel/install.d/. This can be used to override a system-supplied executables with a local file if needed; a symbolic link in /etc/kernel/install.d/ diff --git a/man/localtime.xml b/man/localtime.xml index d3da4ed277..b95c2ee6be 100644 --- a/man/localtime.xml +++ b/man/localtime.xml @@ -51,7 +51,7 @@ localtime - Local time zone configuration file + Local timezone configuration file @@ -62,24 +62,24 @@ Description The /etc/localtime file - configures the system-wide time zone of the local + configures the system-wide timezone of the local system that is used by applications for presentation to the user. It should be an absolute or relative symbolic link pointing to /usr/share/zoneinfo/, followed by - a time zone identifier such as + a timezone identifier such as Europe/Berlin or Etc/UTC. The resulting link should lead to the corresponding binary tzfile5 - time zone data for the configured time zone. + timezone data for the configured timezone. - As the time zone identifier is extracted from + As the timezone identifier is extracted from the symlink target name of /etc/localtime this file may not be a normal file or hardlink. - The time zone may be overridden for individual + The timezone may be overridden for individual programs by using the TZ environment variable. See environ7. diff --git a/man/loginctl.xml b/man/loginctl.xml index e76ee95902..f10ca030c9 100644 --- a/man/loginctl.xml +++ b/man/loginctl.xml @@ -144,7 +144,7 @@ to select whether to kill only the leader process of the session or all processes of the - session. If omitted defaults to + session. If omitted, defaults to . @@ -157,8 +157,8 @@ kill-user, choose which signal to send to selected processes. Must be one of the well - known signal specifiers such as - SIGTERM, SIGINT or SIGSTOP. If omitted + known signal specifiers, such as + SIGTERM, SIGINT or SIGSTOP. If omitted, defaults to . @@ -308,10 +308,10 @@ Show properties of one or more users or the manager - itself. If no argument is specified + itself. If no argument is specified, properties of the manager will be - shown. If a user is specified - properties of the user is shown. By + shown. If a user is specified, + properties of the user are shown. By default, empty properties are suppressed. Use to show those too. To select specific @@ -332,9 +332,9 @@ Enable/disable user lingering for one or more users. If - enabled for a specific user a user + enabled for a specific user, a user manager is spawned for him/her at - boot, and kept around after + boot and kept around after logouts. This allows users who aren't logged in to run long-running services. @@ -386,14 +386,14 @@ Show properties of one or more seats or the manager - itself. If no argument is specified + itself. If no argument is specified, properties of the manager will be - shown. If a seat is specified + shown. If a seat is specified, properties of the seat are shown. By default, empty properties are suppressed. Use to show those too. To select specific - properties to show use + properties to show, use . This command is intended to be used whenever computer-parsable output is @@ -411,13 +411,13 @@ one or more devices to a seat. The devices should be specified via device paths in the /sys - file system. To create a new seat + file system. To create a new seat, attach at least one graphics card to a previously unused seat name. Seat names may consist only of a-z, A-Z, 0-9, "-" and "_" and must be prefixed with "seat". To drop assignment of a - device to a specific seat just + device to a specific seat, just reassign it to a different seat, or use flush-devices. @@ -429,8 +429,8 @@ Removes all device assignments previously created with attach. After this - call only automatically generated - seats will remain and all seat + call, only automatically generated + seats will remain, and all seat hardware is assigned to them. diff --git a/man/logind.conf.xml b/man/logind.conf.xml index 47ee0e73ff..b7109353ca 100644 --- a/man/logind.conf.xml +++ b/man/logind.conf.xml @@ -184,10 +184,10 @@ KillExcludeUsers= These settings take - space separated lists of user names + space-separated lists of usernames that influence the effect of KillUserProcesses=. If - not empty only processes of users + not empty, only processes of users listed in KillOnlyUsers will be killed when they log out @@ -210,12 +210,12 @@ users logging in are added to, in addition to the name=systemd named - hierarchy. These settings take space - separated lists of controller + hierarchy. These settings take + space-separated lists of controller names. Pass the empty string to ensure that logind does not touch any hierarchies but systemd's own. When - logging in user sessions will get + logging in, user sessions will get private control groups in all hierarchies listed in Controllers= and be @@ -228,8 +228,8 @@ cpu. Note that for all controllers that are not listed in either Controllers= - nor - ResetControllers= + or + ResetControllers=, newly created sessions will be part of the control groups of the system service that created the @@ -269,11 +269,11 @@ hibernate, hybrid-sleep and lock. If - ignore logind will + ignore, logind will never handle these keys. If - lock all running - sessions will be screen - locked. Otherwise the specified action + lock, all running + sessions will be screen-locked; otherwise, + the specified action will be taken in the respective event. Only input devices with the power-switch udev @@ -301,10 +301,10 @@ sleep keys and the lid switch are subject to inhibitor locks. These settings take boolean arguments. If - off the inhibitor + off, the inhibitor locks taken by applications in order to block the requested operation are - respected, if on + respected, if on, the requested operation is executed in any case. PowerKeyIgnoreInhibited=, diff --git a/man/machine-id.xml b/man/machine-id.xml index 1e558a6178..d7a56cb548 100644 --- a/man/machine-id.xml +++ b/man/machine-id.xml @@ -55,12 +55,12 @@ Description The /etc/machine-id file - contains the unique machine id of the local system + contains the unique machine ID of the local system that is set during installation. The machine ID is a - single newline-terminated, hexadecimal, lowercase 32 - character machine ID string. (When decoded from - hexadecimal this corresponds with a 16 byte/128 bit - string.) + single newline-terminated, hexadecimal, 32-character, + lowercase machine ID string. When decoded from + hexadecimal, this corresponds with a 16-byte/128-bit + string. The machine ID is usually generated from a random source during system installation and stays @@ -69,7 +69,7 @@ boot if it is found to be empty. The machine ID does not change based on user - configuration, or when hardware is replaced. + configuration or when hardware is replaced. This machine ID adheres to the same format and logic as the D-Bus machine ID. @@ -77,10 +77,10 @@ Programs may use this ID to identify the host with a globally unique ID in the network, which does not change even if the local network configuration - changes. Due to this and its greater length it is + changes. Due to this and its greater length, it is a more useful replacement for the gethostid3 - call POSIX specifies. + call that POSIX specifies. The systemd-machine-id-setup1 @@ -94,8 +94,8 @@ Note that the machine ID historically is not an OSF UUID as defined by RFC - 4122, nor a Microsoft GUID. Starting with - systemd v30 newly generated machine IDs however do + 4122, nor a Microsoft GUID; however, starting with + systemd v30, newly generated machine IDs do qualify as v4 UUIDs. In order to maintain compatibility with existing diff --git a/man/machine-info.xml b/man/machine-info.xml index 1c3a21c643..7f396aafde 100644 --- a/man/machine-info.xml +++ b/man/machine-info.xml @@ -101,12 +101,12 @@ present to the user and does not suffer by the syntax limitations of internet domain names. If possible the - internet host name as configured in + internet hostname as configured in /etc/hostname should be kept similar to this one. Example: if this value is Lennart's Computer - an Internet host name of + an Internet hostname of lennarts-computer might be a good choice. If this parameter is not set an application diff --git a/man/modules-load.d.xml b/man/modules-load.d.xml index ce94bef7a7..0d104c563d 100644 --- a/man/modules-load.d.xml +++ b/man/modules-load.d.xml @@ -94,7 +94,7 @@ recommended way is to place a symlink to /dev/null in /etc/modules-load.d/ bearing the - same file name. + same filename. diff --git a/man/nss-myhostname.xml b/man/nss-myhostname.xml index c0e2b828be..efbadac33f 100644 --- a/man/nss-myhostname.xml +++ b/man/nss-myhostname.xml @@ -45,7 +45,7 @@ nss-myhostname - Provide host name resolution for the locally + Provide hostname resolution for the locally configured system hostname. @@ -58,17 +58,17 @@ nss-myhostname is a plugin for the GNU Name Service Switch (NSS) functionality of the GNU C Library (glibc) - providing host name resolution for the locally configured system + providing hostname resolution for the locally configured system hostname as returned by gethostname2. - Various software relies on an always resolvable local host name. When - using dynamic hostnames this is usually achieved by patching + Various software relies on an always-resolvable local hostname. When + using dynamic hostnames, this is usually achieved by patching /etc/hosts at the same time as changing the host name. This however is not ideal since it requires a writable /etc file system and is fragile because the file might be edited by the administrator at the same time. nss-myhostname - simply returns all locally configure public IP addresses, or -- if none - are configured -- the IPv4 address 127.0.0.2 (which is on the local + simply returns all locally configured public IP addresses, or, if none + are configured, the IPv4 address 127.0.0.2 (which is on the local loopback) and the IPv6 address ::1 (which is the local host) for whatever system hostname is configured locally. Patching /etc/hosts is thus no longer necessary. @@ -116,7 +116,7 @@ $ getent ahosts `hostname` 127.0.0.2 RAW - In this case the local host name is omega. + In this case the local hostname is omega. diff --git a/man/os-release.xml b/man/os-release.xml index 45babd61b9..d714b51fba 100644 --- a/man/os-release.xml +++ b/man/os-release.xml @@ -142,7 +142,7 @@ identifying the operating system, excluding any version information and suitable for processing by scripts or - usage in generated file names. If not + usage in generated filenames. If not set defaults to ID=linux. Example: ID=fedora or @@ -199,7 +199,7 @@ system version, excluding any OS name information or release code name, and suitable for processing by scripts or - usage in generated file names. This + usage in generated filenames. This field is optional. Example: VERSION_ID=17 or VERSION_ID=11.04. diff --git a/man/pam_systemd.xml b/man/pam_systemd.xml index 0354811976..4e5cdf248b 100644 --- a/man/pam_systemd.xml +++ b/man/pam_systemd.xml @@ -131,13 +131,13 @@ - Takes a comma - separated list of user names or - numeric user ids as argument. If this - option is used the effect of the + Takes a comma-separated + list of usernames or + numeric user IDs as argument. If this + option is used, the effect of the options will apply only to the listed - users. If this option is not used the + users. If this option is not used, the option applies to all local users. Note that @@ -149,13 +149,13 @@ - Takes a comma - separated list of user names or - numeric user ids as argument. Users + Takes a comma-separated + list of usernames or + numeric user IDs as argument. Users listed in this argument will not be subject to the effect of - . Note - that this option takes precedence + . + Note that this option takes precedence over , and hence whatever is listed for @@ -169,8 +169,8 @@ - Takes a comma - separated list of control group + Takes a comma-separated + list of control group controllers in which hierarchies a user/session control group will be created by default for each user @@ -183,8 +183,8 @@ - Takes a comma - separated list of control group + Takes a comma-separated + list of control group controllers in which hierarchies the logged in processes will be reset to the root control @@ -222,7 +222,7 @@ configured system-wide in logind.conf5. The former kills processes of a session as soon as it - ends, the latter kills processes as soon as the last + ends; the latter kills processes as soon as the last session of the user ends. If the options are omitted they default to @@ -250,7 +250,7 @@ $XDG_SESSION_ID A session identifier, - suitable to be used in file names. The + suitable to be used in filenames. The string itself should be considered opaque, although often it is just the audit session ID as reported by @@ -281,7 +281,7 @@ applications should not rely on this behavior and must be able to deal with stale files. To store session-private - data in this directory the user should + data in this directory, the user should include the value of $XDG_SESSION_ID in the filename. This directory shall be used for runtime file system diff --git a/man/sd-id128.xml b/man/sd-id128.xml index c194f57458..02fb76b56d 100644 --- a/man/sd-id128.xml +++ b/man/sd-id128.xml @@ -50,7 +50,7 @@ SD_ID128_FORMAT_STR SD_ID128_FORMAT_VAL sd_id128_equal - APIs for processing 128 bit IDs + APIs for processing 128-bit IDs @@ -68,12 +68,12 @@ Description sd-id128.h provides APIs to - process and generate 128 bit ID values. The 128 bit ID + process and generate 128-bit ID values. The 128-bit ID values processed and generated by these APIs are a generalization of OSF UUIDs as defined by RFC - 4122, though use a simpler string - formatting. These functions impose no structure on the + 4122 but use a simpler string + format. These functions impose no structure on the used IDs, much unlike OSF UUIDs or Microsoft GUIDs, but are fully compatible with those types of IDs. @@ -85,7 +85,7 @@ for more information about the implemented functions. - A 128 bit ID is implemented as the following + A 128-bit ID is implemented as the following union type: typedef union sd_id128 { @@ -93,26 +93,26 @@ uint64_t qwords[2]; } sd_id128_t; - This union type allows accessing the 128 bit ID - as 16 separate bytes or two 64 bit words. It is generally - safer to access the ID components by their 8 bit array + This union type allows accessing the 128-bit ID + as 16 separate bytes or two 64-bit words. It is generally + safer to access the ID components by their 8-bit array to avoid endianness issues. This union is intended to be passed call-by-value (as opposed to call-by-reference) and may be directly manipulated by clients. A couple of macros are defined to denote and - decode 128 bit IDs: + decode 128-bit IDs: SD_ID128_MAKE() may be used - to denote a constant 128 bit ID in source code. A - commonly used idiom is to assign a name to a 128 bit + to denote a constant 128-bit ID in source code. A + commonly used idiom is to assign a name to a 128-bit ID using this macro: #define SD_MESSAGE_COREDUMP SD_ID128_MAKE(fc,2e,22,bc,6e,e6,47,b6,b9,07,29,ab,34,a2,50,b1) SD_ID128_CONST_STR() may be - used to convert constant 128bit IDs into constant + used to convert constant 128-bit IDs into constant strings for output. The following example code will output the string "fc2e22bc6ee647b6b90729ab34a250b1": @@ -122,7 +122,7 @@ SD_ID128_FORMAT_STR and SD_ID128_FORMAT_VAL() may be used - to format a 128 bit ID in a + to format a 128-bit ID in a printf3 format string, as shown in the following example: @@ -134,7 +134,7 @@ return 0; } - Use sd_id128_equal() to compare two 128 bit IDs: + Use sd_id128_equal() to compare two 128-bit IDs: int main(int argc, char *argv[]) { sd_id128_t a, b, c; diff --git a/man/sd_id128_get_machine.xml b/man/sd_id128_get_machine.xml index 12887a240a..6bee7ad9c1 100644 --- a/man/sd_id128_get_machine.xml +++ b/man/sd_id128_get_machine.xml @@ -45,7 +45,7 @@ sd_id128_get_machine sd_id128_get_boot - Retrieve 128 bit IDs + Retrieve 128-bit IDs @@ -92,10 +92,10 @@ sd_id128_get_boot() always returns a UUID v4 compatible ID. sd_id128_get_machine() will - also return a UUID v4 compatible ID on new - installations, but might not on older. It is possible - to convert the machine ID into an UUID v4 compatible - one. For more information see + also return a UUID v4-compatible ID on new + installations but might not on older. It is possible + to convert the machine ID into a UUID v4-compatible + one. For more information, see machine-id5. For more information about the diff --git a/man/sd_id128_randomize.xml b/man/sd_id128_randomize.xml index 15e17619d0..0b9580308a 100644 --- a/man/sd_id128_randomize.xml +++ b/man/sd_id128_randomize.xml @@ -44,7 +44,7 @@ sd_id128_randomize - Generate 128 bit IDs + Generate 128-bit IDs @@ -63,7 +63,7 @@ Description sd_id128_randomize() - generates a new randomized 128 bit ID and returns it + generates a new randomized 128-bit ID and returns it in ret. Every invocation returns a new randomly generated ID. This uses the /dev/urandom kernel random number @@ -71,16 +71,15 @@ Note that sd_id128_randomize() always returns - a UUID v4 compatible - ID. + a UUID v4-compatible ID. For more information about the - sd_id128_t type see + sd_id128_t type, see sd-id1283. journalctl1's - option may be used as - command line front-end for + option may be used as a + command-line front-end for sd_id128_randomize(). diff --git a/man/sd_id128_to_string.xml b/man/sd_id128_to_string.xml index 6d5cf45f90..3da5b70f80 100644 --- a/man/sd_id128_to_string.xml +++ b/man/sd_id128_to_string.xml @@ -45,7 +45,7 @@ sd_id128_to_string sd_id128_from_string - Format or parse 128 bit IDs as strings + Format or parse 128-bit IDs as strings @@ -69,7 +69,7 @@ Description sd_id128_to_string() - formats a 128 bit ID as character string. It expects + formats a 128-bit ID as a character string. It expects the ID and a string array capable of storing 33 characters. The ID will be formatted as 32 lowercase hexadecimal digits and be terminated by a NUL @@ -78,10 +78,10 @@ sd_id128_from_string() implements the reverse operation: it takes a 33 character string with 32 hexadecimal digits - (either lowercase or uppercase, terminated by NUL) and parses them back into an 128 - bit ID returned in + (either lowercase or uppercase, terminated by NUL) and + parses them back into a 128-bit ID returned in ret. Alternatively, this call - can also parse a 37 character string with a 128bit ID + can also parse a 37-character string with a 128-bit ID formatted as RFC UUID. For more information about the @@ -89,9 +89,9 @@ sd-id1283. Note that these calls operate the same way on all architectures, i.e. the results do not depend on - endianess. + endianness. - When formatting a 128 bit ID into a string it is + When formatting a 128-bit ID into a string, it is often easier to use a format string for printf3. This is easily done using the @@ -106,9 +106,9 @@ sd_id128_to_string() always succeeds and returns a pointer to the string array - passed in. sd_id128_from_string - returns 0 on success (in which case - ret is filled in), or a negative + passed in. sd_id128_from_string + returns 0 on success, in which case + ret is filled in, or a negative errno-style error code. diff --git a/man/sd_is_fifo.xml b/man/sd_is_fifo.xml index 44b41abf86..c136b37d8f 100644 --- a/man/sd_is_fifo.xml +++ b/man/sd_is_fifo.xml @@ -109,14 +109,14 @@ called to check whether the specified file descriptor refers to a socket. If the family parameter is not - AF_UNSPEC it is checked whether + AF_UNSPEC, it is checked whether the socket is of the specified family (AF_UNIX, AF_INET, ...). If the - type parameter is not 0 it is + type parameter is not 0, it is checked whether the socket is of the specified type (SOCK_STREAM, SOCK_DGRAM, ...). If the - listening parameter is positive + listening parameter is positive, it is checked whether the socket is in accepting mode, i.e. listen() has been called for it. If listening is 0, it is @@ -135,14 +135,14 @@ AF_INET6. sd_is_socket_unix() is - similar to sd_is_socket(), but + similar to sd_is_socket() but optionally checks the AF_UNIX path the socket is bound to, unless the path parameter - is NULL. For normal file system AF_UNIX sockets set - the length parameter to 0. For - Linux abstract namespace sockets set the + is NULL. For normal file system AF_UNIX sockets, + set the length parameter to 0. For + Linux abstract namespace sockets, set the length to the size of the - address, including the initial 0 byte and set + address, including the initial 0 byte, and set the path to the initial 0 byte of the socket address. @@ -170,7 +170,7 @@ These functions are provided by the reference implementation of APIs for new-style daemons and distributed with the systemd package. The algorithms - they implement are simple, and can easily be + they implement are simple, and they can easily be reimplemented in daemons if it is important to support this interface without using the reference implementation. @@ -180,7 +180,7 @@ getsockname() to check the file descriptor type and where it is bound to. - For details about the algorithms check the + For details about the algorithms, check the liberally licensed reference implementation sources: and CLOCK_REALTIME. Either one @@ -88,8 +88,8 @@ sd_journal_get_cutoff_monotonic_usec() gets the monotonic timestamps of the first and last entries accessible in the journal. It takes three - arguments: the journal context object, a 128 Bit - identifier for the boot, and two pointers to 64 Bit + arguments: the journal context object, a 128-bit + identifier for the boot, and two pointers to 64-bit unsigned integers to store the timestamps. The timestamps are in microseconds since boot-up of the specific boot, diff --git a/man/sd_journal_get_realtime_usec.xml b/man/sd_journal_get_realtime_usec.xml index e7e4e4e4d1..8870c29e30 100644 --- a/man/sd_journal_get_realtime_usec.xml +++ b/man/sd_journal_get_realtime_usec.xml @@ -73,27 +73,27 @@ sd_journal_get_realtime_usec() gets the realtime (wallclock) timestamp of the - current journal entry. It takes two arguments: the - journal context object and a pointer to a 64 Bit + current journal entry. It takes two arguments: the + journal context object and a pointer to a 64-bit unsigned integer to store the timestamp in. The timestamp is in microseconds since the epoch, i.e. CLOCK_REALTIME. sd_journal_get_monotonic_usec() gets the monotonic timestamp of the current journal - entry. It takes three arguments: the journal context - object, a pointer to a 64 Bit unsigned integer to - store the timestamp in as well as a 128 Bit ID buffer - to store the boot ID of the monotonic timestamp - in. The timestamp is in microseconds since boot-up of + entry. It takes three arguments: the journal context + object, a pointer to a 64-bit unsigned integer to + store the timestamp in, as well as a 128-bit ID buffer + to store the boot ID of the monotonic timestamp. + The timestamp is in microseconds since boot-up of the specific boot, i.e. CLOCK_MONOTONIC. Since the - monotonic clock begins new with every reboot it only + monotonic clock begins new with every reboot, it only defines a well-defined point in time when used - together with an identifier identifying the boot, see + together with an identifier identifying the boot. See sd_id128_get_boot3 for more information. If the boot ID parameter is - passed NULL the function will + passed NULL, the function will fail if the monotonic timestamp of the current entry is not of the current system boot. diff --git a/man/sd_journal_print.xml b/man/sd_journal_print.xml index 81900dbdfb..1437342a55 100644 --- a/man/sd_journal_print.xml +++ b/man/sd_journal_print.xml @@ -202,7 +202,7 @@ sd_journal_send("MESSAGE=Hello World, this is PID %lu!", (unsigned long) getpid( chronological ordering between the two streams cannot be guaranteed. Using sd_journal_print() has the - benefit of logging source code line, file names, and + benefit of logging source code line, filenames, and functions as meta data along all entries, and guaranteeing chronological ordering with structured log entries that are generated via diff --git a/man/sd_journal_stream_fd.xml b/man/sd_journal_stream_fd.xml index 3577526f20..4bd0abc3b4 100644 --- a/man/sd_journal_stream_fd.xml +++ b/man/sd_journal_stream_fd.xml @@ -67,7 +67,7 @@ sd_journal_stream_fd() may be used to create a log stream file descriptor. Log messages written to this file descriptor as simple - newline separated text strings are written to the + newline-separated text strings are written to the journal. This file descriptor can be used internally by applications or be made STDOUT/STDERR of other processes executed. diff --git a/man/sysctl.d.xml b/man/sysctl.d.xml index 759b8740f5..69e96ee9e5 100644 --- a/man/sysctl.d.xml +++ b/man/sysctl.d.xml @@ -96,11 +96,11 @@ contain the same variable setting. If the administrator wants to disable a - configuration file supplied by the vendor the + configuration file supplied by the vendor, the recommended way is to place a symlink to /dev/null in /etc/sysctl.d/ bearing the - same file name. + same filename. diff --git a/man/systemctl.xml b/man/systemctl.xml index 9ab5c8ba5f..84a149c3d0 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -92,7 +92,7 @@ along with systemd; If not, see . - The argument should be a comma separated list of unit + The argument should be a comma-separated list of unit types such as and , or unit load states such as and @@ -732,7 +732,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service names such as cpu.shares. This will output the current values of the specified attributes, separated by new-lines. For attributes that take list of - items the output will be new-line separated, too. This + items the output will be new-line-separated, too. This operation will always try to retrieve the data in question from the kernel first, and if that is not available use the configured values instead. Instead of low-level control diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml index cecf1bf4d3..f5a9424248 100644 --- a/man/systemd-analyze.xml +++ b/man/systemd-analyze.xml @@ -95,7 +95,7 @@ prints the time spent in the kernel before userspace has been reached, the time spent in the initial RAM disk (initrd) before normal system - userspace has been reached and the time normal system + userspace has been reached, and the time normal system userspace took to initialize. Note that these measurements simply measure the time passed up to the point where all system services have been spawned, but @@ -111,7 +111,7 @@ of another service to complete. systemd-analyze critical-chain [UNIT...] - prints a tree of the time critical chain of units + prints a tree of the time-critical chain of units (for each of the specified UNITs or for the default target otherwise). The time after the unit is active or started is printed @@ -135,7 +135,7 @@ dot | dot -Tsvg > systemd.svg to generate a graphical dependency tree. Unless or - is passed the generated graph will show both ordering + is passed, the generated graph will show both ordering and requirement dependencies. Optional pattern globbing style specifications (e.g. *.target) may be given at @@ -143,7 +143,7 @@ any of these patterns match either the origin or destination node. - If no command is passed systemd-analyze + If no command is passed, systemd-analyze time is implied. @@ -191,7 +191,7 @@ RequisiteOverridable=, Wants= and Conflicts= are - shown. If neither is passed, shows + shown. If neither is passed, this shows dependencies of all these types. @@ -203,16 +203,16 @@ When used in conjunction with the dot command (see - above), selects which relationships + above), this selects which relationships are shown in the dependency graph. They both require glob7 patterns as arguments, which are - matched against lefthand and - righthand, respectively, nodes of a + matched against left-hand and + right-hand, respectively, nodes of a relationship. Each of these can be - used more than once which means a - unit name must match one of given + used more than once, which means a + unit name must match one of the given values. @@ -226,7 +226,7 @@ latest unit in the same level. The unit of timespan is seconds unless specified with a different unit, - i.e. "50ms". + e.g. "50ms". diff --git a/man/systemd-hostnamed.service.xml b/man/systemd-hostnamed.service.xml index fe64a62fbe..bdd3a51cc9 100644 --- a/man/systemd-hostnamed.service.xml +++ b/man/systemd-hostnamed.service.xml @@ -45,7 +45,7 @@ systemd-hostnamed.service systemd-hostnamed - Hostname bus mechanism + Host name bus mechanism @@ -57,14 +57,14 @@ Description systemd-hostnamed is a system - service that may be used as mechanism to change the - system hostname. systemd-hostnamed is + service that may be used as a mechanism to change the + system's hostname. systemd-hostnamed is automatically activated on request and terminates itself when it is unused. The tool hostnamectl1 - is a command line client to this service. + is a command-line client to this service. See the diff --git a/man/systemd-inhibit.xml b/man/systemd-inhibit.xml index 6f63c8c73e..de2f264147 100644 --- a/man/systemd-inhibit.xml +++ b/man/systemd-inhibit.xml @@ -101,8 +101,8 @@ - Takes a colon - separated list of one or more + Takes a colon-separated + list of one or more operations to inhibit: shutdown, sleep, @@ -124,9 +124,9 @@ - Takes a short human - readable descriptive string for the - program taking the lock. If not passed + Takes a short, + human-readable descriptive string for the + program taking the lock. If not passed, defaults to the command line string. @@ -134,8 +134,8 @@ - Takes a short human - readable descriptive string for the + Takes a short, + human-readable descriptive string for the reason for taking the lock. Defaults to "Unknown reason". @@ -155,7 +155,7 @@ delay is used, the lock can only delay the requested operations for a limited time. If the - time elapses the lock is ignored and + time elapses, the lock is ignored and the operation executed. The time limit may be specified in systemd-logind.conf5. Note diff --git a/man/systemd-journald.service.xml b/man/systemd-journald.service.xml index 2860ae9769..d751f9b855 100644 --- a/man/systemd-journald.service.xml +++ b/man/systemd-journald.service.xml @@ -73,14 +73,14 @@ Log data collected by the journal is primarily - text based but can also include binary data where + text-based but can also include binary data where necessary. All objects stored in the journal can be up to 2^64-1 bytes in size. By default the journal stores log data in /run/log/journal/. Since - /run/ is volatile log data is - lost at reboot. To make the data persistent it + /run/ is volatile, log data is + lost at reboot. To make the data persistent, it is sufficient to create /var/log/journal/ where systemd-journald will then store @@ -89,8 +89,8 @@ systemd-journald will forward all received log messages to the AF_UNIX SOCK_DGRAM socket - /run/systemd/journal/syslog (if it exists) which - may be used by UNIX syslog daemons to process the data + /run/systemd/journal/syslog, if it exists, which + may be used by Unix syslog daemons to process the data further. See @@ -161,15 +161,15 @@ Access Control - Journal files are by default owned and readable + Journal files are, by default, owned and readable by the systemd-journal system group - (but not writable). Adding a user to this group thus + but are not writable. Adding a user to this group thus enables her/him to read the journal files. By default, each logged in user will get her/his own set of journal files in /var/log/journal/. These files - will not be owned by the user however, in order to + will not be owned by the user, however, in order to avoid that the user can write to them directly. Instead, file system ACLs are used to ensure the user gets read access only. diff --git a/man/systemd-modules-load.service.xml b/man/systemd-modules-load.service.xml index 1d33b8eec6..f8dfab351a 100644 --- a/man/systemd-modules-load.service.xml +++ b/man/systemd-modules-load.service.xml @@ -77,8 +77,8 @@ modules-load= rd.modules-load= - Takes a comma - separated list of kernel modules to + Takes a comma-separated + list of kernel modules to statically load during early boot. The option prefixed with rd. is read by the diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml index ca21f2e6db..feafb31bc0 100644 --- a/man/systemd-nspawn.xml +++ b/man/systemd-nspawn.xml @@ -242,7 +242,7 @@ - Set the specified uuid + Set the specified UUID for the container. The init system will initialize /etc/machine-id @@ -274,7 +274,7 @@ Mount the root file - system read only for the + system read-only for the container. @@ -283,7 +283,7 @@ List one or more additional capabilities to grant the - container. Takes a comma separated + container. Takes a comma-separated list of capability names, see capabilities7 for more information. Note that the diff --git a/man/systemd-readahead-replay.service.xml b/man/systemd-readahead-replay.service.xml index a00f7e589b..806d46093b 100644 --- a/man/systemd-readahead-replay.service.xml +++ b/man/systemd-readahead-replay.service.xml @@ -72,7 +72,7 @@ time. systemd-readahead-replay.service is a service that replays this access data collected at the subsequent boot. Since disks tend to be - magnitudes slower than RAM this is intended to improve + magnitudes slower than RAM, this is intended to improve boot speeds by pre-loading early at boot all data on disk that is known to be read for the complete boot process. @@ -80,9 +80,9 @@ systemd-readahead-done.service is executed a short while after boot completed and signals systemd-readahead-collect.service - to end data collection. On this signal this service + to end data collection. On this signal, this service will then sort the collected disk accesses and store - information about them disk in + information about them in /.readahead. Normally, both @@ -92,17 +92,17 @@ are activated at boot so that access patterns from the preceding boot are replayed and new data collected for the subsequent boot. However, on read-only media - where the collected data cannot be stored it might + where the collected data cannot be stored, it might be a good idea to disable systemd-readahead-collect.service. On rotating media, when replaying disk accesses - at early boot + at early boot, systemd-readahead-replay.service will order read requests by their location on disk. On non-rotating media, they will be ordered by their original access timestamp. If the file system supports - it + it, systemd-readahead-collect.service will also defragment and rearrange files on disk to optimize subsequent boot times. @@ -136,7 +136,7 @@ Maximum size of files - (in bytes) to read ahead. Only valid + in bytes to read ahead. Only valid for the collect and replay commands. @@ -145,8 +145,8 @@ - Maximum time (in usec) - to to spend collecting data. Only valid + Maximum time in microseconds + to spend collecting data. Only valid for the collect command. @@ -164,7 +164,7 @@ [DIRECTORY] Collect read-ahead data on - early boot. When terminating it will + early boot. When terminating, it will write out a pack file to the indicated directory containing the read-ahead data. @@ -186,9 +186,9 @@ Dumps the content of the read-ahead pack file to the - terminal. The output lists - approximately for each file - how much will be read-ahead by + terminal. For each file, the + output lists approximately how + much will be read ahead by the replay command. diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml index 48d02269cc..a67b158996 100644 --- a/man/systemd-system.conf.xml +++ b/man/systemd-system.conf.xml @@ -112,8 +112,8 @@ addition to the name=systemd named hierarchy. Defaults to - cpu. Takes a space - separated list of controller + cpu. Takes a + space-separated list of controller names. Pass the empty string to ensure that systemd does not touch any hierarchies but its own. @@ -138,8 +138,8 @@ enabled in the kernel in individual hierarchies, with the exception of those listed in this setting. Takes a - space separated list of comma - separated controller names, in order + space-separated list of comma-separated + controller names, in order to allow multiple joined hierarchies. Defaults to 'cpu,cpuacct'. Pass an empty string to @@ -150,7 +150,7 @@ Note that this option is only applied once, at very early boot. If you use an initial RAM disk (initrd) - that uses systemd it might hence be + that uses systemd, it might hence be necessary to rebuild the initrd if this option is changed, and make sure the new configuration file is included @@ -214,9 +214,8 @@ capability bounding set for PID 1 and its children. See capabilities7 - for details. Takes a whitespace - separated list of capability names as - read by + for details. Takes a whitespace-separated + list of capability names as read by cap_from_name3. Capabilities listed will be included in the bounding set, all others are diff --git a/man/systemd-timedated.service.xml b/man/systemd-timedated.service.xml index c82c0ff439..4f17bccc69 100644 --- a/man/systemd-timedated.service.xml +++ b/man/systemd-timedated.service.xml @@ -57,7 +57,7 @@ Description systemd-timedated is a - system service that may be used as mechanism to change + system service that may be used as a mechanism to change the system clock and timezone, as well as to enable/disable NTP time synchronization. systemd-timedated @@ -66,7 +66,7 @@ The tool timedatectl1 - is a command line client to this service. + is a command-line client to this service. See the diff --git a/man/systemd-tmpfiles.xml b/man/systemd-tmpfiles.xml index 0d2d65d593..405a9f1781 100644 --- a/man/systemd-tmpfiles.xml +++ b/man/systemd-tmpfiles.xml @@ -76,7 +76,7 @@ If invoked with no arguments, it applies all directives from all configuration files. If one or - more file names are passed on the command line, only + more filenames are passed on the command line, only the directives in these files are applied. If only the basename of a configuration file is specified, all configuration directories as specified in diff --git a/man/systemd.automount.xml b/man/systemd.automount.xml index e01cac7bc2..2a310d3ecf 100644 --- a/man/systemd.automount.xml +++ b/man/systemd.automount.xml @@ -133,7 +133,7 @@ existing at time that the automount point is installed it is created. This string must be reflected in the unit - file name. (See above.) This option is + filename. (See above.) This option is mandatory. diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 2ccc470e26..d6fc324b5d 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -129,7 +129,7 @@ Sets the supplementary Unix groups the processes are executed - as. This takes a space separated list + as. This takes a space-separated list of group names or IDs. This option may be specified more than once in which case all listed groups are set as @@ -312,7 +312,7 @@ Environment= but reads the environment variables from a text file. The text file should - contain new-line separated variable + contain new-line-separated variable assignments. Empty lines and lines starting with ; or # will be ignored, which may be used for commenting. A line @@ -324,7 +324,7 @@ double quotes ("). The argument passed should be an - absolute file name or wildcard + absolute filename or wildcard expression, optionally prefixed with "-", which indicates that if the file does not exist it won't be read and no @@ -717,9 +717,8 @@ capability bounding set for the executed process. See capabilities7 - for details. Takes a whitespace - separated list of capability names as - read by + for details. Takes a whitespace-separated + list of capability names as read by cap_from_name3, e.g. CAP_SYS_ADMIN, CAP_DAC_OVERRIDE, @@ -986,7 +985,7 @@ Control access to specific device nodes by the executed processes. Takes two - space separated strings: a device node + space-separated strings: a device node path (such as /dev/null) followed by a combination of r, w, m @@ -1011,7 +1010,7 @@ processes. Takes either a single weight value (between 10 and 1000) to set the default block IO weight, or a - space separated pair of a file path + space-separated pair of a file path and a weight value to specify the device specific weight value (Example: "/dev/sda 500"). The file path may be @@ -1037,8 +1036,8 @@ Set the per-device overall block IO bandwidth limit for - the executed processes. Takes a space - separated pair of a file path and a + the executed processes. Takes a + space-separated pair of a file path and a bandwidth value (in bytes per second) to specify the device specific bandwidth. The file path may be @@ -1185,9 +1184,9 @@ IgnoreSIGPIPE= Takes a boolean - argument. If true causes SIGPIPE to be + argument. If true, causes SIGPIPE to be ignored in the executed - process. Defaults to true, since + process. Defaults to true because SIGPIPE generally is useful only in shell pipelines. @@ -1196,7 +1195,7 @@ NoNewPrivileges= Takes a boolean - argument. If true ensures that the + argument. If true, ensures that the service process and all its children can never gain new privileges. This option is more powerful than the respective @@ -1211,9 +1210,9 @@ SystemCallFilter= - Takes a space - separated list of system call - names. If this setting is used all + Takes a space-separated + list of system call + names. If this setting is used, all system calls executed by the unit process except for the listed ones will result in immediate process diff --git a/man/systemd.journal-fields.xml b/man/systemd.journal-fields.xml index fe65078f76..bced51d635 100644 --- a/man/systemd.journal-fields.xml +++ b/man/systemd.journal-fields.xml @@ -72,7 +72,7 @@ MESSAGE= - The human readable + The human-readable message string for this entry. This is supposed to be the primary text shown to the @@ -87,16 +87,16 @@ MESSAGE_ID= - A 128bit message + A 128-bit message identifier ID for recognizing certain message types, if this is desirable. This should - contain a 128bit id formatted - as lower-case hexadecimal + contain a 128-bit ID formatted + as a lower-case hexadecimal string, without any separating dashes or suchlike. This is - recommended to be a UUID - compatible ID, but this is not + recommended to be a + UUID-compatible ID, but this is not enforced, and formatted differently. Developers can generate a new ID for this @@ -113,7 +113,7 @@ 0 (emerg) and 7 (debug) - formatted as decimal + formatted as a decimal string. This field is compatible with syslog's priority concept. @@ -128,7 +128,7 @@ The code location generating this message, if known. Contains the source - file name, the line number and + filename, the line number and the function name. @@ -141,7 +141,7 @@ any. Contains the numeric value of errno3 - formatted as decimal + formatted as a decimal string. @@ -179,7 +179,7 @@ The process, user and group ID of the process the journal entry originates from - formatted as decimal + formatted as a decimal string. @@ -246,8 +246,8 @@ any is known that is different from the reception time of the journal. This is the time in - usec since the epoch UTC - formatted as decimal + microseconds since the epoch UTC, + formatted as a decimal string. @@ -258,7 +258,7 @@ The kernel boot ID for the boot the message was generated in, formatted as - 128bit hexadecimal + a 128-bit hexadecimal string. @@ -457,7 +457,7 @@ JSON Format, the addresses of journal entries are serialized into fields prefixed with double underscores. Note that these aren't proper fields when - stored in the journal, but addressing meta data of + stored in the journal but for addressing meta data of entries. They cannot be written as part of structured log entries via calls such as sd_journal_send3. They @@ -486,11 +486,11 @@ (CLOCK_REALTIME) at the point in time the entry was received by the journal, - in usec since the epoch UTC - formatted as decimal + in microseconds since the epoch + UTC, formatted as a decimal string. This has different properties from - _SOURCE_REALTIME_TIMESTAMP= + _SOURCE_REALTIME_TIMESTAMP=, as it is usually a bit later but more likely to be monotonic. @@ -504,10 +504,10 @@ (CLOCK_MONOTONIC) at the point in time the entry was received by the journal in - usec formatted as decimal + microseconds, formatted as a decimal string. To be useful as an - address for the entry this - should be combined with with + address for the entry, this + should be combined with with the boot ID in _BOOT_ID=. diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml index 21177a2623..d47fb93669 100644 --- a/man/systemd.mount.xml +++ b/man/systemd.mount.xml @@ -206,14 +206,14 @@ the mount point does not exist at the time of mounting, it is created. This string must be reflected in the unit - file name. (See above.) This option is + filename. (See above.) This option is mandatory. Type= Takes a string for the - filesystem type. See + file system type. See mount8 for details. This setting is optional. @@ -223,8 +223,8 @@ Options= Mount options to use - when mounting. This takes a comma - separated list of options. This + when mounting. This takes a + comma-separated list of options. This setting is optional. @@ -245,7 +245,7 @@ Configures the time to wait for the mount command to finish. If a command does not exit - within the configured time the mount + within the configured time, the mount will be considered failed and be shut down again. All commands still running will be terminated forcibly via diff --git a/man/systemd.preset.xml b/man/systemd.preset.xml index a692053876..1ba9272398 100644 --- a/man/systemd.preset.xml +++ b/man/systemd.preset.xml @@ -109,7 +109,7 @@ by default, disable to disable units by default. - If multiple lines apply to a unit name the + If multiple lines apply to a unit name, the first matching one takes precedence over all others. @@ -131,14 +131,14 @@ precedence over another file with an alphabetically earlier name, if both files contain lines that apply to the same unit names. It is recommended to prefix - all file names with two-digit number, to simplify + all filenames with two-digit number, to simplify ordering. If the administrator wants to disable a preset - file supplied by the vendor the recommended way is to + file supplied by the vendor, the recommended way is to place a symlink to /dev/null in /etc/systemd/system-preset/ - bearing the same file name. + bearing the same filename. @@ -150,8 +150,8 @@ disable * - This disables all units. Due to the file name - prefix 99- it will be read last and + This disables all units. Due to the filename + prefix 99-, it will be read last and hence can easily be overridden by spin or administrator preset policy or suchlike. @@ -187,7 +187,7 @@ disable * This enables three specific services and disables all others. This is useful for administrators to specifically select the units to enable, and - disable all others. Due to the file name prefix + disable all others. Due to the filename prefix 00- it will be read early and hence overrides all other preset policy files. diff --git a/man/systemd.service.xml b/man/systemd.service.xml index dcf57c30bb..fab0c4de27 100644 --- a/man/systemd.service.xml +++ b/man/systemd.service.xml @@ -375,7 +375,7 @@ argv[0] to the executed process, followed by the further arguments specified. If the - absolute file name is prefixed with + absolute filename is prefixed with - an exit code of the command normally considered a failure (i.e. non-zero exit status or diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml index 0d5652b834..0ff3ca22ac 100644 --- a/man/systemd.socket.xml +++ b/man/systemd.socket.xml @@ -387,8 +387,8 @@ close2 on the received socket before exiting. However, it must not unlink - the socket from a filesystem. It - should note invoke + the socket from a file system. It + should not invoke shutdown2 on sockets it got with Accept=false, but @@ -412,7 +412,7 @@ are coming in, they will be refused until at least one existing connection is terminated. This setting has no - effect for sockets configured with + effect on sockets configured with or datagram sockets. Defaults to 64. @@ -516,7 +516,7 @@ respectively, i.e. the security label of the FIFO, or the security label for the incoming or outgoing connections - of the socket, respectively. See + of the socket, respectively. See Smack.txt for details. @@ -527,7 +527,7 @@ Takes an integer value. Controls the pipe buffer size of FIFOs configured in this socket - unit. See + unit. See fcntl2 for details. @@ -598,7 +598,7 @@ socket option, which allows AF_UNIX sockets to receive the security context of the sending process in an - ancillary message. Defaults to + ancillary message. Defaults to . @@ -622,7 +622,7 @@ before or after the listening sockets/FIFOs are created and bound, respectively. The first token of the command - line must be an absolute file name, + line must be an absolute filename, then followed by arguments for the process. Multiple command lines may be specified following the same scheme as @@ -701,7 +701,7 @@ - For more extensive descriptions see the "Systemd for Developers" series: + For more extensive descriptions see the "systemd for Developers" series: Socket Activation, Socket Activation, part II, Converting inetd Services, diff --git a/man/systemd.time.xml b/man/systemd.time.xml index a9318bb787..79ebdc5dfc 100644 --- a/man/systemd.time.xml +++ b/man/systemd.time.xml @@ -50,16 +50,16 @@ Description - In systemd timestamps, timespans, and calendar + In systemd, timestamps, time spans, and calendar events are displayed and may be specified in closely related syntaxes. - Displaying Timespans + Displaying Time Spans - Timespans refer to time durations. On display - systemd will present timespans as a space separated + Time spans refer to time durations. On display, + systemd will present time spans as a space-separated series of time values each suffixed by a time unit. @@ -70,10 +70,10 @@ - Parsing Timespans + Parsing Time Spans - When parsing systemd will accept the same - timespan syntax. Separating spaces may be omitted. The + When parsing, systemd will accept the same + time span syntax. Separating spaces may be omitted. The following time units are understood: @@ -92,9 +92,9 @@ are assumed, but some exceptions exist and are marked as such. In a few cases ns, nsec is accepted too, where the - granularity of the timespan allows for this. + granularity of the time span allows for this. - Examples for valid timespan specifications: + Examples for valid time span specifications: 2 h 2hours @@ -108,12 +108,12 @@ Displaying Timestamps Timestamps refer to specific, unique points in - time. On display systemd will format these in the + time. On display, systemd will format these in the local timezone as follows: Fri 2012-11-23 23:02:15 CET - The week day is printed according to the locale + The weekday is printed according to the locale choice of the user. @@ -123,10 +123,10 @@ When parsing systemd will accept a similar timestamp syntax, but excluding any timezone specification (this limitation might be removed - eventually). The week day specification is optional, - but when the week day is specified it must either be + eventually). The weekday specification is optional, + but when the weekday is specified it must either be in the abbreviated (Wed) or - non-abbreviated (Wednesday) english + non-abbreviated (Wednesday) English language form (case doesn't matter), and is not subject to the locale choice of the user. Either the date, or the time part may be omitted, in which case @@ -136,11 +136,11 @@ specified in full or may be abbreviated (omitting the century). - A timestamp is considered invalid if a week day + A timestamp is considered invalid if a weekday is specified and the date does not actually match the specified day of the week. - When parsing systemd will also accept a few + When parsing, systemd will also accept a few special placeholders instead of timestamps: now may be used to refer to the current time (or of the invocation of the command @@ -150,14 +150,14 @@ current day, the day before or the next day, respectively. - When parsing systemd will also accept relative - time specifications. A timespan (see above) that is + When parsing, systemd will also accept relative + time specifications. A time span (see above) that is prefixed with + is evaluated to the current time plus the specified - timespan. Correspondingly a timespan that is prefix + time span. Correspondingly, a time span that is prefixed with - is evaluated to the current - time minus the specified timespan. Instead of - prefixing the timespan with - it + time minus the specified time span. Instead of + prefixing the time span with - it may also be suffixed with a space and the word ago. @@ -182,10 +182,10 @@ Note that timestamps printed by systemd will not be parsed correctly by systemd, as the timezone specification is not accepted, and printing timestamps - is subject to locale settings for the week day while - parsing only accepts english week day names. + is subject to locale settings for the weekday while + parsing only accepts English weekday names. - In some cases systemd will display a relative + In some cases, systemd will display a relative timestamp (relative to the current time, or the time of invocation of the command) instead or in addition to an absolute timestamp as described above. A @@ -208,17 +208,17 @@ The above refers to 11:12:13 of the first or fifth day of any month of the year 2012, given that it - is a thursday or friday. + is a Thursday or Friday. The weekday specification is optional. If - specified it should consist of one or more english - language week day names, either in the abbreviated + specified, it should consist of one or more English + language weekday names, either in the abbreviated (Wed) or non-abbreviated (Wednesday) form (case does - not matter), separated by commas. Specifying two week - days separated by "-" refers to a range of continuous - week days. "," and "-" may be combined freely. + not matter), separated by commas. Specifying two weekdays + separated by "-" refers to a range of continuous + weekdays. "," and "-" may be combined freely. - In the date and time specifications any + In the date and time specifications, any component may be specified as "*" in which case any value will match. Alternatively, each component can be specified as list of values separated by diff --git a/man/systemd.timer.xml b/man/systemd.timer.xml index 2b9d91a60f..1f0aac2eed 100644 --- a/man/systemd.timer.xml +++ b/man/systemd.timer.xml @@ -160,7 +160,7 @@ monotonic clock stops too. If the empty string is assigned - to any of these options the list of + to any of these options, the list of timers is reset, and all prior assignments will have no effect. diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index 1cfdac9267..552c747695 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -182,7 +182,7 @@ directive. If a line starts with - followed by a file name, the specified file will be + followed by a filename, the specified file will be parsed at this point. Make sure that the file that is included has the appropriate section headers before any directives. @@ -200,7 +200,7 @@ with the device node /dev/sda in the file system namespace. If this applies a special way to escape the path name is used, so that the - result is usable as part of a file name. Basically, + result is usable as part of a filename. Basically, given a path, "/" is replaced by "-", and all unprintable characters and the "-" are replaced by C-style "\x20" escapes. The root directory "/" is @@ -382,7 +382,7 @@ Documentation= - A space separated list + A space-separated list of URIs referencing documentation for this unit or its configuration. Accepted are only URIs @@ -393,7 +393,7 @@ info:, man:. For more information about the syntax of these - URIs see + URIs, see uri7. The URIs should be listed in order of relevance, starting with the most @@ -405,7 +405,7 @@ option may be specified more than once in which case the specified list of URIs is merged. If the empty string is - assigned to this option the list is + assigned to this option, the list is reset and all prior assignments will have no effect. @@ -669,8 +669,8 @@ RequiresMountsFor= - Takes a space - separated list of absolute paths. Automatically + Takes a space-separated + list of absolute paths. Automatically adds dependencies of type Requires= and After= for all @@ -1007,11 +1007,11 @@ ConditionHost= may be used to match against the - host name or machine ID of the - host. This either takes a host name + hostname or machine ID of the + host. This either takes a hostname string (optionally with shell style globs) which is tested against the - locally set host name as returned by + locally set hostname as returned by gethostname2, or a machine ID formatted as string (see @@ -1108,7 +1108,7 @@ time, systemctl enable will create symlinks from these names - to the unit file name. + to the unit filename. @@ -1207,7 +1207,7 @@ %f - Unescaped file name + Unescaped filename This is either the unescaped instance name (if applicable) with / prepended (if applicable), or the prefix name similarly prepended with /. @@ -1263,7 +1263,7 @@ %H Host name - The host name of the running system. + The hostname of the running system. %% diff --git a/man/systemd.xml b/man/systemd.xml index ef95641387..5f941e5f94 100644 --- a/man/systemd.xml +++ b/man/systemd.xml @@ -473,7 +473,7 @@ Systemd contains native implementations of various tasks that need to be executed as part of the - boot process. For example, it sets the host name or + boot process. For example, it sets the hostname or configures the loopback network device. It also sets up and mounts various API file systems, such as /sys or diff --git a/man/timedatectl.xml b/man/timedatectl.xml index e291f04e1e..77af2ad460 100644 --- a/man/timedatectl.xml +++ b/man/timedatectl.xml @@ -158,7 +158,7 @@ Set the system time zone to the specified value. Available - time zones can be listed with + timezones can be listed with list-timezones. If the RTC is configured to be in the local time this will also update the @@ -176,7 +176,7 @@ List available time zones, one per line. Entries from the list can be set as the system - time zone with + timezone with set-timezone. @@ -190,7 +190,7 @@ 1 it will maintain the RTC in local time instead. Note that maintaining the RTC in the local - time zone is not fully supported and + timezone is not fully supported and will create various problems with time zone changes and daylight saving adjustments. If at all possible use diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml index 519f9bc618..6a2193d67d 100644 --- a/man/tmpfiles.d.xml +++ b/man/tmpfiles.d.xml @@ -89,7 +89,7 @@ recommended way is to place a symlink to /dev/null in /etc/tmpfiles.d/ bearing the - same file name. + same filename. The configuration format is one line per path containing action, path, mode, ownership, age and argument diff --git a/man/udev.xml b/man/udev.xml index 2353b10023..553bbfd056 100644 --- a/man/udev.xml +++ b/man/udev.xml @@ -61,7 +61,7 @@ and the local administration directory /etc/udev/rules.d. All rules files are collectively sorted and processed in lexical order, regardless of the directories in which they live. However, files with - identical file names replace each other. Files in /etc + identical filenames replace each other. Files in /etc have the highest priority, files in /run take precedence over files with the same name in /lib. This can be used to override a system-supplied rules file with a local file if needed; diff --git a/src/core/main.c b/src/core/main.c index 2bd1efd5d0..8b8e110f24 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1345,10 +1345,10 @@ int main(int argc, char *argv[]) { */ hwclock_reset_timezone(); - /* Tell the kernel our time zone */ + /* Tell the kernel our timezone */ r = hwclock_set_timezone(NULL); if (r < 0) - log_error("Failed to set the kernel's time zone, ignoring: %s", strerror(-r)); + log_error("Failed to set the kernel's timezone, ignoring: %s", strerror(-r)); } } diff --git a/src/shared/hwclock.c b/src/shared/hwclock.c index cc11faa6c3..17f12de51f 100644 --- a/src/shared/hwclock.c +++ b/src/shared/hwclock.c @@ -151,7 +151,7 @@ int hwclock_reset_timezone(void) { /* * The very first time we set the kernel's timezone, it will warp * the clock. Do a dummy call here, so the time warping is sealed - * and we set only the time zone with next call. + * and we set only the timezone with next call. */ if (settimeofday(tv_null, &tz) < 0) return -errno; diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c index d2b483efac..141180c393 100644 --- a/src/timedate/timedatectl.c +++ b/src/timedate/timedatectl.c @@ -198,7 +198,7 @@ static void print_status_info(StatusInfo *i) { if (i->local_rtc) fputs("\n" ANSI_HIGHLIGHT_ON - "Warning: The RTC is configured to maintain time in the local time zone. This\n" + "Warning: The RTC is configured to maintain time in the local timezone. This\n" " mode is not fully supported and will create various problems with time\n" " zone changes and daylight saving adjustments. If at all possible use\n" " RTC in UTC, by calling 'timedatectl set-local-rtc 0'" ANSI_HIGHLIGHT_OFF ".\n", stdout); diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c index cdb6e5b16c..525c72e497 100644 --- a/src/timedate/timedated.c +++ b/src/timedate/timedated.c @@ -662,7 +662,7 @@ static DBusHandlerResult timedate_message_handler( return bus_send_error_reply(connection, message, NULL, r); } - /* 2. Tell the kernel our time zone */ + /* 2. Tell the kernel our timezone */ hwclock_set_timezone(NULL); if (tz.local_rtc) { @@ -719,7 +719,7 @@ static DBusHandlerResult timedate_message_handler( return bus_send_error_reply(connection, message, NULL, r); } - /* 2. Tell the kernel our time zone */ + /* 2. Tell the kernel our timezone */ hwclock_set_timezone(NULL); /* 3. Synchronize clocks */ -- cgit v1.2.1 From 05cc726731c5cec952722f1c14acb08e3d4d5e98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 29 Jun 2013 12:09:14 -0400 Subject: man: add more formatting markup --- man/daemon.xml | 6 +++--- man/hostnamectl.xml | 19 ++++++++++--------- man/localectl.xml | 2 +- man/loginctl.xml | 24 ++++++++++++++---------- man/sd_id128_to_string.xml | 11 ++++++----- man/sd_is_fifo.xml | 11 ++++++----- man/sd_notify.xml | 2 +- man/sd_seat_get_active.xml | 7 ++++--- man/systemctl.xml | 6 +++--- man/systemd.exec.xml | 23 ++++++++++++----------- man/systemd.kill.xml | 8 ++++---- man/systemd.mount.xml | 4 ++-- man/systemd.service.xml | 14 +++++++------- man/systemd.socket.xml | 20 +++++++++++--------- man/systemd.special.xml | 2 +- man/systemd.swap.xml | 4 ++-- man/systemd.time.xml | 23 ++++++++++++----------- man/systemd.unit.xml | 6 +++--- man/systemd.xml | 2 +- man/timedatectl.xml | 2 +- 20 files changed, 104 insertions(+), 92 deletions(-) diff --git a/man/daemon.xml b/man/daemon.xml index 258694080e..76ae832a42 100644 --- a/man/daemon.xml +++ b/man/daemon.xml @@ -92,7 +92,7 @@ best done by iterating through the available signals up to the limit of _NSIG and resetting them to - SIG_DFL. + SIG_DFL. Reset the signal mask using @@ -237,11 +237,11 @@ to implement the following: - If SIGTERM is + If SIGTERM is received, shut down the daemon and exit cleanly. - If SIGHUP is received, + If SIGHUP is received, reload the configuration files, if this applies. diff --git a/man/hostnamectl.xml b/man/hostnamectl.xml index d7a9e92879..28e875dafd 100644 --- a/man/hostnamectl.xml +++ b/man/hostnamectl.xml @@ -129,7 +129,7 @@ Execute the operation remotely. Specify a hostname, or - username and hostname separated by @, + username and hostname separated by @, to connect to. This will use SSH to talk to a remote system. @@ -178,20 +178,21 @@ hostname will be simplified in regards to the character set used before the latter are updated. This is done by - replacing spaces with "-" and removing + replacing spaces with + - and removing special characters. This ensures that the pretty and the static hostname are always closely related while still following the validity rules of the specific name. This simplification of the hostname string is not done if - only the transient and/or static - hostnames are set, and the pretty - hostname is left untouched. Pass the - empty string "" as the hostname to - reset the selected hostnames to their - default (usually "localhost"). - + only the transient and/or static host + names are set, and the pretty host + name is left untouched. Pass the empty + string as the + hostname to reset the selected + hostnames to their default (usually + localhost). diff --git a/man/localectl.xml b/man/localectl.xml index 4a0457018f..f14393071a 100644 --- a/man/localectl.xml +++ b/man/localectl.xml @@ -124,7 +124,7 @@ Execute the operation remotely. Specify a hostname, or - username and hostname separated by @, + username and hostname separated by @, to connect to. This will use SSH to talk to a remote system. diff --git a/man/loginctl.xml b/man/loginctl.xml index f10ca030c9..790a3e4bf8 100644 --- a/man/loginctl.xml +++ b/man/loginctl.xml @@ -158,9 +158,11 @@ which signal to send to selected processes. Must be one of the well known signal specifiers, such as - SIGTERM, SIGINT or SIGSTOP. If omitted, - defaults to - . + SIGTERM, + SIGINT or + SIGSTOP. If + omitted defaults to + SIGTERM. @@ -169,7 +171,7 @@ Execute operation remotely. Specify a hostname, or - username and hostname separated by @, + username and hostname separated by @, to connect to. This will use SSH to talk to the remote login manager instance. @@ -415,12 +417,14 @@ attach at least one graphics card to a previously unused seat name. Seat names may consist only of a-z, A-Z, - 0-9, "-" and "_" and must be prefixed - with "seat". To drop assignment of a - device to a specific seat, just - reassign it to a different seat, or - use - flush-devices. + 0-9, - and + _ and must be + prefixed with seat. + To drop assignment of a device to a + specific seat, just reassign it to a + different seat, or use + flush-devices. + diff --git a/man/sd_id128_to_string.xml b/man/sd_id128_to_string.xml index 3da5b70f80..71cf82a6cd 100644 --- a/man/sd_id128_to_string.xml +++ b/man/sd_id128_to_string.xml @@ -72,14 +72,15 @@ formats a 128-bit ID as a character string. It expects the ID and a string array capable of storing 33 characters. The ID will be formatted as 32 lowercase - hexadecimal digits and be terminated by a NUL - byte. + hexadecimal digits and be terminated by a + NUL byte. sd_id128_from_string() implements the reverse operation: it takes a 33 - character string with 32 hexadecimal digits - (either lowercase or uppercase, terminated by NUL) and - parses them back into a 128-bit ID returned in + character string with 32 hexadecimal digits (either + lowercase or uppercase, terminated by + NUL) and parses them back into a + 128-bit ID returned in ret. Alternatively, this call can also parse a 37-character string with a 128-bit ID formatted as RFC UUID. diff --git a/man/sd_is_fifo.xml b/man/sd_is_fifo.xml index c136b37d8f..a790c370e1 100644 --- a/man/sd_is_fifo.xml +++ b/man/sd_is_fifo.xml @@ -102,8 +102,9 @@ sd_is_fifo() may be called to check whether the specified file descriptor refers to a FIFO or pipe. If the path - parameter is not NULL, it is checked whether the FIFO - is bound to the specified file system path. + parameter is not NULL, it is + checked whether the FIFO is bound to the specified + file system path. sd_is_socket() may be called to check whether the specified file descriptor @@ -149,9 +150,9 @@ sd_is_mq() may be called to check whether the specified file descriptor refers to a POSIX message queue. If the - path parameter is not NULL, it - is checked whether the message queue is bound to the - specified name. + path parameter is not + NULL, it is checked whether the + message queue is bound to the specified name. diff --git a/man/sd_notify.xml b/man/sd_notify.xml index a7bf17f9c6..7d96890397 100644 --- a/man/sd_notify.xml +++ b/man/sd_notify.xml @@ -220,7 +220,7 @@ AF_UNIX socket referenced in the $NOTIFY_SOCKET environment variable. If the first character of - $NOTIFY_SOCKET is @ the string is + $NOTIFY_SOCKET is @ the string is understood as Linux abstract namespace socket. The datagram is accompanied by the process credentials of the sending daemon, using SCM_CREDENTIALS. diff --git a/man/sd_seat_get_active.xml b/man/sd_seat_get_active.xml index 8b32bdc669..3c26fb1e29 100644 --- a/man/sd_seat_get_active.xml +++ b/man/sd_seat_get_active.xml @@ -93,9 +93,10 @@ a seat, if there is any. Returns the session identifier and the user identifier of the Unix user the session is belonging to. Either the session or the - user identifier parameter can be passed NULL, in - case only one of the parameters shall be queried. The - returned string needs to be freed with the libc + user identifier parameter can be passed + NULL, in case only one of the + parameters shall be queried. The returned string needs + to be freed with the libc free3 call after use. diff --git a/man/systemctl.xml b/man/systemctl.xml index 84a149c3d0..632a26dedb 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -382,8 +382,8 @@ along with systemd; If not, see . When used with kill, choose which signal to send to selected processes. Must be one of the - well known signal specifiers such as SIGTERM, SIGINT or - SIGSTOP. If omitted defaults to + well known signal specifiers such as SIGTERM, SIGINT or + SIGSTOP. If omitted defaults to . @@ -453,7 +453,7 @@ along with systemd; If not, see . Execute operation remotely. Specify a hostname, or - username and hostname separated by @, to connect to. This + username and hostname separated by @, to connect to. This will use SSH to talk to the remote systemd instance. diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index d6fc324b5d..4294e54a55 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -326,15 +326,16 @@ The argument passed should be an absolute filename or wildcard expression, optionally prefixed with - "-", which indicates that if the file - does not exist it won't be read and no - error or warning message is logged. - This option may be specified more than - once in which case all specified files - are read. If the empty string is - assigned to this option the list of - file to read is reset, all prior - assignments have no effect. + -, which indicates + that if the file does not exist it + won't be read and no error or warning + message is logged. This option may be + specified more than once in which case + all specified files are read. If the + empty string is assigned to this + option the list of file to read is + reset, all prior assignments have no + effect. The files listed with this directive will be read shortly before @@ -1184,10 +1185,10 @@ IgnoreSIGPIPE= Takes a boolean - argument. If true, causes SIGPIPE to be + argument. If true, causes SIGPIPE to be ignored in the executed process. Defaults to true because - SIGPIPE generally is useful only in + SIGPIPE generally is useful only in shell pipelines. diff --git a/man/systemd.kill.xml b/man/systemd.kill.xml index b41ce460b5..2a810e257f 100644 --- a/man/systemd.kill.xml +++ b/man/systemd.kill.xml @@ -115,14 +115,14 @@ . Processes will first be - terminated via SIGTERM (unless the + terminated via SIGTERM (unless the signal to send is changed via KillSignal=). If then after a delay (configured via the TimeoutSec= option) processes still remain, the termination request is repeated with - the SIGKILL signal (unless this is + the SIGKILL signal (unless this is disabled via the SendSIGKILL= option). See @@ -135,14 +135,14 @@ KillSignal= Specifies which signal to use when killing a - service. Defaults to SIGTERM. + service. Defaults to SIGTERM. SendSIGKILL= Specifies whether to - send SIGKILL to remaining processes + send SIGKILL to remaining processes after a timeout, if the normal shutdown procedure left processes of the service around. Takes a boolean diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml index d47fb93669..07f21025b8 100644 --- a/man/systemd.mount.xml +++ b/man/systemd.mount.xml @@ -249,8 +249,8 @@ will be considered failed and be shut down again. All commands still running will be terminated forcibly via - SIGTERM, and after another delay of - this time with SIGKILL. (See + SIGTERM, and after another delay of + this time with SIGKILL. (See in systemd.kill5.) Takes a unit-less value in seconds, or diff --git a/man/systemd.service.xml b/man/systemd.service.xml index fab0c4de27..abe3a8d673 100644 --- a/man/systemd.service.xml +++ b/man/systemd.service.xml @@ -529,9 +529,9 @@ wait for stop. If a service is asked to stop but does not terminate in the specified time, it will be terminated - forcibly via SIGTERM, and after + forcibly via SIGTERM, and after another delay of this time with - SIGKILL (See + SIGKILL (See KillMode= in systemd.kill5). Takes a unit-less value in seconds, or a @@ -620,7 +620,7 @@ exits cleanly. In this context, a clean exit means an exit code of 0, or one of the signals - SIGHUP, SIGINT, SIGTERM, or SIGPIPE, and + SIGHUP, SIGINT, SIGTERM, or SIGPIPE, and additionally, exit statuses and signals specified in SuccessExitStatus=. If set to @@ -657,15 +657,15 @@ by the main service process will be considered successful termination, in addition to the normal successful exit - code 0 and the signals SIGHUP, SIGINT, - SIGTERM and SIGPIPE. Exit status + code 0 and the signals SIGHUP, SIGINT, + SIGTERM and SIGPIPE. Exit status definitions can either be numeric exit codes or termination signal names, separated by spaces. Example: SuccessExitStatus=1 2 8 - SIGKILL, ensures that exit + SIGKILL, ensures that exit codes 1, 2, 8 and the termination - signal SIGKILL are considered clean + signal SIGKILL are considered clean service terminations. This option may appear more than once in which case the list of successful exit statuses diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml index 0ff3ca22ac..0a2d86996b 100644 --- a/man/systemd.socket.xml +++ b/man/systemd.socket.xml @@ -156,16 +156,18 @@ can be written in various formats: If the address starts with a - slash (/), it is read as file system + slash (/), it is read as file system socket in the AF_UNIX socket family. - If the address starts with an - at symbol (@) it is read as abstract - namespace socket in the AF_UNIX - family. The @ is replaced with a NUL - character before binding. For details - see + If the address starts with an at + symbol (@) it is read as abstract + namespace socket in the + AF_UNIX + family. The @ is + replaced with a + NUL character + before binding. For details see unix7. If the address string is a @@ -657,8 +659,8 @@ will be considered failed and be shut down again. All commands still running, will be terminated forcibly via - SIGTERM, and after another delay of - this time with SIGKILL. (See + SIGTERM, and after another delay of + this time with SIGKILL. (See in systemd.kill5.) Takes a unit-less value in seconds, or a time span value such as "5min diff --git a/man/systemd.special.xml b/man/systemd.special.xml index 4588f58999..d1cd81f1d1 100644 --- a/man/systemd.special.xml +++ b/man/systemd.special.xml @@ -1007,7 +1007,7 @@ terminate the user service manager should start this unit. If systemd receives - SIGTERM or SIGINT when running + SIGTERM or SIGINT when running as user service daemon it will start this unit. diff --git a/man/systemd.swap.xml b/man/systemd.swap.xml index 8268e6164d..9a3905a927 100644 --- a/man/systemd.swap.xml +++ b/man/systemd.swap.xml @@ -176,8 +176,8 @@ will be considered failed and be shut down again. All commands still running will be terminated forcibly via - SIGTERM, and after another delay of - this time with SIGKILL. (See + SIGTERM, and after another delay of + this time with SIGKILL. (See in systemd.kill5.) Takes a unit-less value in seconds, or diff --git a/man/systemd.time.xml b/man/systemd.time.xml index 79ebdc5dfc..4f6dd0f086 100644 --- a/man/systemd.time.xml +++ b/man/systemd.time.xml @@ -214,23 +214,24 @@ specified, it should consist of one or more English language weekday names, either in the abbreviated (Wed) or non-abbreviated (Wednesday) form (case does - not matter), separated by commas. Specifying two weekdays - separated by "-" refers to a range of continuous - weekdays. "," and "-" may be combined freely. + not matter), separated by commas. Specifying two + weekdays separated by - refers to a + range of continuous weekdays. , and + - may be combined freely. In the date and time specifications, any - component may be specified as "*" in which case any - value will match. Alternatively, each component can be - specified as list of values separated by - commas. Values may also be suffixed with "/" and a - repetition value, which indicates that the value and - all values plus multiples of the repetition value are - matched. + component may be specified as * in + which case any value will match. Alternatively, each + component can be specified as list of values separated + by commas. Values may also be suffixed with + / and a repetition value, which + indicates that the value and all values plus multiples + of the repetition value are matched. Either time or date specification may be omitted, in which case the current day and 00:00:00 is implied, respectively. If the second component is not - specified ":00" is assumed. + specified :00 is assumed. Timezone names may not be specified. diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index 552c747695..1fd609dc85 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -214,9 +214,9 @@ systemd looks for a unit configuration file it will first search for the literal unit name in the filesystem. If that yields no success and the unit - name contains an @ character, systemd will look for a + name contains an @ character, systemd will look for a unit template that shares the same name but with the - instance string (i.e. the part between the @ character + instance string (i.e. the part between the @ character and the suffix) removed. Example: if a service getty@tty3.service is requested and no file by that name is found, systemd will look @@ -1198,7 +1198,7 @@ %i Instance name - For instantiated units: this is the string between the @ character and the suffix. + For instantiated units: this is the string between the @ character and the suffix. %I diff --git a/man/systemd.xml b/man/systemd.xml index 5f941e5f94..b4b4845305 100644 --- a/man/systemd.xml +++ b/man/systemd.xml @@ -643,7 +643,7 @@ systemd user managers treat this signal the same way as - SIGTERM. + SIGTERM. diff --git a/man/timedatectl.xml b/man/timedatectl.xml index 77af2ad460..16ee3df4be 100644 --- a/man/timedatectl.xml +++ b/man/timedatectl.xml @@ -111,7 +111,7 @@ Execute the operation remotely. Specify a hostname, or - username and hostname separated by @, + username and hostname separated by @, to connect to. This will use SSH to talk to a remote system. -- cgit v1.2.1 From e79f68d11dcf4f7470fe21c219009c81e6433cf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 29 Jun 2013 13:11:44 -0400 Subject: journald: drop (deleted) from _EXE= fields The kernel adds those when the file is deleted, but we don't really care if the file is still there or not. The downside is that if the filename ends in ' (deleted)', this part of the filename will be removed. Too bad. --- src/shared/util.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/shared/util.c b/src/shared/util.c index 04811ff26b..ceee6f2c90 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -729,6 +729,8 @@ int is_kernel_thread(pid_t pid) { int get_process_exe(pid_t pid, char **name) { const char *p; + char *d; + int r; assert(pid >= 0); assert(name); @@ -738,7 +740,15 @@ int get_process_exe(pid_t pid, char **name) { else p = procfs_file_alloca(pid, "exe"); - return readlink_malloc(p, name); + r = readlink_malloc(p, name); + if (r < 0) + return r; + + d = endswith(*name, " (deleted)"); + if (d) + *d = '\0'; + + return 0; } static int get_process_id(pid_t pid, const char *field, uid_t *uid) { -- cgit v1.2.1 From e9c1ea9de87d4d508ac38ce87a2fa56e7529a91a Mon Sep 17 00:00:00 2001 From: "Jason St. John" Date: Tue, 2 Jul 2013 13:24:48 +0200 Subject: replace tabs with spaces in various files The affected files in this patch had inconsistent use of tabs vs. spaces for indentation, and this patch eliminates the stray tabs. Also, the opening brace of sigchld_hdl() in activate.c was moved so the opening braces are consistent throughout the file. --- NEWS | 2 +- m4/attributes.m4 | 20 ++++++++++---------- man/systemd-coredumpctl.xml | 4 ++-- src/activate/activate.c | 9 ++++----- src/core/execute.c | 6 +++--- src/shared/missing.h | 2 +- src/systemctl/systemctl.c | 2 +- 7 files changed, 22 insertions(+), 23 deletions(-) diff --git a/NEWS b/NEWS index 6cfe0dfc59..1b3bc2b65b 100644 --- a/NEWS +++ b/NEWS @@ -1798,7 +1798,7 @@ CHANGES WITH 41: understood to set system wide environment variables dynamically at boot. - * We now limit the set of capabilities of systemd-journald. + * We now limit the set of capabilities of systemd-journald. * We now set SIGPIPE to ignore by default, since it only is useful in shell pipelines, and has little use in general diff --git a/m4/attributes.m4 b/m4/attributes.m4 index f0bcf24211..7e080da65d 100644 --- a/m4/attributes.m4 +++ b/m4/attributes.m4 @@ -40,12 +40,12 @@ dnl CC_CHECK_FLAG_APPEND([WHERE-TO-APPEND], [ENV-VAR], [FLAG]) AC_DEFUN([CC_CHECK_FLAG_APPEND], [ AC_CACHE_CHECK([if $CC supports flag $3 in envvar $2], AS_TR_SH([cc_cv_$2_$3]), - [eval "AS_TR_SH([cc_save_$2])='${$2}'" - eval "AS_TR_SH([$2])='-Werror $3'" - AC_COMPILE_IFELSE([AC_LANG_SOURCE([int a = 0; int main(void) { return a; } ])], + [eval "AS_TR_SH([cc_save_$2])='${$2}'" + eval "AS_TR_SH([$2])='-Werror $3'" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([int a = 0; int main(void) { return a; } ])], [eval "AS_TR_SH([cc_cv_$2_$3])='yes'"], [eval "AS_TR_SH([cc_cv_$2_$3])='no'"]) - eval "AS_TR_SH([$2])='$cc_save_$2'"]) + eval "AS_TR_SH([$2])='$cc_save_$2'"]) AS_IF([eval test x$]AS_TR_SH([cc_cv_$2_$3])[ = xyes], [eval "$1='${$1} $3'"]) @@ -92,10 +92,10 @@ AC_DEFUN([CC_NOUNDEFINED], [ dnl for a much more readable commandline, so that people can understand what dnl it does without going to look for what the heck -z defs does. for possible_flags in "-Wl,--no-undefined" "-Wl,-z,defs"; do - CC_CHECK_LDFLAGS([$possible_flags], [LDFLAGS_NOUNDEFINED="$possible_flags"]) - break + CC_CHECK_LDFLAGS([$possible_flags], [LDFLAGS_NOUNDEFINED="$possible_flags"]) + break done - ;; + ;; esac AC_SUBST([LDFLAGS_NOUNDEFINED]) @@ -231,8 +231,8 @@ AC_DEFUN([CC_FLAG_VISIBILITY], [ [cc_flag_visibility_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $cc_cv_werror" CC_CHECK_CFLAGS_SILENT([-fvisibility=hidden], - cc_cv_flag_visibility='yes', - cc_cv_flag_visibility='no') + cc_cv_flag_visibility='yes', + cc_cv_flag_visibility='no') CFLAGS="$cc_flag_visibility_save_CFLAGS"]) AS_IF([test "x$cc_cv_flag_visibility" = "xyes"], @@ -252,7 +252,7 @@ AC_DEFUN([CC_FUNC_EXPECT], [ [int some_function() { int a = 3; return (int)__builtin_expect(a, 3); - }])], + }])], [cc_cv_func_expect=yes], [cc_cv_func_expect=no]) CFLAGS="$ac_save_CFLAGS" diff --git a/man/systemd-coredumpctl.xml b/man/systemd-coredumpctl.xml index 02b688606c..9ccb67d12d 100644 --- a/man/systemd-coredumpctl.xml +++ b/man/systemd-coredumpctl.xml @@ -202,8 +202,8 @@ Exit status On success 0 is returned, a non-zero failure code otherwise. Not finding any matching coredumps is treated - as failure. - + as failure. + diff --git a/src/activate/activate.c b/src/activate/activate.c index 87526d47cc..83d25b13af 100644 --- a/src/activate/activate.c +++ b/src/activate/activate.c @@ -290,16 +290,15 @@ static int do_accept(const char* name, char **argv, char **envp, int fd) { } /* SIGCHLD handler. */ -static void sigchld_hdl(int sig, siginfo_t *t, void *data) -{ +static void sigchld_hdl(int sig, siginfo_t *t, void *data) { log_info("Child %d died with code %d", t->si_pid, t->si_status); - /* Wait for a dead child. */ - waitpid(t->si_pid, NULL, 0); + /* Wait for a dead child. */ + waitpid(t->si_pid, NULL, 0); } static int install_chld_handler(void) { int r; - struct sigaction act; + struct sigaction act; zero(act); act.sa_flags = SA_SIGINFO; act.sa_sigaction = sigchld_hdl; diff --git a/src/core/execute.c b/src/core/execute.c index 5e342f8d47..cbeb0caf26 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -1727,10 +1727,10 @@ int exec_context_load_environment(const ExecContext *c, char ***l) { strv_free(r); return k; - } + } /* Log invalid environment variables with filename */ - if (p) - p = strv_env_clean_log(p, pglob.gl_pathv[n]); + if (p) + p = strv_env_clean_log(p, pglob.gl_pathv[n]); if (r == NULL) r = p; diff --git a/src/shared/missing.h b/src/shared/missing.h index 96e6d63101..24a8392b22 100644 --- a/src/shared/missing.h +++ b/src/shared/missing.h @@ -139,7 +139,7 @@ static inline int fanotify_init(unsigned int flags, unsigned int event_f_flags) static inline int fanotify_mark(int fanotify_fd, unsigned int flags, uint64_t mask, int dfd, const char *pathname) { #if defined _MIPS_SIM && _MIPS_SIM == _MIPS_SIM_ABI32 || defined __powerpc__ && !defined __powerpc64__ \ - || defined __arm__ && !defined __aarch64__ + || defined __arm__ && !defined __aarch64__ union { uint64_t _64; uint32_t _32[2]; diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 7ecd8d2cfb..7436d4e875 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -3444,7 +3444,7 @@ static int show_one(const char *verb, DBusConnection *bus, const char *path, boo r = 1; else r = 3; - } + } while ((p = info.exec)) { LIST_REMOVE(ExecStatusInfo, exec, info.exec, p); -- cgit v1.2.1 From 460c589a92ae58c5cfb4d36dba073220ccdc565f Mon Sep 17 00:00:00 2001 From: Fedora systemd team Date: Thu, 27 Jun 2013 16:30:12 +0200 Subject: build-sys: install rpm macros file to /usr/lib/rpm/macros.d RPM macros are moved from /etc to /usr, in the sprit of moving in the direction of empty /etc. RPM gained support for the new directory recently, in v. 4.10.90: https://bugzilla.redhat.com/show_bug.cgi?id=846679. --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 02cd7e2d25..ca4513bdb4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -65,7 +65,7 @@ pkgconfigdatadir=$(datadir)/pkgconfig pkgconfiglibdir=$(libdir)/pkgconfig polkitpolicydir=$(datadir)/polkit-1/actions bashcompletiondir=@bashcompletiondir@ -rpmmacrosdir=$(sysconfdir)/rpm +rpmmacrosdir=$(prefix)/lib/rpm/macros.d sysvinitdir=$(SYSTEM_SYSVINIT_PATH) sysvrcnddir=$(SYSTEM_SYSVRCND_PATH) varlogdir=$(localstatedir)/log -- cgit v1.2.1 From a0f9c810faa022c264bf534ab9495e0e9f617962 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 27 Jun 2013 21:34:24 +0200 Subject: build-sys: work around automake issue with files with a leading '-' We should probably work around it, until it is sorted out. http://debbugs.gnu.org/cgi/bugreport.cgi?bug=14728 --- Makefile.am | 13 ++++++++++++- units/-.slice | 12 ------------ units/x-.slice | 12 ++++++++++++ 3 files changed, 24 insertions(+), 13 deletions(-) delete mode 100644 units/-.slice create mode 100644 units/x-.slice diff --git a/Makefile.am b/Makefile.am index ca4513bdb4..0dd384e38e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -380,7 +380,7 @@ dist_systemunit_DATA = \ units/swap.target \ units/slices.target \ units/system.slice \ - units/-.slice \ + units/x-.slice \ units/systemd-initctl.socket \ units/systemd-shutdownd.socket \ units/syslog.socket \ @@ -499,6 +499,17 @@ EXTRA_DIST += \ units/rc-local.service.in \ units/halt-local.service.in +# automake is broken and can't handle files with a dash in front +# http://debbugs.gnu.org/cgi/bugreport.cgi?bug=14728#8 +units-install-hook: + mv $(DESTDIR)$(systemunitdir)/x-.slice $(DESTDIR)/$(systemunitdir)/-.slice + +units-uninstall-hook: + rm -f $(DESTDIR)/$(systemunitdir)/-.slice + +INSTALL_DATA_HOOKS += units-install-hook +UNINSTALL_DATA_HOOKS += units-uninstall-hook + dist_doc_DATA = \ README \ NEWS \ diff --git a/units/-.slice b/units/-.slice deleted file mode 100644 index ac82c35874..0000000000 --- a/units/-.slice +++ /dev/null @@ -1,12 +0,0 @@ -# This file is part of systemd. -# -# systemd is free software; you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or -# (at your option) any later version. - -[Unit] -Description=Root Slice -Documentation=man:systemd.special(7) -DefaultDependencies=no -Before=slices.target diff --git a/units/x-.slice b/units/x-.slice new file mode 100644 index 0000000000..ac82c35874 --- /dev/null +++ b/units/x-.slice @@ -0,0 +1,12 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Root Slice +Documentation=man:systemd.special(7) +DefaultDependencies=no +Before=slices.target -- cgit v1.2.1 From 19fbd6253640bd66e59a688b796a100897d7c4d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 2 Jul 2013 22:55:45 -0400 Subject: build-sys: two files were missing in distcheck One is a typo, the other one doesn't actually exist yet. --- Makefile.am | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Makefile.am b/Makefile.am index 0dd384e38e..b2573199dc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3635,11 +3635,8 @@ dist_dbuspolicy_DATA += \ SYSTEM_UNIT_ALIASES += \ systemd-machined.service dbus-org.freedesktop.machine1.service -polkitpolicy_in_files += \ - src/machine/org.freedesktop.machine1.policy.in - EXTRA_DIST += \ - units/systemd-machine.service.in + units/systemd-machined.service.in endif -- cgit v1.2.1 From 5199cbe4a4cb0f3e4134e8577dda37c05abf7dc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 2 Jul 2013 23:35:20 -0400 Subject: man: describe OBJECT_PID= --- man/systemd.journal-fields.xml | 64 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/man/systemd.journal-fields.xml b/man/systemd.journal-fields.xml index bced51d635..ad03282b1e 100644 --- a/man/systemd.journal-fields.xml +++ b/man/systemd.journal-fields.xml @@ -424,10 +424,15 @@ - Special Journal Fields + Fields to log on behalf of a different program + + Fields in this section are used by programs + to specify that they are logging on behalf of another + program or unit. + Fields used by the systemd-coredump - coredump kernel helper. + coredump kernel helper: @@ -444,6 +449,61 @@ + + Priviledged programs (currently UID 0) may + attach OBJECT_PID= to a + message. This will instruct + systemd-journald to attach + additional fields on behalf of caller: + + + + OBJECT_PID=PID + + PID of the program that this + message pertains to. + + + + + + OBJECT_UID= + OBJECT_GID= + OBJECT_COMM= + OBJECT_EXE= + OBJECT_CMDLINE= + OBJECT_AUDIT_SESSION= + OBJECT_AUDIT_LOGINUID= + OBJECT_SYSTEMD_CGROUP= + OBJECT_SYSTEMD_SESSION= + OBJECT_SYSTEMD_OWNER_UID= + OBJECT_SYSTEMD_UNIT= + OBJECT_SYSTEMD_USER_UNIT= + + Additional fields added automatically + by systemd-journald. + Their meaning is the same as + _UID=, + _GID=, + _COMM=, + _EXE=, + _CMDLINE=, + _AUDIT_SESSION=, + _AUDIT_LOGINUID=, + _SYSTEMD_CGROUP=, + _SYSTEMD_SESSION=, + _SYSTEMD_UNIT=, + _SYSTEMD_USER_UNIT=, and + _SYSTEMD_OWNER_UID= + described above, except that + process PID + is described, instead of the process + which logged the message. + + + + + -- cgit v1.2.1 From 4edcaa21daceef99617e93b957e95607e5370703 Mon Sep 17 00:00:00 2001 From: "Jason St. John" Date: Wed, 3 Jul 2013 13:15:11 +0200 Subject: keymap: improve consistency and general formatting of comments --- keymaps-force-release/samsung-other | 4 ++-- keymaps-force-release/samsung-series-3 | 2 +- keymaps-force-release/samsung-series-9 | 6 +++--- keymaps/acer-aspire_8930 | 4 ++-- keymaps/dell | 20 ++++++++++---------- keymaps/fujitsu-amilo_pro_edition_v3505 | 8 ++++---- keymaps/hewlett-packard | 10 +++++----- keymaps/hewlett-packard-hdx9494nr | 2 +- keymaps/lenovo-ideapad | 2 +- keymaps/lenovo-thinkpad-usb-keyboard-trackpoint | 4 ++-- keymaps/lg-x110 | 22 +++++++++++----------- keymaps/logitech-wave | 20 ++++++++++---------- keymaps/logitech-wave-cordless | 8 ++++---- keymaps/maxdata-pro_7000 | 6 +++--- keymaps/micro-star | 16 ++++++++-------- keymaps/olpc-xo | 12 ++++++------ keymaps/samsung-other | 4 ++-- keymaps/samsung-series-3 | 2 +- keymaps/samsung-series-9 | 6 +++--- keymaps/toshiba-satellite_m30x | 4 ++-- 20 files changed, 81 insertions(+), 81 deletions(-) diff --git a/keymaps-force-release/samsung-other b/keymaps-force-release/samsung-other index c51123a0b6..e9627af882 100644 --- a/keymaps-force-release/samsung-other +++ b/keymaps-force-release/samsung-other @@ -3,8 +3,8 @@ 0x83 # Fn+F2 battery 0x84 # Fn+F5 backlight on/off 0x86 # Fn+F9 WLAN -0x88 # Fn-Up brightness up -0x89 # Fn-Down brightness down +0x88 # Fn+Up brightness up +0x89 # Fn+Down brightness down 0xB3 # Fn+F8 switch power mode (battery/dynamic/performance) 0xF7 # Fn+F10 Touchpad on 0xF9 # Fn+F10 Touchpad off diff --git a/keymaps-force-release/samsung-series-3 b/keymaps-force-release/samsung-series-3 index bfa06e10b7..c26594a4c5 100644 --- a/keymaps-force-release/samsung-series-3 +++ b/keymaps-force-release/samsung-series-3 @@ -1,2 +1,2 @@ 0xCE # Fn+F1 launch control setting -0xD5 # Fn+F12 wifi on/off +0xD5 # Fn+F12 Wi-Fi toggle diff --git a/keymaps-force-release/samsung-series-9 b/keymaps-force-release/samsung-series-9 index 65707effb7..fa6a0b1d18 100644 --- a/keymaps-force-release/samsung-series-9 +++ b/keymaps-force-release/samsung-series-9 @@ -1,6 +1,6 @@ # list of scancodes (hex or decimal), optional comment -0xCE # Fn+F8 keyboard backlit up -0x8D # Fn+F7 keyboard backlit down -0x97 # Fn+F12 wifi on/off +0xCE # Fn+F8 keyboard backlight up +0x8D # Fn+F7 keyboard backlight down +0x97 # Fn+F12 Wi-Fi toggle 0x96 # Fn+F1 performance mode (?) 0xD5 # Fn+F6 battery life extender diff --git a/keymaps/acer-aspire_8930 b/keymaps/acer-aspire_8930 index fb27bfb4f5..8e36cd947c 100644 --- a/keymaps/acer-aspire_8930 +++ b/keymaps/acer-aspire_8930 @@ -1,5 +1,5 @@ -0xCA prog3 # key 'HOLD' on cine dash media console +0xCA prog3 # key 'HOLD' on CineDash Media Console 0x83 rewind 0x89 fastforward -0x92 media # key 'ARCADE' on cine dash media console +0x92 media # key 'ARCADE' on CineDash Media Console 0x9E back diff --git a/keymaps/dell b/keymaps/dell index 4f907b3eef..55015e352a 100644 --- a/keymaps/dell +++ b/keymaps/dell @@ -2,28 +2,28 @@ 0x82 stopcd # Stop 0x83 previoussong # Previous song 0x84 nextsong # Next song -0x85 brightnessdown # Fn+Down arrow Brightness Down -0x86 brightnessup # Fn+Up arrow Brightness Up +0x85 brightnessdown # Fn+Down Brightness Down +0x86 brightnessup # Fn+Up Brightness Up 0x87 battery # Fn+F3 battery icon 0x88 unknown # Fn+F2 Turn On/Off Wireless - handled in hardware 0x89 ejectclosecd # Fn+F10 Eject CD 0x8A suspend # Fn+F1 hibernate 0x8B switchvideomode # Fn+F8 CRT/LCD (high keycode: "displaytoggle") -0x8C f23 # Fn+Right arrow Auto Brightness +0x8C f23 # Fn+Right Auto Brightness 0x8F switchvideomode # Fn+F7 aspect ratio 0x90 previoussong # Front panel previous song -0x91 prog1 # Wifi Catcher (DELL Specific) +0x91 prog1 # Wi-Fi Catcher (Dell-specific) 0x92 media # MediaDirect button (house icon) -0x93 f23 # FIXME Fn+Left arrow Auto Brightness -0x95 camera # Shutter button Takes a picture if optional camera available +0x93 f23 # FIXME Fn+Left Auto Brightness +0x95 camera # Shutter button - Takes a picture if optional camera available 0x97 email # Tablet email button -0x98 f21 # FIXME: Tablet screen rotatation +0x98 f21 # FIXME: Tablet screen rotation 0x99 nextsong # Front panel next song 0x9A setup # Tablet tools button -0x9B switchvideomode # Display Toggle button -0x9E f21 #touchpad toggle +0x9B switchvideomode # Display toggle button +0x9E f21 # Touchpad toggle 0xA2 playpause # Front panel play/pause 0xA4 stopcd # Front panel stop 0xED media # MediaDirect button 0xD8 screenlock # FIXME: Tablet lock button -0xD9 f21 # touchpad toggle +0xD9 f21 # Touchpad toggle diff --git a/keymaps/fujitsu-amilo_pro_edition_v3505 b/keymaps/fujitsu-amilo_pro_edition_v3505 index d2e38cbb23..74bae2f144 100644 --- a/keymaps/fujitsu-amilo_pro_edition_v3505 +++ b/keymaps/fujitsu-amilo_pro_edition_v3505 @@ -1,4 +1,4 @@ -0xA5 help # Fn-F1 -0xA9 switchvideomode # Fn-F3 -0xD9 brightnessdown # Fn-F8 -0xE0 brightnessup # Fn-F9 +0xA5 help # Fn+F1 +0xA9 switchvideomode # Fn+F3 +0xD9 brightnessdown # Fn+F8 +0xE0 brightnessup # Fn+F9 diff --git a/keymaps/hewlett-packard b/keymaps/hewlett-packard index 4461fa2ce5..4ab21947e2 100644 --- a/keymaps/hewlett-packard +++ b/keymaps/hewlett-packard @@ -1,12 +1,12 @@ 0x81 fn_esc -0x89 battery # FnF8 -0x8A screenlock # FnF6 +0x89 battery # Fn+F8 +0x8A screenlock # Fn+F6 0x8B camera 0x8C media # music 0x8E dvd 0xB1 help 0xB3 f23 # FIXME: Auto brightness 0xD7 wlan -0x92 brightnessdown # FnF7 (FnF9 on 6730b) -0x97 brightnessup # FnF8 (FnF10 on 6730b) -0xEE switchvideomode # FnF4 +0x92 brightnessdown # Fn+F7 (Fn+F9 on 6730b) +0x97 brightnessup # Fn+F8 (Fn+F10 on 6730b) +0xEE switchvideomode # Fn+F4 diff --git a/keymaps/hewlett-packard-hdx9494nr b/keymaps/hewlett-packard-hdx9494nr index 92217879c8..39e8b4c9f7 100644 --- a/keymaps/hewlett-packard-hdx9494nr +++ b/keymaps/hewlett-packard-hdx9494nr @@ -1,3 +1,3 @@ -0xB2 www # FnF3 +0xB2 www # Fn+F3 0xD8 f23 # touchpad off 0xD9 f22 # touchpad on diff --git a/keymaps/lenovo-ideapad b/keymaps/lenovo-ideapad index fc339839f2..0de16466b4 100644 --- a/keymaps/lenovo-ideapad +++ b/keymaps/lenovo-ideapad @@ -4,5 +4,5 @@ 0xB9 brightnessup # does nothing in BIOS 0xBA brightnessdown # does nothing in BIOS 0xF1 camera # BIOS toggles camera power -0xf2 f21 # touchpad toggle (key alternately emits f2 and f3) +0xf2 f21 # touchpad toggle (key alternately emits F2 and F3) 0xf3 f21 diff --git a/keymaps/lenovo-thinkpad-usb-keyboard-trackpoint b/keymaps/lenovo-thinkpad-usb-keyboard-trackpoint index d87549e445..ac829d8f7f 100644 --- a/keymaps/lenovo-thinkpad-usb-keyboard-trackpoint +++ b/keymaps/lenovo-thinkpad-usb-keyboard-trackpoint @@ -2,12 +2,12 @@ 0x90013 battery # Fn+F3 0x90014 wlan # Fn+F5 0x90016 switchvideomode # Fn+F7 -0x90017 f21 # Fn+F8 touchpadtoggle +0x90017 f21 # Fn+F8 touchpad toggle 0x90019 suspend # Fn+F12 0x9001A brightnessup # Fn+Home 0x9001B brightnessdown # Fn+End 0x9001D zoom # Fn+Space -0x90011 prog1 # Thinkvantage button +0x90011 prog1 # ThinkVantage button 0x90015 camera # Fn+F6 headset/camera VoIP key ?? 0x90010 f20 # Microphone mute button; should be micmute, but see https://mail.gnome.org/archives/commits-list/2013-January/msg05822.html diff --git a/keymaps/lg-x110 b/keymaps/lg-x110 index ba08cba3fe..57f9156c62 100644 --- a/keymaps/lg-x110 +++ b/keymaps/lg-x110 @@ -1,12 +1,12 @@ -0xA0 mute # Fn-F9 -0xAE volumedown # Fn-Left -0xAF search # Fn-F3 -0xB0 volumeup # Fn-Right -0xB1 battery # Fn-F10 Info -0xB3 suspend # Fn-F12 -0xDF sleep # Fn-F4 +0xA0 mute # Fn+F9 +0xAE volumedown # Fn+Left +0xAF search # Fn+F3 +0xB0 volumeup # Fn+Right +0xB1 battery # Fn+F10 Info +0xB3 suspend # Fn+F12 +0xDF sleep # Fn+F4 # 0xE2 bluetooth # satellite dish2 -0xE4 f21 # Fn-F5 Touchpad disable -0xF6 wlan # Fn-F6 -0xF7 reserved # brightnessdown # Fn-Down -0xF8 reserved # brightnessup # Fn-Up +0xE4 f21 # Fn+F5 Touchpad toggle +0xF6 wlan # Fn+F6 +0xF7 reserved # Fn+Down brightnessdown +0xF8 reserved # Fn+Up brightnessup diff --git a/keymaps/logitech-wave b/keymaps/logitech-wave index caa5d5d310..724694e067 100644 --- a/keymaps/logitech-wave +++ b/keymaps/logitech-wave @@ -4,13 +4,13 @@ 0x9003D prog1 #gadget 0x90005 camera #camera 0x90018 media #media center -0x90041 wordprocessor #fn+f1 (word) -0x90042 spreadsheet #fn+f2 (excel) -0x90043 calendar #fn+f3 (calendar) -0x90044 prog2 #fn+f4 (program a) -0x90045 prog3 #fn+f5 (program b) -0x90046 prog4 #fn+f6 (program c) -0x90048 messenger #fn+f8 (msn messenger) -0x9002D find #fn+f10 (search www) -0x9004B search #fn+f11 (search pc) -0x9004C ejectclosecd #fn+f12 (eject) +0x90041 wordprocessor #Fn+F1 (Word) +0x90042 spreadsheet #Fn+F2 (Excel) +0x90043 calendar #Fn+F3 (calendar) +0x90044 prog2 #Fn+F4 (program a) +0x90045 prog3 #Fn+F5 (program b) +0x90046 prog4 #Fn+F6 (program c) +0x90048 messenger #Fn+F8 (MSN messenger) +0x9002D find #Fn+F10 (search www) +0x9004B search #Fn+F11 (search PC) +0x9004C ejectclosecd #Fn+F12 (eject) diff --git a/keymaps/logitech-wave-cordless b/keymaps/logitech-wave-cordless index a10dad5e4d..83bba1daf5 100644 --- a/keymaps/logitech-wave-cordless +++ b/keymaps/logitech-wave-cordless @@ -7,9 +7,9 @@ 0xC1041 wordprocessor 0xC1042 spreadsheet 0xC1043 calendar -0xC1044 prog2 #fn+f4 (program a) -0xC1045 prog3 #fn+f5 (program b) -0xC1046 prog4 #fn+f6 (program c) +0xC1044 prog2 #Fn+F4 (program a) +0xC1045 prog3 #Fn+F5 (program b) +0xC1046 prog4 #Fn+F6 (program c) 0xC1048 messenger -0xC104A find #fn+f10 (search www) +0xC104A find #Fn+F10 (search www) 0xC104C ejectclosecd diff --git a/keymaps/maxdata-pro_7000 b/keymaps/maxdata-pro_7000 index c0e4f77af4..87c94a3411 100644 --- a/keymaps/maxdata-pro_7000 +++ b/keymaps/maxdata-pro_7000 @@ -1,9 +1,9 @@ 0x97 prog2 0x9F prog1 -0xA0 mute # Fn-F5 +0xA0 mute # Fn+F5 0x82 www 0xEC email -0xAE volumedown # Fn-Down -0xB0 volumeup # Fn-Up +0xAE volumedown # Fn+Down +0xB0 volumeup # Fn+Up 0xDF suspend # Fn+F2 0xF5 help diff --git a/keymaps/micro-star b/keymaps/micro-star index 4a438698ed..40a8decbe2 100644 --- a/keymaps/micro-star +++ b/keymaps/micro-star @@ -1,13 +1,13 @@ -0xA0 mute # Fn-F9 -0xAE volumedown # Fn-F7 -0xB0 volumeup # Fn-F8 +0xA0 mute # Fn+F9 +0xAE volumedown # Fn+F7 +0xB0 volumeup # Fn+F8 0xB2 www # e button -0xDF sleep # Fn-F12 +0xDF sleep # Fn+F12 0xE2 bluetooth # satellite dish2 -0xE4 f21 # Fn-F3 Touchpad disable +0xE4 f21 # Fn+F3 Touchpad disable 0xEC email # envelope button -0xEE camera # Fn-F6 camera disable +0xEE camera # Fn+F6 camera disable 0xF6 wlan # satellite dish1 -0xF7 brightnessdown # Fn-F4 -0xF8 brightnessup # Fn-F5 +0xF7 brightnessdown # Fn+F4 +0xF8 brightnessup # Fn+F5 0xF9 search diff --git a/keymaps/olpc-xo b/keymaps/olpc-xo index 34434a121d..78dad553a8 100644 --- a/keymaps/olpc-xo +++ b/keymaps/olpc-xo @@ -1,7 +1,7 @@ 0x59 fn 0x81 fn_esc 0xF9 camera -0xF8 sound # Fn-CAMERA = Mic +0xF8 sound # Fn+CAMERA = Mic # Function key mappings, as per @@ -14,7 +14,7 @@ 0x57 volumedown 0x58 volumeup -# fn-modified fkeys all produce the unmodified version of the key. +# Fn-modified fkeys all produce the unmodified version of the key. 0xBB f1 0xBC f2 0xBD f3 @@ -41,11 +41,11 @@ 0xEF f21 0xEE chat -0xE4 chat # Just mapping Fn-Chat to Chat for now +0xE4 chat # Just mapping Fn+Chat to Chat for now 0xDD menu # Frame -0xDA prog1 # Fn-Frame +0xDA prog1 # Fn+Frame -# The FN of some keys is other keys +# The Fn of some keys is other keys 0xD3 delete 0xD2 insert 0xC9 pageup @@ -60,7 +60,7 @@ 0xDB leftmeta # left grab 0xDC rightmeta # right grab 0x85 rightmeta # Right grab releases on a different scancode -0xD6 kbdillumtoggle # Fn-space +0xD6 kbdillumtoggle # Fn+space 0x69 switchvideomode # Brightness key # Game keys diff --git a/keymaps/samsung-other b/keymaps/samsung-other index 3ac0c2f10c..536a13d9cd 100644 --- a/keymaps/samsung-other +++ b/keymaps/samsung-other @@ -5,8 +5,8 @@ 0x83 battery # Fn+F2 0x84 prog1 # Fn+F5 backlight on/off 0x86 wlan # Fn+F9 -0x88 brightnessup # Fn-Up -0x89 brightnessdown # Fn-Down +0x88 brightnessup # Fn+Up +0x89 brightnessdown # Fn+Down 0xB1 prog2 # Fn+F7 run Samsung Magic Doctor (keypressed event is generated twice) 0xB3 prog3 # Fn+F8 switch power mode (battery/dynamic/performance) 0xB4 wlan # Fn+F9 (X60P) diff --git a/keymaps/samsung-series-3 b/keymaps/samsung-series-3 index 52b2d64b44..9a16fbce27 100644 --- a/keymaps/samsung-series-3 +++ b/keymaps/samsung-series-3 @@ -1,3 +1,3 @@ 0xCE prog1 # Fn+F1 launch control setting 0xB3 prog2 # Fn+F11 performance mode -0xD5 wlan # Fn+F12 wifi on/off +0xD5 wlan # Fn+F12 Wi-Fi toggle diff --git a/keymaps/samsung-series-9 b/keymaps/samsung-series-9 index 3b65735fa0..c0712f02a0 100644 --- a/keymaps/samsung-series-9 +++ b/keymaps/samsung-series-9 @@ -1,5 +1,5 @@ -0x96 kbdillumup # Fn+F8 keyboard backlit up -0x97 kbdillumdown # Fn+F7 keyboard backlit down -0xD5 wlan # Fn+F12 wifi on/off +0x96 kbdillumup # Fn+F8 keyboard backlight up +0x97 kbdillumdown # Fn+F7 keyboard backlight down +0xD5 wlan # Fn+F12 Wi-Fi toggle 0xCE prog1 # Fn+F1 performance mode 0x8D prog2 # Fn+F6 battery life extender diff --git a/keymaps/toshiba-satellite_m30x b/keymaps/toshiba-satellite_m30x index ae8e34941b..26e0bbd939 100644 --- a/keymaps/toshiba-satellite_m30x +++ b/keymaps/toshiba-satellite_m30x @@ -2,5 +2,5 @@ 0xd9 brightnessup 0xee screenlock 0x93 media -0x9e f22 #touchpad_enable -0x9f f23 #touchpad_disable +0x9e f22 # touchpad enable +0x9f f23 # touchpad disable -- cgit v1.2.1 From 337fa161c40f26cb7c33847d666556d28905b6a9 Mon Sep 17 00:00:00 2001 From: "Jason St. John" Date: Wed, 3 Jul 2013 13:15:12 +0200 Subject: keymap: horizontally align comments in the same column --- keymaps-force-release/common-volume-keys | 6 +-- keymaps-force-release/samsung-series-3 | 4 +- keymaps/acer | 34 ++++++++-------- keymaps/acer-aspire_5720 | 6 +-- keymaps/dell | 52 ++++++++++++------------- keymaps/dell-latitude-xt2 | 8 ++-- keymaps/everex-xt5000 | 4 +- keymaps/fujitsu-amilo_li_2732 | 4 +- keymaps/fujitsu-amilo_pro_edition_v3505 | 6 +-- keymaps/fujitsu-amilo_pro_v3205 | 2 +- keymaps/hewlett-packard | 12 +++--- keymaps/hewlett-packard-pavilion | 6 +-- keymaps/hewlett-packard_elitebook-8460p | 6 +-- keymaps/lenovo-3000 | 8 ++-- keymaps/lenovo-thinkpad-usb-keyboard-trackpoint | 24 ++++++------ keymaps/lenovo-thinkpad_x200_tablet | 6 +-- keymaps/lenovo-thinkpad_x6_tablet | 16 ++++---- keymaps/lg-x110 | 22 +++++------ keymaps/logitech-usb | 12 +++--- keymaps/logitech-wave | 32 +++++++-------- keymaps/logitech-wave-cordless | 8 ++-- keymaps/maxdata-pro_7000 | 6 +-- keymaps/medion-fid2060 | 4 +- keymaps/medionnb-a555 | 8 ++-- keymaps/micro-star | 24 ++++++------ keymaps/module-ibm | 24 ++++++------ keymaps/module-lenovo | 28 ++++++------- keymaps/module-sony | 16 ++++---- keymaps/module-sony-vgn | 8 ++-- keymaps/module-sony-vpc | 6 +-- keymaps/olpc-xo | 16 ++++---- keymaps/onkyo | 26 ++++++------- keymaps/samsung-other | 24 ++++++------ keymaps/samsung-series-3 | 6 +-- 34 files changed, 237 insertions(+), 237 deletions(-) diff --git a/keymaps-force-release/common-volume-keys b/keymaps-force-release/common-volume-keys index 3a7654d735..e384a3b8f2 100644 --- a/keymaps-force-release/common-volume-keys +++ b/keymaps-force-release/common-volume-keys @@ -1,3 +1,3 @@ -0xa0 #mute -0xae #volume down -0xb0 #volume up +0xa0 # mute +0xae # volume down +0xb0 # volume up diff --git a/keymaps-force-release/samsung-series-3 b/keymaps-force-release/samsung-series-3 index c26594a4c5..63707508aa 100644 --- a/keymaps-force-release/samsung-series-3 +++ b/keymaps-force-release/samsung-series-3 @@ -1,2 +1,2 @@ -0xCE # Fn+F1 launch control setting -0xD5 # Fn+F12 Wi-Fi toggle +0xCE # Fn+F1 launch control setting +0xD5 # Fn+F12 Wi-Fi toggle diff --git a/keymaps/acer b/keymaps/acer index 4e7c297dea..a0c6fd278a 100644 --- a/keymaps/acer +++ b/keymaps/acer @@ -1,22 +1,22 @@ -0xA5 help # Fn+F1 -0xA6 setup # Fn+F2 Acer eSettings -0xA7 battery # Fn+F3 Power Management +0xA5 help # Fn+F1 +0xA6 setup # Fn+F2 Acer eSettings +0xA7 battery # Fn+F3 Power Management 0xA9 switchvideomode # Fn+F5 0xB3 euro 0xB4 dollar -0xCE brightnessup # Fn+Right -0xD4 bluetooth # (toggle) off-to-on -0xD5 wlan # (toggle) on-to-off -0xD6 wlan # (toggle) off-to-on -0xD7 bluetooth # (toggle) on-to-off -0xD8 bluetooth # (toggle) off-to-on -0xD9 brightnessup # Fn+Right -0xEE brightnessup # Fn+Right -0xEF brightnessdown # Fn+Left -0xF1 f22 # Fn+F7 Touchpad toggle (off-to-on) -0xF2 f23 # Fn+F7 Touchpad toggle (on-to-off) -0xF3 prog2 # "P2" programmable button -0xF4 prog1 # "P1" programmable button +0xCE brightnessup # Fn+Right +0xD4 bluetooth # (toggle) off-to-on +0xD5 wlan # (toggle) on-to-off +0xD6 wlan # (toggle) off-to-on +0xD7 bluetooth # (toggle) on-to-off +0xD8 bluetooth # (toggle) off-to-on +0xD9 brightnessup # Fn+Right +0xEE brightnessup # Fn+Right +0xEF brightnessdown # Fn+Left +0xF1 f22 # Fn+F7 Touchpad toggle (off-to-on) +0xF2 f23 # Fn+F7 Touchpad toggle (on-to-off) +0xF3 prog2 # "P2" programmable button +0xF4 prog1 # "P1" programmable button 0xF5 presentation 0xF8 fn -0xF9 f23 # Launch NTI shadow +0xF9 f23 # Launch NTI shadow diff --git a/keymaps/acer-aspire_5720 b/keymaps/acer-aspire_5720 index 3ff9de3f32..b9381f86c6 100644 --- a/keymaps/acer-aspire_5720 +++ b/keymaps/acer-aspire_5720 @@ -1,5 +1,5 @@ 0x84 bluetooth # sent when bluetooth module missing, and key pressed -0x92 media # acer arcade -0xD4 bluetooth # bluetooth on -0xD9 bluetooth # bluetooth off +0x92 media # Acer arcade +0xD4 bluetooth # Bluetooth on +0xD9 bluetooth # Bluetooth off 0xF4 prog3 # e-key diff --git a/keymaps/dell b/keymaps/dell index 55015e352a..cef41d3e7b 100644 --- a/keymaps/dell +++ b/keymaps/dell @@ -1,29 +1,29 @@ -0x81 playpause # Play/Pause -0x82 stopcd # Stop -0x83 previoussong # Previous song -0x84 nextsong # Next song -0x85 brightnessdown # Fn+Down Brightness Down -0x86 brightnessup # Fn+Up Brightness Up -0x87 battery # Fn+F3 battery icon -0x88 unknown # Fn+F2 Turn On/Off Wireless - handled in hardware -0x89 ejectclosecd # Fn+F10 Eject CD -0x8A suspend # Fn+F1 hibernate +0x81 playpause # Play/Pause +0x82 stopcd # Stop +0x83 previoussong # Previous song +0x84 nextsong # Next song +0x85 brightnessdown # Fn+Down Brightness Down +0x86 brightnessup # Fn+Up Brightness Up +0x87 battery # Fn+F3 battery icon +0x88 unknown # Fn+F2 Turn On/Off Wireless - handled in hardware +0x89 ejectclosecd # Fn+F10 Eject CD +0x8A suspend # Fn+F1 hibernate 0x8B switchvideomode # Fn+F8 CRT/LCD (high keycode: "displaytoggle") -0x8C f23 # Fn+Right Auto Brightness +0x8C f23 # Fn+Right Auto Brightness 0x8F switchvideomode # Fn+F7 aspect ratio -0x90 previoussong # Front panel previous song -0x91 prog1 # Wi-Fi Catcher (Dell-specific) -0x92 media # MediaDirect button (house icon) -0x93 f23 # FIXME Fn+Left Auto Brightness -0x95 camera # Shutter button - Takes a picture if optional camera available -0x97 email # Tablet email button -0x98 f21 # FIXME: Tablet screen rotation -0x99 nextsong # Front panel next song -0x9A setup # Tablet tools button +0x90 previoussong # Front panel previous song +0x91 prog1 # Wi-Fi Catcher (Dell-specific) +0x92 media # MediaDirect button (house icon) +0x93 f23 # FIXME Fn+Left Auto Brightness +0x95 camera # Shutter button - Takes a picture if optional camera available +0x97 email # Tablet email button +0x98 f21 # FIXME: Tablet screen rotation +0x99 nextsong # Front panel next song +0x9A setup # Tablet tools button 0x9B switchvideomode # Display toggle button -0x9E f21 # Touchpad toggle -0xA2 playpause # Front panel play/pause -0xA4 stopcd # Front panel stop -0xED media # MediaDirect button -0xD8 screenlock # FIXME: Tablet lock button -0xD9 f21 # Touchpad toggle +0x9E f21 # Touchpad toggle +0xA2 playpause # Front panel play/pause +0xA4 stopcd # Front panel stop +0xED media # MediaDirect button +0xD8 screenlock # FIXME: Tablet lock button +0xD9 f21 # Touchpad toggle diff --git a/keymaps/dell-latitude-xt2 b/keymaps/dell-latitude-xt2 index 39872f559d..59ff6ff264 100644 --- a/keymaps/dell-latitude-xt2 +++ b/keymaps/dell-latitude-xt2 @@ -1,4 +1,4 @@ -0x9B up # tablet rocker up -0x9E enter # tablet rocker press -0x9F back # tablet back -0xA3 down # tablet rocker down +0x9B up # tablet rocker up +0x9E enter # tablet rocker press +0x9F back # tablet back +0xA3 down # tablet rocker down diff --git a/keymaps/everex-xt5000 b/keymaps/everex-xt5000 index 4823a832f5..bd89a23d3e 100644 --- a/keymaps/everex-xt5000 +++ b/keymaps/everex-xt5000 @@ -1,6 +1,6 @@ 0x5C media -0x65 f21 # Fn+F5 Touchpad toggle -0x67 prog3 # Fan Speed Control button +0x65 f21 # Fn+F5 Touchpad toggle +0x67 prog3 # Fan speed control button 0x6F brightnessup 0x7F brightnessdown 0xB2 www diff --git a/keymaps/fujitsu-amilo_li_2732 b/keymaps/fujitsu-amilo_li_2732 index 9b8b36a170..c9b3198d1b 100644 --- a/keymaps/fujitsu-amilo_li_2732 +++ b/keymaps/fujitsu-amilo_li_2732 @@ -1,3 +1,3 @@ -0xD9 brightnessdown # Fn+F8 brightness down -0xEF brightnessup # Fn+F9 brightness up +0xD9 brightnessdown # Fn+F8 brightness down +0xEF brightnessup # Fn+F9 brightness up 0xA9 switchvideomode # Fn+F10 Cycle between available video outputs diff --git a/keymaps/fujitsu-amilo_pro_edition_v3505 b/keymaps/fujitsu-amilo_pro_edition_v3505 index 74bae2f144..fd95b000c6 100644 --- a/keymaps/fujitsu-amilo_pro_edition_v3505 +++ b/keymaps/fujitsu-amilo_pro_edition_v3505 @@ -1,4 +1,4 @@ -0xA5 help # Fn+F1 +0xA5 help # Fn+F1 0xA9 switchvideomode # Fn+F3 -0xD9 brightnessdown # Fn+F8 -0xE0 brightnessup # Fn+F9 +0xD9 brightnessdown # Fn+F8 +0xE0 brightnessup # Fn+F9 diff --git a/keymaps/fujitsu-amilo_pro_v3205 b/keymaps/fujitsu-amilo_pro_v3205 index 43e3199d59..8cbf239464 100644 --- a/keymaps/fujitsu-amilo_pro_v3205 +++ b/keymaps/fujitsu-amilo_pro_v3205 @@ -1,2 +1,2 @@ -0xF4 f21 # FIXME: silent-mode decrease CPU/GPU clock +0xF4 f21 # FIXME: silent-mode decrease CPU/GPU clock 0xF7 switchvideomode # Fn+F3 diff --git a/keymaps/hewlett-packard b/keymaps/hewlett-packard index 4ab21947e2..3f5f5ace6f 100644 --- a/keymaps/hewlett-packard +++ b/keymaps/hewlett-packard @@ -1,12 +1,12 @@ 0x81 fn_esc -0x89 battery # Fn+F8 -0x8A screenlock # Fn+F6 +0x89 battery # Fn+F8 +0x8A screenlock # Fn+F6 0x8B camera -0x8C media # music +0x8C media # music 0x8E dvd 0xB1 help -0xB3 f23 # FIXME: Auto brightness +0xB3 f23 # FIXME: Auto brightness 0xD7 wlan -0x92 brightnessdown # Fn+F7 (Fn+F9 on 6730b) -0x97 brightnessup # Fn+F8 (Fn+F10 on 6730b) +0x92 brightnessdown # Fn+F7 (Fn+F9 on 6730b) +0x97 brightnessup # Fn+F8 (Fn+F10 on 6730b) 0xEE switchvideomode # Fn+F4 diff --git a/keymaps/hewlett-packard-pavilion b/keymaps/hewlett-packard-pavilion index 3d3cefc8e6..60d1191106 100644 --- a/keymaps/hewlett-packard-pavilion +++ b/keymaps/hewlett-packard-pavilion @@ -1,3 +1,3 @@ -0x88 media # FIXME: quick play -0xD8 f23 # touchpad off -0xD9 f22 # touchpad on +0x88 media # FIXME: quick play +0xD8 f23 # touchpad off +0xD9 f22 # touchpad on diff --git a/keymaps/hewlett-packard_elitebook-8460p b/keymaps/hewlett-packard_elitebook-8460p index 1fe1b7237c..59035f4005 100644 --- a/keymaps/hewlett-packard_elitebook-8460p +++ b/keymaps/hewlett-packard_elitebook-8460p @@ -1,3 +1,3 @@ -0xF8 wlan # Wireless HW switch button -0xB3 prog1 # Fn+F11 - Ambient Light Sensor button -0xB1 prog2 # Fn+ESC - System information button +0xF8 wlan # Wireless HW switch button +0xB3 prog1 # Fn+F11 - Ambient Light Sensor button +0xB1 prog2 # Fn+ESC - System information button diff --git a/keymaps/lenovo-3000 b/keymaps/lenovo-3000 index 5bd165654a..7973369a9d 100644 --- a/keymaps/lenovo-3000 +++ b/keymaps/lenovo-3000 @@ -1,5 +1,5 @@ 0x8B switchvideomode # Fn+F7 video -0x96 wlan # Fn+F5 wireless -0x97 sleep # Fn+F4 suspend -0x98 suspend # Fn+F12 hibernate -0xB4 prog1 # Lenovo Care +0x96 wlan # Fn+F5 wireless +0x97 sleep # Fn+F4 suspend +0x98 suspend # Fn+F12 hibernate +0xB4 prog1 # Lenovo Care diff --git a/keymaps/lenovo-thinkpad-usb-keyboard-trackpoint b/keymaps/lenovo-thinkpad-usb-keyboard-trackpoint index ac829d8f7f..78701acbc7 100644 --- a/keymaps/lenovo-thinkpad-usb-keyboard-trackpoint +++ b/keymaps/lenovo-thinkpad-usb-keyboard-trackpoint @@ -1,13 +1,13 @@ -0x90012 screenlock # Fn+F2 -0x90013 battery # Fn+F3 -0x90014 wlan # Fn+F5 -0x90016 switchvideomode # Fn+F7 -0x90017 f21 # Fn+F8 touchpad toggle -0x90019 suspend # Fn+F12 -0x9001A brightnessup # Fn+Home -0x9001B brightnessdown # Fn+End -0x9001D zoom # Fn+Space -0x90011 prog1 # ThinkVantage button +0x90012 screenlock # Fn+F2 +0x90013 battery # Fn+F3 +0x90014 wlan # Fn+F5 +0x90016 switchvideomode # Fn+F7 +0x90017 f21 # Fn+F8 touchpad toggle +0x90019 suspend # Fn+F12 +0x9001A brightnessup # Fn+Home +0x9001B brightnessdown # Fn+End +0x9001D zoom # Fn+Space +0x90011 prog1 # ThinkVantage button -0x90015 camera # Fn+F6 headset/camera VoIP key ?? -0x90010 f20 # Microphone mute button; should be micmute, but see https://mail.gnome.org/archives/commits-list/2013-January/msg05822.html +0x90015 camera # Fn+F6 headset/camera VoIP key ?? +0x90010 f20 # Microphone mute button; should be micmute, but see https://mail.gnome.org/archives/commits-list/2013-January/msg05822.html diff --git a/keymaps/lenovo-thinkpad_x200_tablet b/keymaps/lenovo-thinkpad_x200_tablet index 31ea3b2c70..f22ec65a5b 100644 --- a/keymaps/lenovo-thinkpad_x200_tablet +++ b/keymaps/lenovo-thinkpad_x200_tablet @@ -1,6 +1,6 @@ 0x5D menu 0x63 fn 0x66 screenlock -0x67 cyclewindows # bezel circular arrow -0x68 setup # bezel setup / menu -0x6c direction # rotate screen +0x67 cyclewindows # bezel circular arrow +0x68 setup # bezel setup / menu +0x6c direction # rotate screen diff --git a/keymaps/lenovo-thinkpad_x6_tablet b/keymaps/lenovo-thinkpad_x6_tablet index 6fd16b5662..49c5f64f4c 100644 --- a/keymaps/lenovo-thinkpad_x6_tablet +++ b/keymaps/lenovo-thinkpad_x6_tablet @@ -1,8 +1,8 @@ -0x6C f21 # rotate -0x68 screenlock # screenlock -0x6B esc # escape -0x6D right # right on d-pad -0x6E left # left on d-pad -0x71 up # up on d-pad -0x6F down # down on d-pad -0x69 enter # enter on d-pad +0x6C f21 # rotate +0x68 screenlock # screenlock +0x6B esc # escape +0x6D right # right on d-pad +0x6E left # left on d-pad +0x71 up # up on d-pad +0x6F down # down on d-pad +0x69 enter # enter on d-pad diff --git a/keymaps/lg-x110 b/keymaps/lg-x110 index 57f9156c62..bbc29a13e9 100644 --- a/keymaps/lg-x110 +++ b/keymaps/lg-x110 @@ -1,12 +1,12 @@ -0xA0 mute # Fn+F9 -0xAE volumedown # Fn+Left -0xAF search # Fn+F3 -0xB0 volumeup # Fn+Right -0xB1 battery # Fn+F10 Info -0xB3 suspend # Fn+F12 -0xDF sleep # Fn+F4 +0xA0 mute # Fn+F9 +0xAE volumedown # Fn+Left +0xAF search # Fn+F3 +0xB0 volumeup # Fn+Right +0xB1 battery # Fn+F10 Info +0xB3 suspend # Fn+F12 +0xDF sleep # Fn+F4 # 0xE2 bluetooth # satellite dish2 -0xE4 f21 # Fn+F5 Touchpad toggle -0xF6 wlan # Fn+F6 -0xF7 reserved # Fn+Down brightnessdown -0xF8 reserved # Fn+Up brightnessup +0xE4 f21 # Fn+F5 Touchpad toggle +0xF6 wlan # Fn+F6 +0xF7 reserved # Fn+Down brightness down +0xF8 reserved # Fn+Up brightness up diff --git a/keymaps/logitech-usb b/keymaps/logitech-usb index 728f0e02b2..b575aa7c47 100644 --- a/keymaps/logitech-usb +++ b/keymaps/logitech-usb @@ -1,6 +1,6 @@ -0x90001 shop # Shopping -0x90002 config # iTouch -0x90003 finance # Finance -0x90004 prog1 # My Sites -0x90005 prog2 # Community -0xC0183 media # Media +0x90001 shop # Shopping +0x90002 config # iTouch +0x90003 finance # Finance +0x90004 prog1 # My Sites +0x90005 prog2 # Community +0xC0183 media # Media diff --git a/keymaps/logitech-wave b/keymaps/logitech-wave index 724694e067..781dbe26f7 100644 --- a/keymaps/logitech-wave +++ b/keymaps/logitech-wave @@ -1,16 +1,16 @@ -0x9001C scale #expo -0x9001F zoomout #zoom out -0x90020 zoomin #zoom in -0x9003D prog1 #gadget -0x90005 camera #camera -0x90018 media #media center -0x90041 wordprocessor #Fn+F1 (Word) -0x90042 spreadsheet #Fn+F2 (Excel) -0x90043 calendar #Fn+F3 (calendar) -0x90044 prog2 #Fn+F4 (program a) -0x90045 prog3 #Fn+F5 (program b) -0x90046 prog4 #Fn+F6 (program c) -0x90048 messenger #Fn+F8 (MSN messenger) -0x9002D find #Fn+F10 (search www) -0x9004B search #Fn+F11 (search PC) -0x9004C ejectclosecd #Fn+F12 (eject) +0x9001C scale # expo +0x9001F zoomout # zoom out +0x90020 zoomin # zoom in +0x9003D prog1 # gadget +0x90005 camera # camera +0x90018 media # media center +0x90041 wordprocessor # Fn+F1 (Word) +0x90042 spreadsheet # Fn+F2 (Excel) +0x90043 calendar # Fn+F3 (calendar) +0x90044 prog2 # Fn+F4 (program a) +0x90045 prog3 # Fn+F5 (program b) +0x90046 prog4 # Fn+F6 (program c) +0x90048 messenger # Fn+F8 (MSN messenger) +0x9002D find # Fn+F10 (search www) +0x9004B search # Fn+F11 (search PC) +0x9004C ejectclosecd # Fn+F12 (eject) diff --git a/keymaps/logitech-wave-cordless b/keymaps/logitech-wave-cordless index 83bba1daf5..b40c4dbff7 100644 --- a/keymaps/logitech-wave-cordless +++ b/keymaps/logitech-wave-cordless @@ -7,9 +7,9 @@ 0xC1041 wordprocessor 0xC1042 spreadsheet 0xC1043 calendar -0xC1044 prog2 #Fn+F4 (program a) -0xC1045 prog3 #Fn+F5 (program b) -0xC1046 prog4 #Fn+F6 (program c) +0xC1044 prog2 # Fn+F4 (program a) +0xC1045 prog3 # Fn+F5 (program b) +0xC1046 prog4 # Fn+F6 (program c) 0xC1048 messenger -0xC104A find #Fn+F10 (search www) +0xC104A find # Fn+F10 (search www) 0xC104C ejectclosecd diff --git a/keymaps/maxdata-pro_7000 b/keymaps/maxdata-pro_7000 index 87c94a3411..0d5bbf3ce5 100644 --- a/keymaps/maxdata-pro_7000 +++ b/keymaps/maxdata-pro_7000 @@ -1,9 +1,9 @@ 0x97 prog2 0x9F prog1 -0xA0 mute # Fn+F5 +0xA0 mute # Fn+F5 0x82 www 0xEC email 0xAE volumedown # Fn+Down -0xB0 volumeup # Fn+Up -0xDF suspend # Fn+F2 +0xB0 volumeup # Fn+Up +0xDF suspend # Fn+F2 0xF5 help diff --git a/keymaps/medion-fid2060 b/keymaps/medion-fid2060 index 5a76c76799..75b1647e43 100644 --- a/keymaps/medion-fid2060 +++ b/keymaps/medion-fid2060 @@ -1,2 +1,2 @@ -0x6B channeldown # Thottle Down -0x6D channelup # Thottle Up +0x6B channeldown # Thottle Down +0x6D channelup # Thottle Up diff --git a/keymaps/medionnb-a555 b/keymaps/medionnb-a555 index c3b5dfa60b..b69618308b 100644 --- a/keymaps/medionnb-a555 +++ b/keymaps/medionnb-a555 @@ -1,4 +1,4 @@ -0x63 www # N button -0x66 prog1 # link 1 button -0x67 email # envelope button -0x69 prog2 # link 2 button +0x63 www # N button +0x66 prog1 # link 1 button +0x67 email # envelope button +0x69 prog2 # link 2 button diff --git a/keymaps/micro-star b/keymaps/micro-star index 40a8decbe2..c283cde8bb 100644 --- a/keymaps/micro-star +++ b/keymaps/micro-star @@ -1,13 +1,13 @@ -0xA0 mute # Fn+F9 -0xAE volumedown # Fn+F7 -0xB0 volumeup # Fn+F8 -0xB2 www # e button -0xDF sleep # Fn+F12 -0xE2 bluetooth # satellite dish2 -0xE4 f21 # Fn+F3 Touchpad disable -0xEC email # envelope button -0xEE camera # Fn+F6 camera disable -0xF6 wlan # satellite dish1 -0xF7 brightnessdown # Fn+F4 -0xF8 brightnessup # Fn+F5 +0xA0 mute # Fn+F9 +0xAE volumedown # Fn+F7 +0xB0 volumeup # Fn+F8 +0xB2 www # e button +0xDF sleep # Fn+F12 +0xE2 bluetooth # satellite dish2 +0xE4 f21 # Fn+F3 Touchpad disable +0xEC email # envelope button +0xEE camera # Fn+F6 camera disable +0xF6 wlan # satellite dish1 +0xF7 brightnessdown # Fn+F4 +0xF8 brightnessup # Fn+F5 0xF9 search diff --git a/keymaps/module-ibm b/keymaps/module-ibm index a92dfa2506..ee61b6cf3b 100644 --- a/keymaps/module-ibm +++ b/keymaps/module-ibm @@ -1,16 +1,16 @@ -0x01 battery # Fn+F2 -0x02 screenlock # Fn+F3 -0x03 sleep # Fn+F4 -0x04 wlan # Fn+F5 +0x01 battery # Fn+F2 +0x02 screenlock # Fn+F3 +0x03 sleep # Fn+F4 +0x04 wlan # Fn+F5 0x06 switchvideomode # Fn+F7 -0x07 zoom # Fn+F8 screen expand -0x08 f24 # Fn+F9 undock -0x0B suspend # Fn+F12 -0x0F brightnessup # Fn+Home -0x10 brightnessdown # Fn+End -0x11 kbdillumtoggle # Fn+PgUp - ThinkLight -0x13 zoom # Fn+Space +0x07 zoom # Fn+F8 screen expand +0x08 f24 # Fn+F9 undock +0x0B suspend # Fn+F12 +0x0F brightnessup # Fn+Home +0x10 brightnessdown # Fn+End +0x11 kbdillumtoggle # Fn+PgUp - ThinkLight +0x13 zoom # Fn+Space 0x14 volumeup 0x15 volumedown 0x16 mute -0x17 prog1 # ThinkPad/ThinkVantage button (high keycode: "vendor") +0x17 prog1 # ThinkPad/ThinkVantage button (high keycode: "vendor") diff --git a/keymaps/module-lenovo b/keymaps/module-lenovo index 573a6a774b..ed31899d0f 100644 --- a/keymaps/module-lenovo +++ b/keymaps/module-lenovo @@ -1,17 +1,17 @@ -0x1 screenlock # Fn+F2 -0x2 battery # Fn+F3 -0x3 sleep # Fn+F4 -0x4 wlan # Fn+F5 -0x6 switchvideomode # Fn+F7 -0x7 f21 # Fn+F8 touchpadtoggle -0x8 f24 # Fn+F9 undock -0xB suspend # Fn+F12 -0xF brightnessup # Fn+Home -0x10 brightnessdown # Fn+End -0x11 kbdillumtoggle # Fn+PgUp - ThinkLight -0x13 zoom # Fn+Space +0x1 screenlock # Fn+F2 +0x2 battery # Fn+F3 +0x3 sleep # Fn+F4 +0x4 wlan # Fn+F5 +0x6 switchvideomode # Fn+F7 +0x7 f21 # Fn+F8 touchpadtoggle +0x8 f24 # Fn+F9 undock +0xB suspend # Fn+F12 +0xF brightnessup # Fn+Home +0x10 brightnessdown # Fn+End +0x11 kbdillumtoggle # Fn+PgUp - ThinkLight +0x13 zoom # Fn+Space 0x14 volumeup 0x15 volumedown 0x16 mute -0x17 prog1 # ThinkPad/ThinkVantage button (high keycode: "vendor") -0x1A f20 # Microphone mute button; should be micmute, but see https://mail.gnome.org/archives/commits-list/2013-January/msg05822.html +0x17 prog1 # ThinkPad/ThinkVantage button (high keycode: "vendor") +0x1A f20 # Microphone mute button; should be micmute, but see https://mail.gnome.org/archives/commits-list/2013-January/msg05822.html diff --git a/keymaps/module-sony b/keymaps/module-sony index 7c000131d1..5d3742b463 100644 --- a/keymaps/module-sony +++ b/keymaps/module-sony @@ -1,8 +1,8 @@ -0x06 mute # Fn+F2 -0x07 volumedown # Fn+F3 -0x08 volumeup # Fn+F4 -0x09 brightnessdown # Fn+F5 -0x0A brightnessup # Fn+F6 -0x0B switchvideomode # Fn+F7 -0x0E zoom # Fn+F10 -0x10 suspend # Fn+F12 +0x06 mute # Fn+F2 +0x07 volumedown # Fn+F3 +0x08 volumeup # Fn+F4 +0x09 brightnessdown # Fn+F5 +0x0A brightnessup # Fn+F6 +0x0B switchvideomode # Fn+F7 +0x0E zoom # Fn+F10 +0x10 suspend # Fn+F12 diff --git a/keymaps/module-sony-vgn b/keymaps/module-sony-vgn index c8ba001516..cb4ce33717 100644 --- a/keymaps/module-sony-vgn +++ b/keymaps/module-sony-vgn @@ -1,8 +1,8 @@ -0x00 brightnessdown # Fn+F5 -0x10 brightnessup # Fn+F6 -0x11 switchvideomode # Fn+F7 +0x00 brightnessdown # Fn+F5 +0x10 brightnessup # Fn+F6 +0x11 switchvideomode # Fn+F7 0x12 zoomout 0x14 zoomin -0x15 suspend # Fn+F12 +0x15 suspend # Fn+F12 0x17 prog1 0x20 media diff --git a/keymaps/module-sony-vpc b/keymaps/module-sony-vpc index 681082c59e..1b52779535 100644 --- a/keymaps/module-sony-vpc +++ b/keymaps/module-sony-vpc @@ -1,4 +1,4 @@ # 0x05 touchpad_toggle # fn_f1 -> KEY_TOUCHPAD_TOGGLE -0x05 f21 # fn_f1 -> KEY_F21 (The actual touchpad toggle) -0x0d zoomout # fn_f9 -0x0e zoomin # fn_f10 +0x05 f21 # fn_f1 -> KEY_F21 (The actual touchpad toggle) +0x0d zoomout # fn_f9 +0x0e zoomin # fn_f10 diff --git a/keymaps/olpc-xo b/keymaps/olpc-xo index 78dad553a8..0fa497211a 100644 --- a/keymaps/olpc-xo +++ b/keymaps/olpc-xo @@ -41,9 +41,9 @@ 0xEF f21 0xEE chat -0xE4 chat # Just mapping Fn+Chat to Chat for now -0xDD menu # Frame -0xDA prog1 # Fn+Frame +0xE4 chat # Just mapping Fn+Chat to Chat for now +0xDD menu # Frame +0xDA prog1 # Fn+Frame # The Fn of some keys is other keys 0xD3 delete @@ -57,11 +57,11 @@ 0x73 hp 0x7E hp -0xDB leftmeta # left grab -0xDC rightmeta # right grab -0x85 rightmeta # Right grab releases on a different scancode -0xD6 kbdillumtoggle # Fn+space -0x69 switchvideomode # Brightness key +0xDB leftmeta # left grab +0xDC rightmeta # right grab +0x85 rightmeta # Right grab releases on a different scancode +0xD6 kbdillumtoggle # Fn+Space +0x69 switchvideomode # Brightness key # Game keys 0x65 kp8 # up diff --git a/keymaps/onkyo b/keymaps/onkyo index ee864ade4d..8fc4cffa92 100644 --- a/keymaps/onkyo +++ b/keymaps/onkyo @@ -1,14 +1,14 @@ -0xA0 mute # Fn+D -0xAE volumedown # Fn+F -0xB0 volumeup # Fn+G -0xDF sleep # Fn+W -0xE0 bluetooth # Fn+H -0xE2 cyclewindows # Fn+Esc -0xEE battery # Fn+Q -0xF0 media # Fn+R +0xA0 mute # Fn+D +0xAE volumedown # Fn+F +0xB0 volumeup # Fn+G +0xDF sleep # Fn+W +0xE0 bluetooth # Fn+H +0xE2 cyclewindows # Fn+Esc +0xEE battery # Fn+Q +0xF0 media # Fn+R 0xF5 switchvideomode # Fn+E -0xF6 camera # Fn+T -0xF7 f21 # Fn+Y (touchpad toggle) -0xF8 brightnessup # Fn+S -0xF9 brightnessdown # Fn+A -0xFB wlan # Fn+J +0xF6 camera # Fn+T +0xF7 f21 # Fn+Y (touchpad toggle) +0xF8 brightnessup # Fn+S +0xF9 brightnessdown # Fn+A +0xFB wlan # Fn+J diff --git a/keymaps/samsung-other b/keymaps/samsung-other index 536a13d9cd..d950c2cbd9 100644 --- a/keymaps/samsung-other +++ b/keymaps/samsung-other @@ -1,14 +1,14 @@ -0x74 prog1 # User key +0x74 prog1 # User key 0x75 www 0x78 mail -0x82 switchvideomode # Fn+F4 CRT/LCD (high keycode: "displaytoggle") -0x83 battery # Fn+F2 -0x84 prog1 # Fn+F5 backlight on/off -0x86 wlan # Fn+F9 -0x88 brightnessup # Fn+Up -0x89 brightnessdown # Fn+Down -0xB1 prog2 # Fn+F7 run Samsung Magic Doctor (keypressed event is generated twice) -0xB3 prog3 # Fn+F8 switch power mode (battery/dynamic/performance) -0xB4 wlan # Fn+F9 (X60P) -0xF7 f22 # Fn+F10 Touchpad on -0xF9 f23 # Fn+F10 Touchpad off +0x82 switchvideomode # Fn+F4 CRT/LCD (high keycode: "displaytoggle") +0x83 battery # Fn+F2 +0x84 prog1 # Fn+F5 backlight on/off +0x86 wlan # Fn+F9 +0x88 brightnessup # Fn+Up +0x89 brightnessdown # Fn+Down +0xB1 prog2 # Fn+F7 run Samsung Magic Doctor (keypressed event is generated twice) +0xB3 prog3 # Fn+F8 switch power mode (battery/dynamic/performance) +0xB4 wlan # Fn+F9 (X60P) +0xF7 f22 # Fn+F10 Touchpad on +0xF9 f23 # Fn+F10 Touchpad off diff --git a/keymaps/samsung-series-3 b/keymaps/samsung-series-3 index 9a16fbce27..303a428b47 100644 --- a/keymaps/samsung-series-3 +++ b/keymaps/samsung-series-3 @@ -1,3 +1,3 @@ -0xCE prog1 # Fn+F1 launch control setting -0xB3 prog2 # Fn+F11 performance mode -0xD5 wlan # Fn+F12 Wi-Fi toggle +0xCE prog1 # Fn+F1 launch control setting +0xB3 prog2 # Fn+F11 performance mode +0xD5 wlan # Fn+F12 Wi-Fi toggle -- cgit v1.2.1 From 409dee2e44e7dc73d6bf00d782938e4cb4105f5b Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Tue, 2 Jul 2013 05:44:04 +0200 Subject: man: more grammar improvements - place commas - expand contractions (this is written prose :) - add some missing words --- man/bootchart.conf.xml | 6 +- man/bootup.xml | 27 ++++----- man/crypttab.xml | 10 ++-- man/daemon.xml | 130 ++++++++++++++++++++++---------------------- man/halt.xml | 8 +-- man/hostname.xml | 2 +- man/hostnamectl.xml | 4 +- man/journalctl.xml | 58 ++++++++++---------- man/journald.conf.xml | 84 +++++++++++++++------------- man/kernel-command-line.xml | 30 +++++----- man/kernel-install.xml | 6 +- man/locale.conf.xml | 6 +- man/localectl.xml | 8 +-- man/localtime.xml | 4 +- man/loginctl.xml | 20 +++---- man/logind.conf.xml | 16 +++--- man/machine-id.xml | 6 +- man/systemd.unit.xml | 2 +- 18 files changed, 217 insertions(+), 210 deletions(-) diff --git a/man/bootchart.conf.xml b/man/bootchart.conf.xml index 7fd47ebe96..68d10d4415 100644 --- a/man/bootchart.conf.xml +++ b/man/bootchart.conf.xml @@ -72,7 +72,7 @@ Samples=500 Configure the amount of samples to - record total before bootchart exits. Each sample will + record in total before bootchart exits. Each sample will record at intervals defined by Frequency=. @@ -107,7 +107,7 @@ Output=[path] - Configures the output folder for writing + Configures the output directory for writing the graphs. By default, bootchart writes the graphs to /run/log. @@ -124,7 +124,7 @@ PlotMemoryUsage=no If set to yes, enables logging and graphing - of processes PSS memory consumption. + of processes' PSS memory consumption. diff --git a/man/bootup.xml b/man/bootup.xml index a596e85b70..65c2cee70e 100644 --- a/man/bootup.xml +++ b/man/bootup.xml @@ -56,26 +56,27 @@ and hand control over to a boot loader stored on a persistent storage device. This boot loader will then invoke an OS kernel from disk (or the network). In the - Linux case this kernel (optionally) extracts and - executes an initial RAM disk image (initrd) such as - dracut8 + Linux case, this kernel (optionally) extracts and + executes an initial RAM disk image (initrd), such as + generated by + dracut8, which looks for the root file system (possibly using systemd1 for this). After the root file system is found and - mounted the initrd hands over control to the host's + mounted, the initrd hands over control to the host's system manager (such as systemd1) - stored on the OS image which is then responsible for + stored on the OS image, which is then responsible for probing all remaining hardware, mounting all necessary file systems and spawning all configured services. - On shutdown the system manager stops all + On shutdown, the system manager stops all services, unmounts all file systems (detaching the storage technologies backing them), and then (optionally) jumps back into the initrd code which unmounts/detaches the root file system and the storage - it resides on. As last step the system is powered down. + it resides on. As a last step, the system is powered down. Additional information about the system boot process may be found in @@ -90,7 +91,7 @@ systems, services and drivers that are necessary for operation of the system. On systemd1 - systems this process is split up in various discrete + systems, this process is split up in various discrete steps which are exposed as target units. (See systemd.target5 for detailed information about target units.) The @@ -99,17 +100,17 @@ deterministic, but still adheres to a limited amount of ordering structure. - When systemd starts up the system it will + When systemd starts up the system, it will activate all units that are dependencies of default.target (as well as recursively all dependencies of these - dependencies). Usually + dependencies). Usually, default.target is simply an alias of graphical.target or - multi-user.target depending on + multi-user.target, depending on whether the system is configured for a graphical UI or only for a text console. To enforce minimal ordering - between the units pulled in a number of well-known + between the units pulled in, a number of well-known target units are available, as listed on systemd.special7. @@ -178,7 +179,7 @@ Bootup in the Initial RAM Disk (initrd) The initial RAM disk implementation (initrd) can - be set up using systemd as well. In this case boot up + be set up using systemd as well. In this case, boot up inside the initrd follows the following structure. diff --git a/man/crypttab.xml b/man/crypttab.xml index 1063b46e06..e52b7e6015 100644 --- a/man/crypttab.xml +++ b/man/crypttab.xml @@ -83,15 +83,15 @@ underlying block device, or a specification of a block device via UUID= followed by the UUID. If the block device contains a LUKS signature, - it is opened as a LUKS encrypted partition; otherwise + it is opened as a LUKS encrypted partition; otherwise, it is assumed to be a raw dm-crypt partition. The third field specifies the encryption password. If the field is not present or the password is set to none, the password has to be manually - entered during system boot. Otherwise the field is + entered during system boot. Otherwise, the field is interpreted as a path to a file containing the - encryption password. For swap encryption + encryption password. For swap encryption, /dev/urandom or the hardware device /dev/hw_random can be used as the password file; using @@ -239,7 +239,7 @@ The system will not wait for the device to show up and be unlocked at boot, and not fail the - boot if it doesn't show + boot if it does not show up. @@ -282,7 +282,7 @@ At early boot and when the system manager - configuration is reloaded this file is translated into + configuration is reloaded, this file is translated into native systemd units by systemd-cryptsetup-generator8. diff --git a/man/daemon.xml b/man/daemon.xml index 76ae832a42..7790420c6e 100644 --- a/man/daemon.xml +++ b/man/daemon.xml @@ -79,7 +79,7 @@ descriptors 0, 1, 2). This ensures that no accidentally passed file descriptor stays around in the daemon - process. On Linux this is best + process. On Linux, this is best implemented by iterating through /proc/self/fd, with a fallback of iterating from file @@ -115,7 +115,7 @@ In the child, call fork() again, to - ensure the daemon can never re-acquire + ensure that the daemon can never re-acquire a terminal again. Call exit() in the @@ -150,15 +150,15 @@ getpid()) to a PID file, for example /var/run/foobar.pid - (for a hypothetical daemon "foobar"), + (for a hypothetical daemon "foobar") to ensure that the daemon cannot be started more than once. This must be implemented in race-free fashion so that the PID file is only updated when - at the same time it is verified that + it is verified at the same time that the PID previously stored in the PID file no longer exists or belongs to a - foreign process. Commonly some kind of + foreign process. Commonly, some kind of file locking is employed to implement this logic. @@ -167,7 +167,7 @@ applicable. From the daemon - process notify the original process + process, notify the original process started that initialization is complete. This can be implemented via an unnamed pipe or similar @@ -197,7 +197,7 @@ implement the scheme pointed out above. However, it is recommended to make this behavior optional and configurable via a - command line argument, to ease debugging as + command line argument to ease debugging as well as to simplify integration into systems using systemd. @@ -211,20 +211,20 @@ runtime and simplifies their implementation. - For developing a new-style daemon none + For developing a new-style daemon, none of the initialization steps recommended for SysV daemons need to be implemented. New-style init systems such as systemd make all of them redundant. Moreover, since some of these steps interfere with process monitoring, file descriptor passing and other functionality of - the init system it is recommended not to + the init system, it is recommended not to execute them when run as new-style service. Note that new-style init systems guarantee execution of daemon processes in - clean process contexts: it is guaranteed that + a clean process context: it is guaranteed that the environment block is sanitized, that the signal handlers and mask is reset and that no left-over file descriptors are passed. Daemons @@ -256,7 +256,7 @@ scripts. If possible and - applicable expose the daemon's control + applicable, expose the daemon's control interface via the D-Bus IPC system and grab a bus name as last step of initialization. @@ -274,7 +274,7 @@ rely on the init system's functionality to limit the access of the daemon to files, services and - other resources. i.e. in the case of + other resources, i.e. in the case of systemd, rely on systemd's resource limit control instead of implementing your own, rely on systemd's privilege @@ -285,7 +285,7 @@ controls. If D-Bus is used, make - your daemon bus-activatable, via + your daemon bus-activatable by supplying a D-Bus service activation configuration file. This has multiple advantages: your daemon may be started @@ -293,7 +293,7 @@ parallel to other daemons requiring it -- which maximizes parallelization and boot-up speed; your daemon can be - restarted on failure, without losing + restarted on failure without losing any bus requests, as the bus queues requests for activatable services. See below for details. @@ -304,17 +304,17 @@ socket, it should be made socket-activatable following the scheme pointed out below. Like D-Bus - activation this enables on-demand + activation, this enables on-demand starting of services as well as it allows improved parallelization of service start-up. Also, for state-less - protocols (such as syslog, DNS) a + protocols (such as syslog, DNS), a daemon implementing socket-based activation can be restarted without losing a single request. See below for details. - If applicable a daemon + If applicable, a daemon should notify the init system about startup completion or status updates via the @@ -327,7 +327,7 @@ choose to simply log to STDERR via fprintf(), which is then forwarded to syslog by the init system. If log - priorities are necessary these can be + priorities are necessary, these can be encoded by prefixing individual log lines with strings like "<4>" (for log priority 4 "WARNING" in the @@ -343,7 +343,7 @@ kind of logging may be enabled by setting StandardError=syslog - in the service unit file. For details + in the service unit file. For details, see sd-daemon3 and @@ -374,9 +374,9 @@ when a printer is plugged in, or when a file is queued in the printer spool directory. Even for services that are intended to be started on system bootup - unconditionally it is a good idea to implement some of + unconditionally, it is a good idea to implement some of the various activation schemes outlined below, in - order to maximize parallelization: if a daemon + order to maximize parallelization. If a daemon implements a D-Bus service or listening socket, implementing the full bus and socket activation scheme allows starting of the daemon with its clients in @@ -384,7 +384,7 @@ communication channels are established already, and no request is lost because client requests will be queued by the bus system (in case of D-Bus) or the kernel (in - case of sockets), until the activation is + case of sockets) until the activation is completed. @@ -399,7 +399,7 @@ Specification. This method of activation is supported ubiquitously on Linux init systems, both old-style and new-style - systems. Among other issues SysV init scripts + systems. Among other issues, SysV init scripts have the disadvantage of involving shell scripts in the boot process. New-style init systems generally employ updated versions of @@ -409,7 +409,7 @@ In systemd, if the developer or administrator wants to make sure a service or - other unit is activated automatically on boot + other unit is activated automatically on boot, it is recommended to place a symlink to the unit file in the .wants/ directory of either @@ -434,25 +434,25 @@ recommended for all new-style daemons that communicate via listening sockets to employ socket-based activation. In a socket-based - activation scheme the creation and binding of + activation scheme, the creation and binding of the listening socket as primary communication channel of daemons to local (and sometimes remote) clients is moved out of the daemon code and into the init system. Based on - per-daemon configuration the init system + per-daemon configuration, the init system installs the sockets and then hands them off to the spawned process as soon as the respective daemon is to be started. - Optionally activation of the service can be + Optionally, activation of the service can be delayed until the first inbound traffic - arrives at the socket, to implement on-demand + arrives at the socket to implement on-demand activation of daemons. However, the primary advantage of this scheme is that all providers and all consumers of the sockets can be started in parallel as soon as all sockets - are established. In addition to that daemons + are established. In addition to that, daemons can be restarted with losing only a minimal - number of client transactions or even any + number of client transactions, or even any client request at all (the latter is particularly true for state-less protocols, such as DNS or syslog), because the socket @@ -462,16 +462,16 @@ New-style daemons which support socket activation must be able to receive their - sockets from the init system, instead of + sockets from the init system instead of creating and binding them themselves. For details about the programming interfaces for - this scheme provided by systemd see + this scheme provided by systemd, see sd_listen_fds3 and sd-daemon3. For details about porting existing daemons to - socket-based activation see below. With - minimal effort it is possible to implement + socket-based activation, see below. With + minimal effort, it is possible to implement socket-based activation in addition to traditional internal socket creation in the same codebase in order to support both @@ -483,20 +483,20 @@ units, which are described in systemd.socket5. When configuring socket units for socket-based - activation it is essential that all listening + activation, it is essential that all listening sockets are pulled in by the special target unit sockets.target. It is recommended to place a WantedBy=sockets.target directive in the [Install] - section, to automatically add such a + section to automatically add such a dependency on installation of a socket unit. Unless DefaultDependencies=no is - set the necessary ordering dependencies are + set, the necessary ordering dependencies are implicitly created for all socket units. For more information about - sockets.target see + sockets.target, see systemd.special7. It is not necessary or recommended to place any additional dependencies on socket units (for @@ -518,16 +518,16 @@ service files (not to be confused with systemd service unit files!). To ensure that D-Bus uses systemd to start-up and maintain the - daemon use the + daemon, use the SystemdService= directive - in these service files, to configure the + in these service files to configure the matching systemd service for a D-Bus - service. e.g.: for a D-Bus service whose D-Bus + service. e.g.: For a D-Bus service whose D-Bus activation file is named org.freedesktop.RealtimeKit.service, make sure to set SystemdService=rtkit-daemon.service - in that file, to bind it to the systemd + in that file to bind it to the systemd service rtkit-daemon.service. This is needed to make sure that the daemon is @@ -542,23 +542,23 @@ type of hardware should be activated only when the hardware of the respective kind is plugged in or otherwise becomes available. In a - new-style init system it is possible to bind + new-style init system, it is possible to bind activation to hardware plug/unplug events. In systemd, kernel devices appearing in the sysfs/udev device tree can be exposed as units if they are tagged with the string systemd. Like any other - kind of unit they may then pull in other units - when activated (i.e. Plugged in) and thus - implement device-based activation. Systemd + kind of unit, they may then pull in other units + when activated (i.e. plugged in) and thus + implement device-based activation. systemd dependencies may be encoded in the udev database via the SYSTEMD_WANTS= property. See systemd.device5 - for details. Often it is nicer to pull in + for details. Often, it is nicer to pull in services from devices only indirectly via - dedicated targets. Example: instead of pulling + dedicated targets. Example: Instead of pulling in bluetoothd.service from all the various bluetooth dongles and other hardware available, pull in @@ -610,10 +610,10 @@ Other forms of activation have been suggested and implemented in some - systems. However, often there are simpler or + systems. However, there are often simpler or better alternatives, or they can be put together of combinations of the schemes - above. Example: sometimes it appears useful to + above. Example: Sometimes, it appears useful to start daemons or .socket units when a specific IP address is configured on a network interface, because network @@ -634,7 +634,7 @@ service activation is low system load. However, here too, a more convincing approach might be to make proper use of - features of the operating system: in + features of the operating system, in particular, the CPU or IO scheduler of Linux. Instead of scheduling jobs from userspace based on monitoring the OS @@ -668,7 +668,7 @@ suggestions: - If possible do not use + If possible, do not use the Type=forking setting in service files. But if you do, make sure to set the PID file path @@ -711,15 +711,15 @@ information for the unit file. See systemd.unit5 for details. To activate your service - on boot make sure to add a + on boot, make sure to add a WantedBy=multi-user.target or WantedBy=graphical.target directive. To activate your socket on boot, make sure to add - WantedBy=sockets.target. Usually + WantedBy=sockets.target. Usually, you also want to make sure that when - your service is installed your socket + your service is installed, your socket is installed too, hence add Also=foo.socket in your service file @@ -735,7 +735,7 @@ At the build installation time (e.g. make install during - package build) packages are recommended to + package build), packages are recommended to install their systemd unit files in the directory returned by pkg-config systemd @@ -748,12 +748,12 @@ request but not activate them automatically during boot. Optionally, during package installation (e.g. rpm -i - by the administrator) symlinks should be + by the administrator), symlinks should be created in the systemd configuration directories via the enable command of the systemctl1 - tool, to activate them automatically on + tool to activate them automatically on boot. Packages using @@ -801,7 +801,7 @@ endif In the rpm8 - .spec file use snippets + .spec file, use snippets like the following to enable/disable the service during installation/deinstallation. This makes use of @@ -827,7 +827,7 @@ endif %systemd_postun If the service shall be restarted during - upgrades replace the + upgrades, replace the %postun scriptlet above with the following: @@ -859,7 +859,7 @@ fi Where 0.47.11-1 is the first package version that includes the native unit file. This fragment will ensure that the first - time the unit file is installed it will be + time the unit file is installed, it will be enabled if and only if the SysV init script is enabled, thus making sure that the enable status is not changed. Note that @@ -875,13 +875,13 @@ fi Porting Existing Daemons Since new-style init systems such as systemd are - compatible with traditional SysV init systems it is + compatible with traditional SysV init systems, it is not strictly necessary to port existing daemons to the - new style. However doing so offers additional + new style. However, doing so offers additional functionality to the daemons as well as simplifying integration into new-style init systems. - To port an existing SysV compatible daemon the + To port an existing SysV compatible daemon, the following steps are recommended: @@ -896,7 +896,7 @@ fi interfaces to other software running on the local system via local AF_UNIX sockets, consider implementing socket-based activation - (see above). Usually a minimal patch is + (see above). Usually, a minimal patch is sufficient to implement this: Extend the socket creation in the daemon code so that sd_listen_fds3 diff --git a/man/halt.xml b/man/halt.xml index 8473965194..2a13d3c635 100644 --- a/man/halt.xml +++ b/man/halt.xml @@ -114,7 +114,7 @@ Force immediate halt, - power-off, reboot. Don't contact the + power-off, reboot. Do not contact the init system. @@ -123,7 +123,7 @@ Only write wtmp - shutdown entry, don't actually halt, + shutdown entry, do not actually halt, power-off, reboot. @@ -131,14 +131,14 @@ - Don't write wtmp + Do not write wtmp shutdown entry. - Don't send wall + Do not send wall message before halt, power-off, reboot. diff --git a/man/hostname.xml b/man/hostname.xml index 5971ad4345..a8648c5291 100644 --- a/man/hostname.xml +++ b/man/hostname.xml @@ -56,7 +56,7 @@ The /etc/hostname file configures the name of the local system that is set - during boot, with the + during boot using the sethostname2 system call. It should contain a single newline-terminated hostname string. The diff --git a/man/hostnamectl.xml b/man/hostnamectl.xml index 28e875dafd..f28e430a42 100644 --- a/man/hostnamectl.xml +++ b/man/hostnamectl.xml @@ -75,7 +75,7 @@ Note that the pretty hostname has little restrictions on the characters used, while the static and transient hostnames are limited to the usually - accepted characters of internet domain names. + accepted characters of Internet domain names. The static hostname is stored in /etc/hostname, see @@ -110,7 +110,7 @@ - Don't query the user + Do not query the user for authentication for privileged operations. diff --git a/man/journalctl.xml b/man/journalctl.xml index fa29c4103c..8dbfb3f0f3 100644 --- a/man/journalctl.xml +++ b/man/journalctl.xml @@ -64,11 +64,11 @@ journal as written by systemd-journald.service8. - If called without parameter it will show the full + If called without parameters, it will show the full contents of the journal, starting with the oldest entry collected. - If one or more match arguments are passed the + If one or more match arguments are passed, the output is filtered accordingly. A match is in the format FIELD=VALUE, e.g. _SYSTEMD_UNIT=httpd.service, @@ -76,7 +76,7 @@ entry. See systemd.journal-fields7 for a list of well-known fields. If multiple matches - are specified matching different fields the log + are specified matching different fields, the log entries are filtered by both, i.e. the resulting output will show only entries matching all the specified matches of this kind. If two matches apply to the same @@ -85,25 +85,25 @@ entries matching any of the specified matches for the same field. Finally, if the character + appears as separate word on the - command line all matches before and after are combined + command line, all matches before and after are combined in a disjunction (i.e. logical OR). As shortcuts for a few types of field/value - matches file paths may be specified. If a file path + matches, file paths may be specified. If a file path refers to an executable file, this is equivalent to an _EXE= match for the canonicalized - binary path. Similar, if a path refers to a device + binary path. Similarly, if a path refers to a device node, this is equivalent to a _KERNEL_DEVICE= match for the device. Output is interleaved from all accessible journal files, whether they are rotated or currently - being written, and regardless whether they belong to the + being written, and regardless of whether they belong to the system itself or are accessible user journals. All users are granted access to their private - per-user journals. However, by default only root and + per-user journals. However, by default, only root and users who are members of the adm group get access to the system journal and the journals of other users. @@ -173,7 +173,7 @@ the end of the journal inside the implied pager tool. This implies to guarantee - that the pager won't buffer logs of + that the pager will not buffer logs of unbounded size. This may be overridden with an explicit with some other numeric value on the @@ -230,7 +230,7 @@ cat. short is the default and generates an output that is mostly identical to the - formatting of classic syslog log + formatting of classic syslog files, showing one line per journal entry. short-monotonic is very similar but shows monotonic @@ -285,7 +285,7 @@ manuals. Note that help texts are not available for all messages, but only for selected ones. For more - information on the message catalog + information on the message catalog, please refer to the Message Catalog Developer @@ -386,10 +386,10 @@ notice (5), info (6), debug (7). If a - single log level is specified all + single log level is specified, all messages with this log level or a lower (hence more important) log level - are shown. If a range is specified all + are shown. If a range is specified, all messages within the range are shown, including both the start and the end value of the range. This will add @@ -468,7 +468,7 @@ Takes a directory path - as argument. If specified journalctl + as argument. If specified, journalctl will operate on the specified journal directory DIR instead @@ -480,7 +480,7 @@ Takes a file glob as - argument. If specified journalctl will + argument. If specified, journalctl will operate on the specified journal files matching GLOB instead of the default runtime and @@ -493,7 +493,7 @@ Takes a directory path - as argument. If specified journalctl + as argument. If specified, journalctl will operate on catalog file hierarchy underneath the specified directory instead of the root directory @@ -507,13 +507,13 @@ Instead of showing - journal contents generate a new 128 + journal contents, generate a new 128 bit ID suitable for identifying messages. This is intended for usage by developers who need a new identifier for a new message they introduce and want to make - recognizable. Will print the new ID in + recognizable. This will print the new ID in three different formats which can be copied into source code or similar. @@ -523,7 +523,7 @@ Instead of showing - journal contents show internal header + journal contents, show internal header information of the journal fields accessed. @@ -587,7 +587,7 @@ Instead of showing - journal contents generate a new key + journal contents, generate a new key pair for Forward Secure Sealing (FSS). This will generate a sealing key and a verification key. The @@ -604,7 +604,7 @@ Specifies the change - interval for the sealing key, when + interval for the sealing key when generating an FSS key pair with . Shorter intervals increase CPU consumption but @@ -620,9 +620,9 @@ Check the journal file for internal consistency. If the file has been generated with FSS - enabled, and the FSS verification key + enabled and the FSS verification key has been specified with - + , authenticity of the journal file is verified. @@ -642,7 +642,7 @@ Exit status - On success 0 is returned, a non-zero failure + On success, 0 is returned, a non-zero failure code otherwise. @@ -665,24 +665,24 @@ Examples - Without arguments all collected logs are shown + Without arguments, all collected logs are shown unfiltered: journalctl - With one match specified all entries with a field matching the expression are shown: + With one match specified, all entries with a field matching the expression are shown: journalctl _SYSTEMD_UNIT=avahi-daemon.service - If two different fields are matched only entries matching both expressions at the same time are shown: + If two different fields are matched, only entries matching both expressions at the same time are shown: journalctl _SYSTEMD_UNIT=avahi-daemon.service _PID=28097 - If two matches refer to the same field all entries matching either expression are shown: + If two matches refer to the same field, all entries matching either expression are shown: journalctl _SYSTEMD_UNIT=avahi-daemon.service _SYSTEMD_UNIT=dbus.service - If the separator + is used + If the separator + is used, two expressions may be combined in a logical OR. The following will show all messages from the Avahi service process with the PID 28097 plus all messages diff --git a/man/journald.conf.xml b/man/journald.conf.xml index 6e43914f23..b161b34e4e 100644 --- a/man/journald.conf.xml +++ b/man/journald.conf.xml @@ -54,8 +54,8 @@ Description - This files configures various parameters of the - systemd journal service + This file configures various parameters of the + systemd journal service, systemd-journald.service8. @@ -77,13 +77,13 @@ persistent, auto and none. If - volatile journal + volatile, journal log data will be stored only in memory, i.e. below the /run/log/journal hierarchy (which is created if needed). If - persistent data will + persistent, data will be stored preferably on disk, i.e. below the /var/log/journal @@ -112,7 +112,7 @@ Compress= Takes a boolean - value. If enabled (the default) data + value. If enabled (the default), data objects that shall be stored in the journal and are larger than a certain threshold are compressed with the XZ @@ -125,7 +125,7 @@ Seal= Takes a boolean - value. If enabled (the default) and a + value. If enabled (the default), and a sealing key is available (as created by journalctl1's @@ -149,23 +149,23 @@ of login, uid and none. If - login each logged - in user will get his own journal + login, each logged-in + user will get his own journal files, but systemd user IDs will log into the system journal. If - uid any user ID + uid, any user ID will get his own journal files regardless whether it belongs to a system service or refers to a real logged in user. If - none journal files - are not split up per-user and all - messages are stored in the single + none, journal files + are not split up by user and all + messages are instead stored in the single system journal. Note that splitting - up journal files per-user is only - available of journals are stored + up journal files by user is only + available for journals stored persistently. If journals are stored - on volatile storage (see above) only a + on volatile storage (see above), only a single journal file for all user IDs is kept. Defaults to login. @@ -177,14 +177,14 @@ Configures the rate limiting that is applied to all - messages generated on the system. If + messages generated on the system. If, in the time interval defined by - RateLimitInterval= + RateLimitInterval=, more messages than specified in RateLimitBurst= are - logged by a service all further + logged by a service, all further messages within the interval are - dropped, until the interval is over. A + dropped until the interval is over. A message about the number of dropped messages is generated. This rate limiting is applied per-service, so @@ -227,13 +227,13 @@ /run/log/journal. The former is used only when /var is mounted, - writable and the directory + writable, and the directory /var/log/journal - exists. Otherwise only the latter + exists. Otherwise, only the latter applies. Note that this means that during early boot and if the administrator disabled persistent - logging only the latter options apply, + logging, only the latter options apply, while the former apply if persistent logging is enabled and the system is fully booted @@ -293,23 +293,26 @@ The maximum time to store entries in a single journal - file, before rotating to the next - one. Normally time-based rotation + file before rotating to the next + one. Normally, time-based rotation should not be required as size-based rotation with options such as SystemMaxFileSize= should be sufficient to ensure that - journal files don't grow without + journal files do not grow without bounds. However, to ensure that not too much data is lost at once when old - journal files are deleted it might + journal files are deleted, it might make sense to change this value from the default of one month. Set to 0 to turn off this feature. This setting takes time values which may be - suffixed with the units year, month, - week, day, h, m to override the - default time unit of + suffixed with the units + year, + month, + week, day, + h or m + to override the default time unit of seconds. @@ -321,31 +324,34 @@ controls whether journal files containing entries older then the specified time span are - deleted. Normally time-based deletion + deleted. Normally, time-based deletion of old journal files should not be required as size-based deletion with options such as SystemMaxUse= should be sufficient to ensure that - journal files don't grow without + journal files do not grow without bounds. However, to enforce data - retention policies it might make sense + retention policies, it might make sense to change this value from the default of 0 (which turns off this feature). This setting also takes time values which may be suffixed with - the units year, month, week, day, h, m + the units year, + month, + week, day, + h or m to override the default time unit of - seconds. + seconds. SyncIntervalSec= - The timeout before syncing journal - data to disk. After syncing journal files have - OFFLINE state. Default timeout is 5 minutes. + The timeout before synchronizing journal + data to disk. After syncing, journal files have + the OFFLINE state. Default timeout is 5 minutes. @@ -362,8 +368,8 @@ system console. These options take boolean arguments. If forwarding to syslog is enabled but no syslog daemon - is running the respective option has - no effect. By default only forwarding + is running, the respective option has + no effect. By default, only forwarding to syslog is enabled. These settings may be overridden at boot time with the kernel command line options diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml index db5d38a741..a4b7d13c8d 100644 --- a/man/kernel-command-line.xml +++ b/man/kernel-command-line.xml @@ -59,7 +59,7 @@ kernel command line arguments. For command line parameters understood by the - kernel please see kernel-parameters.txt and bootparam7. @@ -93,7 +93,7 @@ Parameters understood by the system and service manager - to control system behavior. For details see + to control system behavior. For details, see systemd1. @@ -105,7 +105,7 @@ both the kernel and the system and service manager to control console log verbosity. For - details see + details, see systemd1. @@ -117,7 +117,7 @@ both the kernel and the system and service manager to control console log verbosity. For - details see + details, see systemd1. @@ -136,7 +136,7 @@ Parameters understood by the system and service manager, as compatibility - options. For details see + options. For details, see systemd1. @@ -160,7 +160,7 @@ Parameters understood by the system and service manager to control locale and language - settings. For details see + settings. For details, see systemd1. @@ -171,7 +171,7 @@ Parameter understood by the file system checker - services. For details see + services. For details, see systemd-fsck@.service8. @@ -182,7 +182,7 @@ Parameter understood by the file quota checker - service. For details see + service. For details, see systemd-quotacheck.service8. @@ -195,7 +195,7 @@ Parameters understood by the journal service. For - details see + details, see systemd-journald.service8. @@ -210,7 +210,7 @@ Parameters understood by the virtual console setup logic. For - details see + details, see systemd-vconsole-setup.service8. @@ -227,7 +227,7 @@ Parameters understood by the device event managing daemon. For - details see + details, see systemd-udevd.service8. @@ -238,7 +238,7 @@ May be used to disable the Plymouth boot splash. For - details see + details, see plymouth8. @@ -256,7 +256,7 @@ Configures the LUKS full-disk encryption logic at - boot. For details see + boot. For details, see systemd-cryptsetup-generator8. @@ -268,7 +268,7 @@ Configures the /etc/fstab - logic at boot. For details see + logic at boot. For details, see systemd-fstab-generator8. @@ -280,7 +280,7 @@ Load a specific kernel module early at boot. For - details see + details, see systemd-modules-load.service8. diff --git a/man/kernel-install.xml b/man/kernel-install.xml index d21d7579bf..929ceef4af 100644 --- a/man/kernel-install.xml +++ b/man/kernel-install.xml @@ -73,7 +73,7 @@ along with systemd; If not, see . executables with a local file if needed; a symbolic link in /etc/kernel/install.d/ with the same name as an executable in /usr/lib/kernel/install.d/, pointing to /dev/null, disables the executable entirely. Executables must have the - extension .install; other extensions are ignored. + extension .install; other extensions are ignored. @@ -112,7 +112,7 @@ add KERNEL-VERSION /boot/MACHI remove KERNEL-VERSION - calls every executable /usr/lib/kernel/install.d/*.install + Calls every executable /usr/lib/kernel/install.d/*.install and /etc/kernel/install.d/*.install with the arguments remove KERNEL-VERSION /boot/MACHINE-ID/KERNEL-VERSION/ @@ -145,7 +145,7 @@ remove KERNEL-VERSION /boot/MA /etc/kernel/install.d/*.install - Drop-in files, which are executed by kernel-install. + Drop-in files which are executed by kernel-install. diff --git a/man/locale.conf.xml b/man/locale.conf.xml index 42634febac..e97092102c 100644 --- a/man/locale.conf.xml +++ b/man/locale.conf.xml @@ -64,7 +64,7 @@ newline-separated list of environment-like shell-compatible variable assignments. It is possible to source the configuration from shell scripts, - however, beyond mere variable assignments no shell + however, beyond mere variable assignments, no shell features are supported, allowing applications to read the file without implementing a shell compatible execution engine. @@ -92,7 +92,7 @@ overridden or unset by individual programs or individual users. - Depending on the operating system other + Depending on the operating system, other configuration files might be checked for locale configuration as well, however only as fallback. @@ -132,7 +132,7 @@ /etc/locale.conf: LANG=de_DE.UTF-8 -LC_MESSAGES=C +LC_MESSAGES=en_US.UTF-8 diff --git a/man/localectl.xml b/man/localectl.xml index f14393071a..a3e07f6508 100644 --- a/man/localectl.xml +++ b/man/localectl.xml @@ -105,7 +105,7 @@ - Don't query the user + Do not query the user for authentication for privileged operations. @@ -188,7 +188,7 @@ one to define a toggle keyboard mapping. Unless is - passed the selected setting is also + passed, the selected setting is also applied to the default keyboard mapping of X11, after converting it to the closest matching X11 keyboard @@ -218,7 +218,7 @@ kbd4 for details. Unless is - passed the selected setting is also + passed, the selected setting is also applied to the system console keyboard mapping, after converting it to the closest matching console keyboard @@ -249,7 +249,7 @@ Exit status - On success 0 is returned, a non-zero failure + On success, 0 is returned, a non-zero failure code otherwise. diff --git a/man/localtime.xml b/man/localtime.xml index b95c2ee6be..b7fd1ba15d 100644 --- a/man/localtime.xml +++ b/man/localtime.xml @@ -74,9 +74,9 @@ tzfile5 timezone data for the configured timezone. - As the timezone identifier is extracted from + Because the timezone identifier is extracted from the symlink target name of - /etc/localtime this file may not + /etc/localtime, this file may not be a normal file or hardlink. The timezone may be overridden for individual diff --git a/man/loginctl.xml b/man/loginctl.xml index 790a3e4bf8..b9db475983 100644 --- a/man/loginctl.xml +++ b/man/loginctl.xml @@ -91,11 +91,11 @@ session/user properties, limit display to certain properties as specified as argument. If not - specified all set properties are + specified, all set properties are shown. The argument should be a property name, such as Sessions. If - specified more than once all + specified more than once, all properties with the specified names are shown. @@ -129,7 +129,7 @@ - Don't query the user + Do not query the user for authentication for privileged operations. @@ -161,7 +161,7 @@ SIGTERM, SIGINT or SIGSTOP. If - omitted defaults to + omitted, defaults to SIGTERM. @@ -214,14 +214,14 @@ Show properties of one or more sessions or the manager - itself. If no argument is specified + itself. If no argument is specified, properties of the manager will be - shown. If a session ID is specified + shown. If a session ID is specified, properties of the session is shown. By default, empty properties are suppressed. Use to show those too. To select specific - properties to show use + properties to show, use . This command is intended to be used whenever computer-parsable output is @@ -317,7 +317,7 @@ default, empty properties are suppressed. Use to show those too. To select specific - properties to show use + properties to show, use . This command is intended to be used whenever computer-parsable output is @@ -337,7 +337,7 @@ enabled for a specific user, a user manager is spawned for him/her at boot and kept around after - logouts. This allows users who aren't + logouts. This allows users who are not logged in to run long-running services. @@ -455,7 +455,7 @@ Exit status - On success 0 is returned, a non-zero failure + On success, 0 is returned, a non-zero failure code otherwise. diff --git a/man/logind.conf.xml b/man/logind.conf.xml index b7109353ca..74a100eb1e 100644 --- a/man/logind.conf.xml +++ b/man/logind.conf.xml @@ -54,7 +54,7 @@ Description - This file configures various parameters of the systemd login manager systemd-logind.service8. + This file configures various parameters of the systemd login manager, systemd-logind.service8. @@ -81,7 +81,7 @@ autovt@.service for the respective VT TTY name, e.g. autovt@tty4.service. By - default + default, autovt@.service is linked to getty@.service, @@ -92,7 +92,7 @@ gettys are available on the VTs. If a VT is already used by some other subsystem - (for example a graphical login) this + (for example a graphical login), this kind of activation will not be attempted. Note that the VT configured in ReserveVT= is @@ -103,7 +103,7 @@ directive. Defaults to 6. When set to 0, automatic spawning of autovt services is - disabled. + disabled. @@ -120,10 +120,10 @@ other subsystem will allocate it. This functionality is useful to ensure that regardless how many VTs are allocated - by other subsystems one login + by other subsystems, one login getty is always available. Defaults to 6 (with other - words: there'll always be a + words: there will always be a getty available on Alt-F6.). When set to 0, VT reservation is @@ -304,7 +304,7 @@ off, the inhibitor locks taken by applications in order to block the requested operation are - respected, if on, + respected. If on, the requested operation is executed in any case. PowerKeyIgnoreInhibited=, @@ -330,7 +330,7 @@ Note that KillUserProcesses=1 is a weaker version of - kill-session-processes=1 which may + kill-session-processes=1, which may be configured per-service for pam_systemd8. The latter kills processes of a session as soon as it diff --git a/man/machine-id.xml b/man/machine-id.xml index d7a56cb548..b037e47c01 100644 --- a/man/machine-id.xml +++ b/man/machine-id.xml @@ -65,7 +65,7 @@ The machine ID is usually generated from a random source during system installation and stays constant for all subsequent boots. Optionally, for - stateless systems it is generated during runtime at + stateless systems, it is generated during runtime at boot if it is found to be empty. The machine ID does not change based on user @@ -113,7 +113,7 @@ id[8] = (id[8] & 0x3F) | 0x80; (This code is inspired by generate_random_uuid() of drivers/char/random.c from the - kernel sources.) + Linux kernel sources.) @@ -123,7 +123,7 @@ id[8] = (id[8] & 0x3F) | 0x80; The simple configuration file format of /etc/machine-id originates in the /var/lib/dbus/machine-id file - introduced by D-Bus. In fact this latter file might be a + introduced by D-Bus. In fact, this latter file might be a symlink to /etc/machine-id. diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index 1fd609dc85..4f0bd64b12 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -797,7 +797,7 @@ highly recommended to leave this option enabled for the majority of common units. If set to - this option + , this option does not disable all implicit dependencies, just non-essential ones. -- cgit v1.2.1 From 286ca4852eb2efc5c8c405e585b4e886c538f538 Mon Sep 17 00:00:00 2001 From: David Coppa Date: Wed, 3 Jul 2013 09:38:35 +0200 Subject: build-sys: rename LEGACY to NOLEGACY to better reflect meaning https://bugs.freedesktop.org/show_bug.cgi?id=66542 --- src/cgroups-agent/cgroups-agent.c | 4 ++-- src/systemctl/systemctl.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cgroups-agent/cgroups-agent.c b/src/cgroups-agent/cgroups-agent.c index 7a6173e2a2..0e3d2b7541 100644 --- a/src/cgroups-agent/cgroups-agent.c +++ b/src/cgroups-agent/cgroups-agent.c @@ -49,7 +49,7 @@ int main(int argc, char *argv[]) { * are called when the dbus service is shut down. */ if (!(bus = dbus_connection_open_private("unix:path=/run/systemd/private", &error))) { -#ifndef LEGACY +#ifndef NOLEGACY dbus_error_free(&error); /* Retry with the pre v21 socket name, to ease upgrades */ @@ -58,7 +58,7 @@ int main(int argc, char *argv[]) { log_error("Failed to get D-Bus connection: %s", bus_error_message(&error)); goto finish; } -#ifndef LEGACY +#ifndef NOLEGACY } #endif diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 7436d4e875..04464deec8 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -1565,7 +1565,7 @@ static DBusHandlerResult wait_filter(DBusConnection *connection, DBusMessage *me return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -#ifndef LEGACY +#ifndef NOLEGACY dbus_error_free(&error); if (dbus_message_get_args(message, &error, DBUS_TYPE_UINT32, &id, @@ -2916,7 +2916,7 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn i->fragment_path = s; else if (streq(name, "SourcePath")) i->source_path = s; -#ifndef LEGACY +#ifndef NOLEGACY else if (streq(name, "DefaultControlGroup")) { const char *e; e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":"); -- cgit v1.2.1 From 943aca8efb39453e3994ccdd1e08534b788c5aee Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 3 Jul 2013 15:12:58 +0200 Subject: logind/machined: properly notice when units are gc'ed --- src/login/logind-dbus.c | 38 ++++++++++++++++++++++++++++++++++++++ src/login/logind.c | 12 ++++++++++++ src/machine/machined-dbus.c | 22 +++++++++++++++++++++- src/machine/machined.c | 12 ++++++++++++ 4 files changed, 83 insertions(+), 1 deletion(-) diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index a52f020b34..eeff84394e 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -2411,6 +2411,44 @@ DBusHandlerResult bus_message_filter( if (u) user_add_to_gc_queue(u); } + } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Manager", "UnitRemoved")) { + + const char *path, *unit; + Session *session; + User *user; + + if (!dbus_message_get_args(message, &error, + DBUS_TYPE_STRING, &unit, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse UnitRemoved message: %s", bus_error_message(&error)); + goto finish; + } + + session = hashmap_get(m->session_units, unit); + if (session) { + hashmap_remove(m->session_units, session->scope); + free(session->scope); + session->scope = NULL; + + session_add_to_gc_queue(session); + } + + user = hashmap_get(m->user_units, unit); + if (user) { + + if (streq_ptr(unit, user->service)) { + hashmap_remove(m->user_units, user->service); + free(user->service); + user->service = NULL; + } else if (streq_ptr(unit, user->slice)) { + hashmap_remove(m->user_units, user->slice); + free(user->slice); + user->slice = NULL; + } + + user_add_to_gc_queue(user); + } } finish: diff --git a/src/login/logind.c b/src/login/logind.c index e37a1071a2..fcb3ccf4a5 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -1020,6 +1020,18 @@ static int manager_connect_bus(Manager *m) { dbus_error_free(&error); } + dbus_bus_add_match(m->bus, + "type='signal'," + "sender='org.freedesktop.systemd1'," + "interface='org.freedesktop.systemd1.Manager'," + "member='UnitRemoved'," + "path='/org/freedesktop/systemd1'", + &error); + if (dbus_error_is_set(&error)) { + log_error("Failed to add match for UnitRemoved: %s", bus_error_message(&error)); + dbus_error_free(&error); + } + dbus_bus_add_match(m->bus, "type='signal'," "sender='org.freedesktop.systemd1'," diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c index a81f37c5ca..1b1eb3a333 100644 --- a/src/machine/machined-dbus.c +++ b/src/machine/machined-dbus.c @@ -531,7 +531,6 @@ DBusHandlerResult bus_message_filter( goto finish; } - mm = hashmap_get(m->machine_units, unit); if (mm) { if (streq_ptr(path, mm->scope_job)) { @@ -570,6 +569,27 @@ DBusHandlerResult bus_message_filter( if (mm) machine_add_to_gc_queue(mm); } + + } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Manager", "UnitRemoved")) { + const char *path, *unit; + Machine *mm; + + if (!dbus_message_get_args(message, &error, + DBUS_TYPE_STRING, &unit, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse UnitRemoved message: %s", bus_error_message(&error)); + goto finish; + } + + mm = hashmap_get(m->machine_units, unit); + if (mm) { + hashmap_remove(m->machine_units, mm->scope); + free(mm->scope); + mm->scope = NULL; + + machine_add_to_gc_queue(mm); + } } finish: diff --git a/src/machine/machined.c b/src/machine/machined.c index 86f8de9195..f2803a18c9 100644 --- a/src/machine/machined.c +++ b/src/machine/machined.c @@ -210,6 +210,18 @@ static int manager_connect_bus(Manager *m) { dbus_error_free(&error); } + dbus_bus_add_match(m->bus, + "type='signal'," + "sender='org.freedesktop.systemd1'," + "interface='org.freedesktop.systemd1.Manager'," + "member='UnitRemoved'," + "path='/org/freedesktop/systemd1'", + &error); + if (dbus_error_is_set(&error)) { + log_error("Failed to add match for UnitRemoved: %s", bus_error_message(&error)); + dbus_error_free(&error); + } + dbus_bus_add_match(m->bus, "type='signal'," "sender='org.freedesktop.systemd1'," -- cgit v1.2.1 From 00aa832b948a27507c33e2157e46963852cffc85 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 3 Jul 2013 16:33:53 +0200 Subject: build-sys: prepare v205 --- NEWS | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 2 +- 2 files changed, 140 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 1b3bc2b65b..adfd3b7e3f 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,144 @@ systemd System and Service Manager +CHANGES WITH 205: + + * Two new unit types have been introduced: + + Scope units are very similar to service units, however, are + created out of pre-existing processes -- instead of PID 1 + forking off the processes. By using scope units it is + possible for system services and applications to group their + own child processes (worker processes) in a powerful way + which then maybe used to organize them, or kill them + together, or apply resource limits on them. + + Slice units may be used to partition system resources in an + hierarchial fashion and then assign other units to them. By + default there are now three slices: system.slice (for all + system services), user.slice (for all user sessions), + machine.slice (for VMs and containers). + + Slices and scopes have been introduced primarily in + context of the work to move cgroup handling to a + single-writer scheme, where only PID 1 + creates/removes/manages cgroups. + + * There's a new concept of "transient" units. In contrast to + normal units these units are created via an API at runtime, + not from configuration from disk. More specifically this + means it is now possible to run arbitrary programs as + independent services, with all execution parameters passed + in via bus APIs rather than read from disk. Transient units + make systemd substantially more dynamic then it ever was, + and useful as a general batch manager. + + * logind has been updated to make use of scope and slice units + for managing user sessions. As a user logs in he will get + his own private slice unit, to which all sessions are added + as scope units. We also added support for automatically + adding an instance of user@.service for the user into the + slice. Effectively logind will no longer create cgroup + hierarchies on its own now, it will defer entirely to PID 1 + for this by means of scope, service and slice units. Since + user sessions this way become entities managed by PID 1 + the output of "systemctl" is now a lot more comprehensive. + + * A new mini-daemon "systemd-machined" has been added which + may be used by virtualization managers to register local + VMs/containers. nspawn has been updated accordingly, and + libvirt will be updated shortly. machined will collect a bit + of meta information about the VMs/containers, and assign + them their own scope unit (see above). The collected + meta-data is then made available via the "machinectl" tool, + and exposed in "ps" and similar tools. machined/machinectl + is compile-time optional. + + * As discussed earlier, the low-level cgroup configuration + options ControlGroup=, ControlGroupModify=, + ControlGroupPersistent=, ControlGroupAttribute= have been + removed. Please use high-level attribute settings instead as + well as slice units. + + * A new bus call SetUnitProperties() has been added to alter + various runtime parameters of a unit. This is primarily + useful to alter cgroup parameters dynamically in a nice way, + but will be extended later on to make more properties + modifiable at runtime. systemctl gained a new set-properties + command that wraps this call. + + * A new tool "systemd-run" has been added which can be used to + run arbitrary command lines as transient services or scopes, + while configuring a number of settings via the command + line. This tool is currently very basic, however already + very useful. We plan to extend this tool to even allow + queuing of execution jobs with time triggers from the + command line, similar in fashion to "at". + + * nspawn will now inform the user explicitly that kernels with + audit enabled break containers, and suggest the user to turn + off audit. + + * Support for detecting the IMA and AppArmor security + frameworks with ConditionSecurity= has been added. + + * journalctl gained a new "-k" switch for showing only kernel + messages. + + * systemd-delta can now show information about drop-in + snippets extending unit files. + + * libsystemd-bus has been substantially updated but is still + not available as public API. + + * systemd will now look for the "debug" argument on the kernel + command line and enable debug logging, similar to + "systemd.log_level=debug" already did before. + + * "systemctl set-default", "systemctl get-default" has been + added to configure the default.target symlink, which + controls what to boot into by default. + + * "systemd-analyze plot" will now show the time the various + generators needed for execution, as well as information + about the unit file loading. + + * journalctl gained new "--user" and "--system" switches to + only show user/system logs. + + * libsystemd-journal gained a new sd_journal_open_files() call + for opening specific journal files. journactl also gained a + new switch to expose this new functionality. Previously we + only supported opening all files from a directory, or all + files from the system, as opening individual files only is + racy due to journal file rotation. + + * systemd gained the new DefaultEnvironment= setting in + /etc/systemd/system.conf to set environment variables for + all services. + + * If a privileged process logs a journal message with the + OBJECT_PID= field set, then journald will automatically + augment this with additional OBJECT_UID=, OBJECT_GID=, + OBJECT_COMM=, OBJECT_EXE=, ... fields. This is useful if + system services want to log events about specific client + processes. journactl/systemctl has been updated to make use + of this information if all log messages regarding a specific + unit is requested. + + Contributions from: Auke Kok, Chengwei Yang, Colin Walters, + Cristian Rodríguez, Daniel Albers, Daniel Wallace, Dave + Reisner, David Coppa, David King, David Strauss, Eelco + Dolstra, Gabriel de Perthuis, Harald Hoyer, Jan Alexander + Steffens, Jan Engelhardt, Jan Janssen, Jason St. John, Johan + Heikkilä, Karel Zak, Karol Lewandowski, Kay Sievers, Lennart + Poettering, Lukas Nykryn, Mantas Mikulėnas, Marius Vollmer, + Martin Pitt, Michael Biebl, Michael Olbrich, Michael Tremer, + Michal Schmidt, Michał Bartoszkiewicz, Nirbheek Chauhan, + Pierre Neidhardt, Ross Burton, Ross Lagerwall, Sean McGovern, + Thomas Hindoe Paaboel Andersen, Tom Gundersen, Umut Tezduyar, + Václav Pavlín, Zachary Cook, Zbigniew Jędrzejewski-Szmek, + Łukasz Stelmach, 장동준 + CHANGES WITH 204: * The Python bindings gained some minimal support for the APIs diff --git a/configure.ac b/configure.ac index 0881e47365..6fd5307c7f 100644 --- a/configure.ac +++ b/configure.ac @@ -20,7 +20,7 @@ AC_PREREQ([2.64]) AC_INIT([systemd], - [204], + [205], [http://bugs.freedesktop.org/enter_bug.cgi?product=systemd], [systemd], [http://www.freedesktop.org/wiki/Software/systemd]) -- cgit v1.2.1 From c01995635d14840074c2ff17a153b76edd0bf1b9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 3 Jul 2013 16:37:39 +0200 Subject: build-sys: bump/correct library versions --- Makefile.am | 14 +++++++------- src/login/libsystemd-login.sym | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Makefile.am b/Makefile.am index b2573199dc..e7b9959f75 100644 --- a/Makefile.am +++ b/Makefile.am @@ -32,16 +32,16 @@ SUBDIRS = . po .SECONDARY: LIBUDEV_CURRENT=4 -LIBUDEV_REVISION=5 +LIBUDEV_REVISION=6 LIBUDEV_AGE=3 LIBGUDEV_CURRENT=1 LIBGUDEV_REVISION=3 LIBGUDEV_AGE=1 -LIBSYSTEMD_LOGIN_CURRENT=7 -LIBSYSTEMD_LOGIN_REVISION=1 -LIBSYSTEMD_LOGIN_AGE=7 +LIBSYSTEMD_LOGIN_CURRENT=8 +LIBSYSTEMD_LOGIN_REVISION=0 +LIBSYSTEMD_LOGIN_AGE=8 LIBSYSTEMD_DAEMON_CURRENT=0 LIBSYSTEMD_DAEMON_REVISION=10 @@ -51,9 +51,9 @@ LIBSYSTEMD_ID128_CURRENT=0 LIBSYSTEMD_ID128_REVISION=23 LIBSYSTEMD_ID128_AGE=0 -LIBSYSTEMD_JOURNAL_CURRENT=10 -LIBSYSTEMD_JOURNAL_REVISION=2 -LIBSYSTEMD_JOURNAL_AGE=10 +LIBSYSTEMD_JOURNAL_CURRENT=11 +LIBSYSTEMD_JOURNAL_REVISION=0 +LIBSYSTEMD_JOURNAL_AGE=11 # Dirs of external packages dbuspolicydir=@dbuspolicydir@ diff --git a/src/login/libsystemd-login.sym b/src/login/libsystemd-login.sym index 417dbb18dc..0720704dbf 100644 --- a/src/login/libsystemd-login.sym +++ b/src/login/libsystemd-login.sym @@ -76,7 +76,7 @@ global: sd_get_machine_names; } LIBSYSTEMD_LOGIN_202; -LIBSYSTEMD_LOGIN_204 { +LIBSYSTEMD_LOGIN_205 { global: sd_pid_get_slice; } LIBSYSTEMD_LOGIN_203; -- cgit v1.2.1 From 1fda0ab5fc9cf7454c8da32941e433dc38ba9991 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 3 Jul 2013 11:20:17 -0400 Subject: NEWS: mention set-log-level, --user, --system --- NEWS | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index adfd3b7e3f..6ff70d9ddd 100644 --- a/NEWS +++ b/NEWS @@ -82,7 +82,9 @@ CHANGES WITH 205: frameworks with ConditionSecurity= has been added. * journalctl gained a new "-k" switch for showing only kernel - messages. + messages, mimicking dmesg output; in addition to "--user" + and "--system" switches for showing only user's own logs + and system logs. * systemd-delta can now show information about drop-in snippets extending unit files. @@ -98,6 +100,9 @@ CHANGES WITH 205: added to configure the default.target symlink, which controls what to boot into by default. + * "systemctl set-log-level" has been added as a convenient + way to raise and lower systemd logging threshold. + * "systemd-analyze plot" will now show the time the various generators needed for execution, as well as information about the unit file loading. -- cgit v1.2.1 From 174da5c5cabbaf3f3a8fc1f14bd6a3b50b2ea278 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 3 Jul 2013 16:49:54 +0200 Subject: update TODO --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index 00f22d592e..7a1df651f6 100644 --- a/TODO +++ b/TODO @@ -28,6 +28,8 @@ Fedora 19: Features: +* move systemctl set-log-level to systemd-analyze? + * fix killing spree logic in systemd-user-sessions * logind: implement session kill exceptions -- cgit v1.2.1 From 34627e3f0de6b676c8e7495eada290312769243f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 3 Jul 2013 17:49:43 +0200 Subject: NEWS: no need to mention journalctl --user/--system twice --- NEWS | 3 --- 1 file changed, 3 deletions(-) diff --git a/NEWS b/NEWS index 6ff70d9ddd..5560355b90 100644 --- a/NEWS +++ b/NEWS @@ -107,9 +107,6 @@ CHANGES WITH 205: generators needed for execution, as well as information about the unit file loading. - * journalctl gained new "--user" and "--system" switches to - only show user/system logs. - * libsystemd-journal gained a new sd_journal_open_files() call for opening specific journal files. journactl also gained a new switch to expose this new functionality. Previously we -- cgit v1.2.1 From b0adb5468cccf32da1365c2e8f97b2b233c4fa30 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 4 Jul 2013 01:09:04 +0200 Subject: update TODO --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index 7a1df651f6..d1bc805050 100644 --- a/TODO +++ b/TODO @@ -28,6 +28,8 @@ Fedora 19: Features: +* when a kernel driver logs in a tight loop we should ratelimit that too. + * move systemctl set-log-level to systemd-analyze? * fix killing spree logic in systemd-user-sessions -- cgit v1.2.1 From 1e4fc9b1d8449e87474b3af8a4ddab09fab27cd5 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Thu, 4 Jul 2013 11:01:47 +0200 Subject: core/mount.c:mount_dump(): don't segfault, if mount is not mounted anymore Don't segfault, if m->from_proc_self_mountinfo and m->from_fragment is false. https://bugzilla.redhat.com/show_bug.cgi?id=957783#c9 --- src/core/mount.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/mount.c b/src/core/mount.c index 3cc3e65b23..58a3f1160f 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -822,9 +822,9 @@ static void mount_dump(Unit *u, FILE *f, const char *prefix) { prefix, mount_state_to_string(m->state), prefix, mount_result_to_string(m->result), prefix, m->where, - prefix, strna(p->what), - prefix, strna(p->fstype), - prefix, strna(p->options), + prefix, p ? strna(p->what) : "n/a", + prefix, p ? strna(p->fstype) : "n/a", + prefix, p ? strna(p->options) : "n/a", prefix, yes_no(m->from_proc_self_mountinfo), prefix, yes_no(m->from_fragment), prefix, m->directory_mode); -- cgit v1.2.1 From 0da26ab51bf61e7a14b5e899326cf9cfa513ca52 Mon Sep 17 00:00:00 2001 From: William Giokas <1007380@gmail.com> Date: Wed, 3 Jul 2013 18:00:46 -0500 Subject: po: add dbus-scope.c to POTFILES.skip --- po/POTFILES.skip | 1 + 1 file changed, 1 insertion(+) diff --git a/po/POTFILES.skip b/po/POTFILES.skip index 65327aaca5..b552029b82 100644 --- a/po/POTFILES.skip +++ b/po/POTFILES.skip @@ -12,6 +12,7 @@ src/core/dbus-swap.c src/core/dbus-target.c src/core/dbus-timer.c src/core/dbus-unit.c +src/core/dbus-scope.c src/hostname/hostnamed.c src/locale/localed.c src/core/org.freedesktop.systemd1.policy.in -- cgit v1.2.1 From ad929bcc27e2c6c1aa731053e45882686e9babab Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 4 Jul 2013 20:31:18 +0200 Subject: disable the cgroups release agent when shutting down During shutdown, when we try to clean up all remaining processes, the kernel will fork new agents every time a cgroup runs empty. These new processes cause delays in the final SIGTERM, SIGKILL logic. Apart from that, this should also avoid that the kernel-forked binaries cause unpredictably timed access to the filesystem which we might need to unmount. --- src/core/main.c | 4 ++++ src/shared/cgroup-util.c | 15 +++++++++++++++ src/shared/cgroup-util.h | 1 + 3 files changed, 20 insertions(+) diff --git a/src/core/main.c b/src/core/main.c index 8b8e110f24..ada0f9d94b 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1942,6 +1942,10 @@ finish: watchdog_close(true); } + /* avoid the creation of new processes forked by the kernel; at this + * point, we will not listen to the signals anyway */ + cg_uninstall_release_agent(SYSTEMD_CGROUP_CONTROLLER); + execve(SYSTEMD_SHUTDOWN_BINARY_PATH, (char **) command_line, env_block); free(env_block); log_error("Failed to execute shutdown binary, freezing: %m"); diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index 390259e3e4..73013d1d97 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -790,6 +790,21 @@ int cg_install_release_agent(const char *controller, const char *agent) { return 0; } +int cg_uninstall_release_agent(const char *controller) { + _cleanup_free_ char *fs = NULL; + int r; + + r = cg_get_path(controller, NULL, "release_agent", &fs); + if (r < 0) + return r; + + r = write_string_file(fs, ""); + if (r < 0) + return r; + + return 0; +} + int cg_is_empty(const char *controller, const char *path, bool ignore_self) { _cleanup_fclose_ FILE *f = NULL; pid_t pid = 0, self_pid; diff --git a/src/shared/cgroup-util.h b/src/shared/cgroup-util.h index c781aabb22..0fc93c12c8 100644 --- a/src/shared/cgroup-util.h +++ b/src/shared/cgroup-util.h @@ -89,6 +89,7 @@ int cg_set_group_access(const char *controller, const char *path, mode_t mode, u int cg_set_task_access(const char *controller, const char *path, mode_t mode, uid_t uid, gid_t gid); int cg_install_release_agent(const char *controller, const char *agent); +int cg_uninstall_release_agent(const char *controller); int cg_is_empty(const char *controller, const char *path, bool ignore_self); int cg_is_empty_by_spec(const char *spec, bool ignore_self); -- cgit v1.2.1 From c1eba3008cac9e625b8bb774e9b44ceec8465980 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 4 Jul 2013 20:54:40 +0200 Subject: cgroups-agent: remove ancient fallback code; turn connection error into warning During re-execution and shutdown cgroups agents might not be able to connect to systemd's private D-Bus socket, the printed error to the console is misleding in that case, so turn it into a warning. --- src/cgroups-agent/cgroups-agent.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/cgroups-agent/cgroups-agent.c b/src/cgroups-agent/cgroups-agent.c index 0e3d2b7541..a47949a180 100644 --- a/src/cgroups-agent/cgroups-agent.c +++ b/src/cgroups-agent/cgroups-agent.c @@ -48,26 +48,19 @@ int main(int argc, char *argv[]) { * this to avoid an activation loop when we start dbus when we * are called when the dbus service is shut down. */ - if (!(bus = dbus_connection_open_private("unix:path=/run/systemd/private", &error))) { -#ifndef NOLEGACY - dbus_error_free(&error); - - /* Retry with the pre v21 socket name, to ease upgrades */ - if (!(bus = dbus_connection_open_private("unix:abstract=/org/freedesktop/systemd1/private", &error))) { -#endif - log_error("Failed to get D-Bus connection: %s", bus_error_message(&error)); - goto finish; - } -#ifndef NOLEGACY + bus = dbus_connection_open_private("unix:path=/run/systemd/private", &error); + if (!bus) { + log_warning("Failed to get D-Bus connection: %s", bus_error_message(&error)); + goto finish; } -#endif if (bus_check_peercred(bus) < 0) { log_error("Bus owner not root."); goto finish; } - if (!(m = dbus_message_new_signal("/org/freedesktop/systemd1/agent", "org.freedesktop.systemd1.Agent", "Released"))) { + m = dbus_message_new_signal("/org/freedesktop/systemd1/agent", "org.freedesktop.systemd1.Agent", "Released"); + if (!m) { log_error("Could not allocate signal message."); goto finish; } -- cgit v1.2.1 From ec26be514ff3c5367b21f9881369080bda54fd2d Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 5 Jul 2013 00:32:05 +0200 Subject: suppress status message output at shutdown when 'quiet' is given --- src/core/main.c | 4 ++-- src/core/shutdown.c | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index ada0f9d94b..243855fa15 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1942,9 +1942,9 @@ finish: watchdog_close(true); } - /* avoid the creation of new processes forked by the kernel; at this + /* avoid the creation of new processes forked by the kernel; at this * point, we will not listen to the signals anyway */ - cg_uninstall_release_agent(SYSTEMD_CGROUP_CONTROLLER); + cg_uninstall_release_agent(SYSTEMD_CGROUP_CONTROLLER); execve(SYSTEMD_SHUTDOWN_BINARY_PATH, (char **) command_line, env_block); free(env_block); diff --git a/src/core/shutdown.c b/src/core/shutdown.c index 2db761de36..c02a14d66e 100644 --- a/src/core/shutdown.c +++ b/src/core/shutdown.c @@ -39,6 +39,7 @@ #include "missing.h" #include "log.h" +#include "fileio.h" #include "umount.h" #include "util.h" #include "mkdir.h" @@ -130,12 +131,26 @@ static int pivot_to_new_root(void) { } int main(int argc, char *argv[]) { + _cleanup_free_ char *line = NULL; int cmd, r; unsigned retries; bool need_umount = true, need_swapoff = true, need_loop_detach = true, need_dm_detach = true; bool in_container, use_watchdog = false; char *arguments[3]; + /* suppress shutdown status output if 'quiet' is used */ + r = read_one_line_file("/proc/cmdline", &line); + if (r >= 0) { + char *w, *state; + size_t l; + + FOREACH_WORD_QUOTED(w, l, line, state) + if (streq(w, "quiet")) { + log_set_max_level(LOG_WARNING); + break; + } + } + log_parse_environment(); log_set_target(LOG_TARGET_CONSOLE); /* syslog will die if not gone yet */ log_open(); -- cgit v1.2.1 From a8b409dbc9e1e853a0f92d92603d9bb74592b1ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 5 Jul 2013 00:25:26 -0400 Subject: tests: add tests for string lookup tables The tests check if the tables have entries for all values in the enum, and that the entries are unique. --- .gitignore | 3 ++ Makefile.am | 103 ++++++++++++++++++++++++++++++-------- src/core/condition.c | 2 + src/login/test-login-tables.c | 35 +++++++++++++ src/machine/test-machine-tables.c | 30 +++++++++++ src/shared/test-tables.h | 46 +++++++++++++++++ src/test/test-tables.c | 102 +++++++++++++++++++++++++++++++++++++ 7 files changed, 301 insertions(+), 20 deletions(-) create mode 100644 src/login/test-login-tables.c create mode 100644 src/machine/test-machine-tables.c create mode 100644 src/shared/test-tables.h create mode 100644 src/test/test-tables.c diff --git a/.gitignore b/.gitignore index ae756c49ef..5f9ba906a4 100644 --- a/.gitignore +++ b/.gitignore @@ -134,6 +134,9 @@ /test-strbuf /test-strv /test-strxcpyx +/test-tables +/test-login-tables +/test-machine-tables /test-time /test-udev /test-unit-file diff --git a/Makefile.am b/Makefile.am index e7b9959f75..290ec1eb60 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1115,7 +1115,8 @@ tests += \ test-fileio \ test-time \ test-hashmap \ - test-list + test-list \ + test-tables EXTRA_DIST += \ test/sched_idle_bad.service \ @@ -1228,6 +1229,18 @@ test_list_CFLAGS = \ test_list_LDADD = \ libsystemd-core.la +test_tables_SOURCES = \ + src/test/test-tables.c \ + src/shared/test-tables.h + +test_tables_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +test_tables_LDADD = \ + libsystemd-core.la \ + libsystemd-logs.la + test_prioq_SOURCES = \ src/test/test-prioq.c @@ -3583,17 +3596,29 @@ endif if ENABLE_MACHINED systemd_machined_SOURCES = \ src/machine/machined.c \ - src/machine/machined.h \ + src/machine/machined.h + +systemd_machined_CFLAGS = \ + $(libsystemd_machine_core_la_CFLAGS) + +systemd_machined_LDADD = \ + libsystemd-machine-core.la \ + $(libsystemd_machine_core_la_LIBADD) + +rootlibexec_PROGRAMS += \ + systemd-machined + +libsystemd_machine_core_la_SOURCES = \ src/machine/machined-dbus.c \ src/machine/machine.c \ src/machine/machine.h \ src/machine/machine-dbus.c -systemd_machined_CFLAGS = \ +libsystemd_machine_core_la_CFLAGS = \ $(AM_CFLAGS) \ $(DBUS_CFLAGS) -systemd_machined_LDADD = \ +libsystemd_machine_core_la_LIBADD = \ libsystemd-label.la \ libsystemd-audit.la \ libsystemd-shared.la \ @@ -3602,8 +3627,8 @@ systemd_machined_LDADD = \ libsystemd-id128-internal.la \ libudev.la -rootlibexec_PROGRAMS += \ - systemd-machined +noinst_LTLIBRARIES += \ + libsystemd-machine-core.la machinectl_SOURCES = \ src/machine/machinectl.c @@ -3620,6 +3645,19 @@ machinectl_LDADD = \ rootbin_PROGRAMS += \ machinectl +test_machine_tables_SOURCES = \ + src/machine/test-machine-tables.c + +test_machine_tables_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +test_machine_tables_LDADD = \ + libsystemd-machine-core.la + +tests += \ + test-machine-tables + nodist_systemunit_DATA += \ units/systemd-machined.service @@ -3644,7 +3682,27 @@ endif if ENABLE_LOGIND systemd_logind_SOURCES = \ src/login/logind.c \ - src/login/logind.h \ + src/login/logind.h + +nodist_systemd_logind_SOURCES = \ + src/login/logind-gperf.c + +systemd_logind_CFLAGS = \ + $(libsystemd_logind_core_la_CFLAGS) + +systemd_logind_LDADD = \ + libsystemd-logind-core.la \ + $(libsystemd_logind_core_la_LIBADD) + +if HAVE_ACL +systemd_logind_SOURCES += \ + src/login/logind-acl.c + +systemd_logind_LDADD += \ + libsystemd-acl.la +endif + +libsystemd_logind_core_la_SOURCES = \ src/login/logind-dbus.c \ src/login/logind-device.c \ src/login/logind-device.h \ @@ -3665,14 +3723,11 @@ systemd_logind_SOURCES = \ src/login/logind-user-dbus.c \ src/login/logind-acl.h -nodist_systemd_logind_SOURCES = \ - src/login/logind-gperf.c - -systemd_logind_CFLAGS = \ +libsystemd_logind_core_la_CFLAGS = \ $(AM_CFLAGS) \ - $(DBUS_CFLAGS) + $(DBUS_CFLAGS) -systemd_logind_LDADD = \ +libsystemd_logind_core_la_LIBADD = \ libsystemd-label.la \ libsystemd-audit.la \ libsystemd-shared.la \ @@ -3681,13 +3736,8 @@ systemd_logind_LDADD = \ libsystemd-id128-internal.la \ libudev.la -if HAVE_ACL -systemd_logind_SOURCES += \ - src/login/logind-acl.c - -systemd_logind_LDADD += \ - libsystemd-acl.la -endif +noinst_LTLIBRARIES += \ + libsystemd-logind-core.la systemd_user_sessions_SOURCES = \ src/login/user-sessions.c @@ -3750,10 +3800,23 @@ test_inhibit_CFLAGS = \ $(AM_CFLAGS) \ $(DBUS_CFLAGS) +test_login_tables_SOURCES = \ + src/login/test-login-tables.c + +test_login_tables_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +test_login_tables_LDADD = \ + libsystemd-logind-core.la + manual_tests += \ test-login \ test-inhibit +tests += \ + test-login-tables + libsystemd_login_la_SOURCES = \ src/login/sd-login.c diff --git a/src/core/condition.c b/src/core/condition.c index b2617ef5bf..427aa080ad 100644 --- a/src/core/condition.c +++ b/src/core/condition.c @@ -391,9 +391,11 @@ static const char* const condition_type_table[_CONDITION_TYPE_MAX] = { [CONDITION_PATH_IS_READ_WRITE] = "ConditionPathIsReadWrite", [CONDITION_DIRECTORY_NOT_EMPTY] = "ConditionDirectoryNotEmpty", [CONDITION_FILE_NOT_EMPTY] = "ConditionFileNotEmpty", + [CONDITION_FILE_IS_EXECUTABLE] = "ConditionFileIsExecutable", [CONDITION_KERNEL_COMMAND_LINE] = "ConditionKernelCommandLine", [CONDITION_VIRTUALIZATION] = "ConditionVirtualization", [CONDITION_SECURITY] = "ConditionSecurity", + [CONDITION_CAPABILITY] = "ConditionCapability", [CONDITION_HOST] = "ConditionHost", [CONDITION_AC_POWER] = "ConditionACPower", [CONDITION_NULL] = "ConditionNull" diff --git a/src/login/test-login-tables.c b/src/login/test-login-tables.c new file mode 100644 index 0000000000..a4196bf14b --- /dev/null +++ b/src/login/test-login-tables.c @@ -0,0 +1,35 @@ +/*** + This file is part of systemd + + Copyright 2013 Zbigniew Jędrzejewski-Szmek + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include "logind-action.h" +#include "logind-session.h" + +#include "test-tables.h" + +int main(int argc, char **argv) { + test_table(handle_action, HANDLE_ACTION); + test_table(inhibit_mode, INHIBIT_MODE); + test_table(kill_who, KILL_WHO); + test_table(session_class, SESSION_CLASS); + test_table(session_state, SESSION_STATE); + test_table(session_type, SESSION_TYPE); + test_table(user_state, USER_STATE); + + return EXIT_SUCCESS; +} diff --git a/src/machine/test-machine-tables.c b/src/machine/test-machine-tables.c new file mode 100644 index 0000000000..4aae426050 --- /dev/null +++ b/src/machine/test-machine-tables.c @@ -0,0 +1,30 @@ +/*** + This file is part of systemd + + Copyright 2013 Zbigniew Jędrzejewski-Szmek + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include "machine.h" + +#include "test-tables.h" + +int main(int argc, char **argv) { + test_table(machine_class, MACHINE_CLASS); + test_table(machine_state, MACHINE_STATE); + test_table(kill_who, KILL_WHO); + + return EXIT_SUCCESS; +} diff --git a/src/shared/test-tables.h b/src/shared/test-tables.h new file mode 100644 index 0000000000..ac7deda39b --- /dev/null +++ b/src/shared/test-tables.h @@ -0,0 +1,46 @@ +/*** + This file is part of systemd + + Copyright 2013 Zbigniew Jędrzejewski-Szmek + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include + +typedef const char* (*lookup_t)(int); +typedef int (*reverse_t)(const char*); + +static inline void _test_table(const char *name, + lookup_t lookup, + reverse_t reverse, + int size) { + int i; + + for (i = 0; i < size; i++) { + const char* val = lookup(i); + int rev = -1; + + if (val) + rev = reverse(val); + + printf("%s: %d → %s → %d\n", name, i, val, rev); + if (!val || rev != i) + exit(EXIT_FAILURE); + } +} + +#define test_table(lower, upper) \ + _test_table(STRINGIFY(lower), lower##_to_string, lower##_from_string, _##upper##_MAX) diff --git a/src/test/test-tables.c b/src/test/test-tables.c new file mode 100644 index 0000000000..dff6431b6d --- /dev/null +++ b/src/test/test-tables.c @@ -0,0 +1,102 @@ +/*** + This file is part of systemd + + Copyright 2013 Zbigniew Jędrzejewski-Szmek + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include "automount.h" +#include "cgroup.h" +#include "condition.h" +#include "device.h" +#include "execute.h" +#include "exit-status.h" +#include "install.h" +#include "job.h" +#include "kill.h" +#include "log.h" +#include "logs-show.h" +#include "mount.h" +#include "path-lookup.h" +#include "path.h" +#include "scope.h" +#include "service.h" +#include "slice.h" +#include "snapshot.h" +#include "socket-util.h" +#include "socket.h" +#include "swap.h" +#include "target.h" +#include "timer.h" +#include "unit-name.h" +#include "unit.h" +#include "util.h" + +#include "test-tables.h" + +int main(int argc, char **argv) { + test_table(automount_result, AUTOMOUNT_RESULT); + test_table(automount_state, AUTOMOUNT_STATE); + test_table(cgroup_device_policy, CGROUP_DEVICE_POLICY); + test_table(condition_type, CONDITION_TYPE); + test_table(device_state, DEVICE_STATE); + test_table(exec_input, EXEC_INPUT); + test_table(exec_output, EXEC_OUTPUT); + test_table(job_mode, JOB_MODE); + test_table(job_result, JOB_RESULT); + test_table(job_state, JOB_STATE); + test_table(job_type, JOB_TYPE); + test_table(kill_mode, KILL_MODE); + test_table(kill_who, KILL_WHO); + test_table(log_target, LOG_TARGET); + test_table(mount_exec_command, MOUNT_EXEC_COMMAND); + test_table(mount_result, MOUNT_RESULT); + test_table(mount_state, MOUNT_STATE); + test_table(notify_access, NOTIFY_ACCESS); + test_table(output_mode, OUTPUT_MODE); + test_table(path_result, PATH_RESULT); + test_table(path_state, PATH_STATE); + test_table(path_type, PATH_TYPE); + test_table(scope_result, SCOPE_RESULT); + test_table(scope_state, SCOPE_STATE); + test_table(service_exec_command, SERVICE_EXEC_COMMAND); + test_table(service_restart, SERVICE_RESTART); + test_table(service_result, SERVICE_RESULT); + test_table(service_state, SERVICE_STATE); + test_table(service_type, SERVICE_TYPE); + test_table(slice_state, SLICE_STATE); + test_table(snapshot_state, SNAPSHOT_STATE); + test_table(socket_address_bind_ipv6_only, SOCKET_ADDRESS_BIND_IPV6_ONLY); + test_table(socket_exec_command, SOCKET_EXEC_COMMAND); + test_table(socket_result, SOCKET_RESULT); + test_table(socket_state, SOCKET_STATE); + test_table(start_limit_action, SERVICE_START_LIMIT); + test_table(swap_exec_command, SWAP_EXEC_COMMAND); + test_table(swap_result, SWAP_RESULT); + test_table(swap_state, SWAP_STATE); + test_table(systemd_running_as, SYSTEMD_RUNNING_AS); + test_table(target_state, TARGET_STATE); + test_table(timer_base, TIMER_BASE); + test_table(timer_result, TIMER_RESULT); + test_table(timer_state, TIMER_STATE); + test_table(unit_active_state, UNIT_ACTIVE_STATE); + test_table(unit_dependency, UNIT_DEPENDENCY); + test_table(unit_file_change_type, UNIT_FILE_CHANGE_TYPE); + test_table(unit_file_state, UNIT_FILE_STATE); + test_table(unit_load_state, UNIT_LOAD_STATE); + test_table(unit_type, UNIT_TYPE); + + return EXIT_SUCCESS; +} -- cgit v1.2.1 From 26306aed13e73b6edbc4b3fd7b97e421e152b56b Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 5 Jul 2013 14:59:52 +0200 Subject: update TODO --- TODO | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/TODO b/TODO index d1bc805050..d428fda5f7 100644 --- a/TODO +++ b/TODO @@ -11,6 +11,14 @@ Bugfixes: * properly handle .mount unit state tracking when two mount points are stacked one on top of another on the exact same mount point. +* stop importing kernel exported env variables. The utterly broken logic in + the kernel exports every kernel command line option which is not recognized + as a built-in module option as an env variable. Systemd should not pass-on + that nonsense, a kernel command line option is a command line option not an + env variable: + $ cat /proc/252/environ + initrd=\6a9857a393724b7a981ebb5b8495b9ea\3.10.0-2.fc20.x86_64\initrd + Fedora 19: * external: maybe it is time to patch procps so that "ps" links to -- cgit v1.2.1 From 925d98b3441881bad3a459cb5f7f3785bab40b5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 5 Jul 2013 22:15:54 -0400 Subject: systemd-python: wrap sd_notify _listen_fds() is modified to accept unset_environment arg as keyword, to match new notify(). --- src/python-systemd/_daemon.c | 49 ++++++++++++++++++++++++++++++++++++++++---- src/python-systemd/daemon.py | 1 + 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/src/python-systemd/_daemon.c b/src/python-systemd/_daemon.c index c6b14d4665..bd4e73e9be 100644 --- a/src/python-systemd/_daemon.c +++ b/src/python-systemd/_daemon.c @@ -79,6 +79,43 @@ static PyObject* booted(PyObject *self, PyObject *args) { return PyBool_FromLong(r); } +PyDoc_STRVAR(notify__doc__, + "notify(status, unset_environment=False) -> bool\n\n" + "Send a message to the init system about a status change.\n" + "Wraps sd_notify(3)."); + +static PyObject* notify(PyObject *self, PyObject *args, PyObject *keywds) { + int r; + const char* msg; + int unset = false; + + static const char* const kwlist[] = { + "status", + "unset_environment", + NULL, + }; +#if PY_MAJOR_VERSION >=3 && PY_MINOR_VERSION >= 3 + if (!PyArg_ParseTupleAndKeywords(args, keywds, "s|p:notify", + (char**) kwlist, &msg, &unset)) + return NULL; +#else + PyObject *obj = NULL; + if (!PyArg_ParseTupleAndKeywords(args, keywds, "s|O:notify", + (char**) kwlist, &msg, &obj)) + return NULL; + if (obj != NULL) + unset = PyObject_IsTrue(obj); + if (unset < 0) + return NULL; +#endif + + r = sd_notify(unset, msg); + if (set_error(r, NULL, NULL)) + return NULL; + + return PyBool_FromLong(r); +} + PyDoc_STRVAR(listen_fds__doc__, "_listen_fds(unset_environment=True) -> int\n\n" @@ -87,16 +124,19 @@ PyDoc_STRVAR(listen_fds__doc__, "Wraps sd_listen_fds(3)." ); -static PyObject* listen_fds(PyObject *self, PyObject *args) { +static PyObject* listen_fds(PyObject *self, PyObject *args, PyObject *keywds) { int r; int unset = true; + static const char* const kwlist[] = {"unset_environment", NULL}; #if PY_MAJOR_VERSION >=3 && PY_MINOR_VERSION >= 3 - if (!PyArg_ParseTuple(args, "|p:_listen_fds", &unset)) + if (!PyArg_ParseTupleAndKeywords(args, keywds, "|p:_listen_fds", + (char**) kwlist, &unset)) return NULL; #else PyObject *obj = NULL; - if (!PyArg_ParseTuple(args, "|O:_listen_fds", &obj)) + if (!PyArg_ParseTupleAndKeywords(args, keywds, "|O:_listen_fds", + (char**) kwlist, &unset, &obj)) return NULL; if (obj != NULL) unset = PyObject_IsTrue(obj); @@ -256,7 +296,8 @@ static PyObject* is_socket_unix(PyObject *self, PyObject *args) { static PyMethodDef methods[] = { { "booted", booted, METH_NOARGS, booted__doc__}, - { "_listen_fds", listen_fds, METH_VARARGS, listen_fds__doc__}, + { "notify", (PyCFunction) notify, METH_VARARGS | METH_KEYWORDS, notify__doc__}, + { "_listen_fds", (PyCFunction) listen_fds, METH_VARARGS | METH_KEYWORDS, listen_fds__doc__}, { "_is_fifo", is_fifo, METH_VARARGS, is_fifo__doc__}, { "_is_mq", is_mq, METH_VARARGS, is_mq__doc__}, { "_is_socket", is_socket, METH_VARARGS, is_socket__doc__}, diff --git a/src/python-systemd/daemon.py b/src/python-systemd/daemon.py index e2829d1671..1c386bb6fc 100644 --- a/src/python-systemd/daemon.py +++ b/src/python-systemd/daemon.py @@ -1,5 +1,6 @@ from ._daemon import (__version__, booted, + notify, _listen_fds, _is_fifo, _is_socket, -- cgit v1.2.1 From 19887cd06a3af2f045e763986eda19e208bd3f85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 6 Jul 2013 22:22:05 -0400 Subject: man: document machinectl and systemd-machined --- Makefile-man.am | 14 +- man/loginctl.xml | 9 +- man/machinectl.xml | 301 +++++++++++++++++++++++++++++++++++++++ man/systemctl.xml | 19 ++- man/systemd-logind.service.xml | 10 +- man/systemd-machined.service.xml | 76 ++++++++++ src/machine/machinectl.c | 2 +- 7 files changed, 410 insertions(+), 21 deletions(-) create mode 100644 man/machinectl.xml create mode 100644 man/systemd-machined.service.xml diff --git a/Makefile-man.am b/Makefile-man.am index ba34d1e3df..fef69be58e 100644 --- a/Makefile-man.am +++ b/Makefile-man.am @@ -654,6 +654,7 @@ endif if ENABLE_LOGIND MANPAGES += \ + man/loginctl.1 \ man/logind.conf.5 \ man/systemd-logind.service.8 MANPAGES_ALIAS += \ @@ -664,6 +665,18 @@ man/systemd-logind.html: man/systemd-logind.service.html endif +if ENABLE_MACHINED +MANPAGES += \ + man/machinectl.1 \ + man/systemd-machined.service.8 +MANPAGES_ALIAS += \ + man/systemd-machined.8 +man/systemd-machined.8: man/systemd-machined.service.8 +man/systemd-machined.html: man/systemd-machined.service.html + $(html-alias) + +endif + if ENABLE_QUOTACHECK MANPAGES += \ man/systemd-quotacheck.service.8 @@ -790,7 +803,6 @@ endif if HAVE_PAM MANPAGES += \ - man/loginctl.1 \ man/pam_systemd.8 \ man/sd-login.3 \ man/sd_get_seats.3 \ diff --git a/man/loginctl.xml b/man/loginctl.xml index b9db475983..e129d1b136 100644 --- a/man/loginctl.xml +++ b/man/loginctl.xml @@ -21,7 +21,7 @@ along with systemd; If not, see . --> - + loginctl @@ -49,7 +49,10 @@ - loginctl OPTIONS COMMAND NAME + loginctl + OPTIONS + COMMAND + NAME @@ -217,7 +220,7 @@ itself. If no argument is specified, properties of the manager will be shown. If a session ID is specified, - properties of the session is shown. By + properties of the session are shown. By default, empty properties are suppressed. Use to show those too. To select specific diff --git a/man/machinectl.xml b/man/machinectl.xml new file mode 100644 index 0000000000..2606180d12 --- /dev/null +++ b/man/machinectl.xml @@ -0,0 +1,301 @@ + + + + + + + + + machinectl + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + machinectl + 1 + + + + machinectl + Control the systemd machine manager + + + + + machinectl + OPTIONS + COMMAND + NAME + + + + + Description + + machinectl may be used to + introspect and control the state of the + systemd1 + virtual machine and container registration manager systemd-machined.service8. + + + + Options + + The following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + + Prints a short version + string and exits. + + + + + + + When showing + session/user properties, limit + display to certain properties as + specified as argument. If not + specified, all set properties are + shown. The argument should be a + property name, such as + Name. If + specified more than once, all + properties with the specified names + are shown. + + + + + + + When showing + unit/job/manager properties, show all + properties regardless whether they are + set or not. + + + + + + + Do not ellipsize cgroup + members. + + + + + + + Do not pipe output into a + pager. + + + + + + Do not query the user + for authentication for privileged + operations. + + + + + + When used with + kill-session, + choose which processes to kill. Must + be one of , or + to select whether + to kill only the leader process of the + session or all processes of the + session. If omitted, defaults to + . + + + + + + + When used with + kill-session or + kill-user, choose + which signal to send to selected + processes. Must be one of the well + known signal specifiers, such as + SIGTERM, + SIGINT or + SIGSTOP. If + omitted, defaults to + SIGTERM. + + + + + + + Execute operation + remotely. Specify a hostname, or + username and hostname separated by @, + to connect to. This will use SSH to + talk to the remote machine manager + instance. + + + + + + + Acquire privileges via + PolicyKit before executing the + operation. + + + + The following commands are understood: + + + + list + + List currently running + virtual machines and containers. + + + + + status [ID...] + + Show terse runtime + status information about one or more + virtual machines and containers. This + function is intended to generate + human-readable output. If you are + looking for computer-parsable output, + use show instead. + + + + + show [ID...] + + Show properties of one + or more registered virtual machines or + containers or the manager itself. If + no argument is specified, properties + of the manager will be shown. If a an + ID is specified, properties of this + virtual machine or container are + shown. By default, empty properties + are suppressed. Use + to show those + too. To select specific properties to + show, use + . This + command is intended to be used + whenever computer-parsable output is + required. Use + status if you are + looking for formatted human-readable + output. + + + + terminate [ID...] + + Terminates a virtual + machine or container. This kills all + processes of the virtual machine or + container and deallocates all + resources attached to that + instance. + + + + kill [ID...] + + Send a signal to one + or more processes of the virtual + machine or container. This means + processes as seen by the host, not the + processes inside the virtual machine + or container. + Use to + select which process to kill. Use + to select + the signal to send. + + + + + + + Exit status + + On success, 0 is returned, a non-zero failure + code otherwise. + + + + Environment + + + + $SYSTEMD_PAGER + Pager to use when + is not given; + overrides $PAGER. Setting + this to an empty string or the value + cat is equivalent to passing + . + + + + + + See Also + + systemd-machined.service8, + systemd-logind.service8 + + + + diff --git a/man/systemctl.xml b/man/systemctl.xml index 632a26dedb..07e7363ab2 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -819,9 +819,8 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service Show manual pages for one or more units, if - available. If a PID is passed the manual pages for the unit - the process of the PID belongs to is - shown. + available. If a PID is given the manual pages for the unit + the process belongs to are shown. @@ -859,13 +858,13 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service created the systemd configuration is reloaded (in a way that is equivalent to daemon-reload) to ensure the changes are taken into account immediately. Note that - this does not have the effect that any of the units enabled - are also started at the same time. If this is desired a - separate start command must be invoked - for the unit. Also note that in case of instance enablement, - symlinks named same as instances are created in install - location, however they all point to the same template unit - file. + this does not have the effect of also + starting starting any of the units beeing enabled. If this + is desired a separate start command must + be invoked for the unit. Also note that in case of instance + enablement, symlinks named same as instances are created in + install location, however they all point to the same + template unit file. This command will print the actions executed. This output may be suppressed by passing . diff --git a/man/systemd-logind.service.xml b/man/systemd-logind.service.xml index 09bcfac430..c0c3d1a897 100644 --- a/man/systemd-logind.service.xml +++ b/man/systemd-logind.service.xml @@ -56,16 +56,14 @@ Description - systemd-logind is a system + systemd-logind is a system service that manages user logins. It is responsible for: - Keeping track of users and sessions, their - processes and their idle state - - Creating control groups for - user processes + Keeping track of users and + sessions, their processes and their idle + state Providing PolicyKit-based access for users to operations such as system diff --git a/man/systemd-machined.service.xml b/man/systemd-machined.service.xml new file mode 100644 index 0000000000..3094315ecb --- /dev/null +++ b/man/systemd-machined.service.xml @@ -0,0 +1,76 @@ + + + + + + + + + systemd-machined.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-machined.service + 8 + + + + systemd-machined.service + systemd-machined + Virtual machine and container registartion manager + + + + systemd-machined.service + /usr/lib/systemd/systemd-machined + + + + Description + + systemd-machined is a + system service that keeps track of virtual machines + and containers, and processes belonging to + them. + + See systemd-nspawn1 for some examples how to + start a container the systemd way. + + + + See Also + + systemd1, + machinectl1. + + + + diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c index 5d107f360a..34bbe36109 100644 --- a/src/machine/machinectl.c +++ b/src/machine/machinectl.c @@ -514,7 +514,7 @@ static int help(void) { "Commands:\n" " list List running VMs and containers\n" " status [NAME...] Show VM/container status\n" - " show[NAME...] Show properties of one or more VMs/containers\n" + " show [NAME...] Show properties of one or more VMs/containers\n" " terminate [NAME...] Terminate one or more VMs/containers\n" " kill [NAME...] Send signal to processes of a VM/container\n", program_invocation_short_name); -- cgit v1.2.1 From 65b571fcfbeb7024b7e1573404c27fcf77322d0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 6 Jul 2013 23:33:26 -0400 Subject: man: tweak the description of System/RuntimeMaxUse https://bugs.freedesktop.org/show_bug.cgi?id=66657 --- man/journald.conf.xml | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/man/journald.conf.xml b/man/journald.conf.xml index b161b34e4e..5986d61c45 100644 --- a/man/journald.conf.xml +++ b/man/journald.conf.xml @@ -256,15 +256,14 @@ system. SystemKeepFree= and RuntimeKeepFree= - control how much disk space the - journal shall always leave free for - other uses if less than the disk space - configured in - SystemMaxUse= and - RuntimeMaxUse= is - available. Defaults to 15% of the size - of the respective file - system. SystemMaxFileSize= + control how much disk space + systemd-journald shall always leave + free for other uses. Defaults to 15% + of the size of the respective file + system. systemd-journald will respect + both limits, i.e. use the smaller of + the two values. + SystemMaxFileSize= and RuntimeMaxFileSize= control how large individual journal @@ -282,10 +281,10 @@ E as units for the specified sizes (equal to 1024, 1024²,... bytes). Note that size limits are enforced - synchronously when journal files - are extended, and no explicit - rotation step triggered by - time is needed. + synchronously when journal files are + extended, and no explicit rotation + step triggered by time is + needed. -- cgit v1.2.1 From bfdf1adc6e4e359c625bffd54d221b9dabaa75a6 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 8 Jul 2013 01:09:08 +0200 Subject: hwdb: remove too broad PNP* match from 20-acpi-vendor.hwdb --- hwdb/20-acpi-vendor.hwdb | 3 --- 1 file changed, 3 deletions(-) diff --git a/hwdb/20-acpi-vendor.hwdb b/hwdb/20-acpi-vendor.hwdb index 09fc3bddc1..9b3b0094d5 100644 --- a/hwdb/20-acpi-vendor.hwdb +++ b/hwdb/20-acpi-vendor.hwdb @@ -4546,9 +4546,6 @@ acpi:PNG*: acpi:PNL*: ID_VENDOR_FROM_DATABASE=Panelview, Inc. -acpi:PNP*: - ID_VENDOR_FROM_DATABASE=Microsoft - acpi:PNR*: ID_VENDOR_FROM_DATABASE=Planar Systems, Inc. -- cgit v1.2.1 From a4bbef099209d4e3bccd913cd30da536f8971064 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 8 Jul 2013 11:44:17 +0200 Subject: hwdb: add --lookup-prefix= option --- src/udev/udev-builtin-hwdb.c | 33 ++++++++++++++++++++++++++------- src/udev/udev-builtin-net_id.c | 2 +- src/udev/udev.h | 3 ++- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/udev/udev-builtin-hwdb.c b/src/udev/udev-builtin-hwdb.c index 36958916c4..314587f2bb 100644 --- a/src/udev/udev-builtin-hwdb.c +++ b/src/udev/udev-builtin-hwdb.c @@ -31,14 +31,26 @@ static struct udev_hwdb *hwdb; int udev_builtin_hwdb_lookup(struct udev_device *dev, - const char *modalias, const char *filter, bool test) { + const char *prefix, const char *modalias, + const char *filter, bool test) { + struct udev_list_entry *list; struct udev_list_entry *entry; int n = 0; if (!hwdb) return -ENOENT; - udev_list_entry_foreach(entry, udev_hwdb_get_properties_list_entry(hwdb, modalias, 0)) { + if (prefix) { + _cleanup_free_ const char *lookup; + + lookup = strjoin(prefix, modalias, NULL); + if (!lookup) + return -ENOMEM; + list = udev_hwdb_get_properties_list_entry(hwdb, lookup, 0); + } else + list = udev_hwdb_get_properties_list_entry(hwdb, modalias, 0); + + udev_list_entry_foreach(entry, list) { if (filter && fnmatch(filter, udev_list_entry_get_name(entry), FNM_NOESCAPE) != 0) continue; @@ -72,7 +84,8 @@ static const char *modalias_usb(struct udev_device *dev, char *s, size_t size) { } static int udev_builtin_hwdb_search(struct udev_device *dev, struct udev_device *srcdev, - const char *subsystem, const char *filter, bool test) { + const char *subsystem, const char *prefix, + const char *filter, bool test) { struct udev_device *d; char s[16]; int n = 0; @@ -99,7 +112,7 @@ static int udev_builtin_hwdb_search(struct udev_device *dev, struct udev_device if (!modalias) continue; - n = udev_builtin_hwdb_lookup(dev, modalias, filter, test); + n = udev_builtin_hwdb_lookup(dev, prefix, modalias, filter, test); if (n > 0) break; } @@ -112,11 +125,13 @@ static int builtin_hwdb(struct udev_device *dev, int argc, char *argv[], bool te { "filter", required_argument, NULL, 'f' }, { "device", required_argument, NULL, 'd' }, { "subsystem", required_argument, NULL, 's' }, + { "lookup-prefix", required_argument, NULL, 'p' }, {} }; const char *filter = NULL; const char *device = NULL; const char *subsystem = NULL; + const char *prefix = NULL; struct udev_device *srcdev; if (!hwdb) @@ -125,7 +140,7 @@ static int builtin_hwdb(struct udev_device *dev, int argc, char *argv[], bool te for (;;) { int option; - option = getopt_long(argc, argv, "s", options, NULL); + option = getopt_long(argc, argv, "f:d:s:p:", options, NULL); if (option == -1) break; @@ -141,12 +156,16 @@ static int builtin_hwdb(struct udev_device *dev, int argc, char *argv[], bool te case 's': subsystem = optarg; break; + + case 'p': + prefix = optarg; + break; } } /* query a specific key given as argument */ if (argv[optind]) { - if (udev_builtin_hwdb_lookup(dev, argv[optind], filter, test) > 0) + if (udev_builtin_hwdb_lookup(dev, prefix, argv[optind], filter, test) > 0) return EXIT_SUCCESS; return EXIT_FAILURE; } @@ -159,7 +178,7 @@ static int builtin_hwdb(struct udev_device *dev, int argc, char *argv[], bool te } else srcdev = dev; - if (udev_builtin_hwdb_search(dev, srcdev, subsystem, filter, test) < 0) + if (udev_builtin_hwdb_search(dev, srcdev, subsystem, prefix, filter, test) < 0) return EXIT_FAILURE; return EXIT_SUCCESS; } diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c index e1d8087122..9ae8f08ccf 100644 --- a/src/udev/udev-builtin-net_id.c +++ b/src/udev/udev-builtin-net_id.c @@ -396,7 +396,7 @@ static int ieee_oui(struct udev_device *dev, struct netnames *names, bool test) snprintf(str, sizeof(str), "OUI:%02X%02X%02X%02X%02X%02X", names->mac[0], names->mac[1], names->mac[2], names->mac[3], names->mac[4], names->mac[5]); - udev_builtin_hwdb_lookup(dev, str, NULL, test); + udev_builtin_hwdb_lookup(dev, NULL, str, NULL, test); return 0; } diff --git a/src/udev/udev.h b/src/udev/udev.h index d5f8cd7dcf..4f10c452e6 100644 --- a/src/udev/udev.h +++ b/src/udev/udev.h @@ -190,7 +190,8 @@ int udev_builtin_run(struct udev_device *dev, enum udev_builtin_cmd cmd, const c void udev_builtin_list(struct udev *udev); bool udev_builtin_validate(struct udev *udev); int udev_builtin_add_property(struct udev_device *dev, bool test, const char *key, const char *val); -int udev_builtin_hwdb_lookup(struct udev_device *dev, const char *modalias, const char *filter, bool test); +int udev_builtin_hwdb_lookup(struct udev_device *dev, const char *prefix, const char *modalias, + const char *filter, bool test); /* udev logging */ void udev_main_log(struct udev *udev, int priority, -- cgit v1.2.1 From fec79699da51a0815ff01e14abcc94b1f6d3926a Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 8 Jul 2013 11:46:44 +0200 Subject: hwdb: import data --- hwdb/20-OUI.hwdb | 63 +++++++++++++++++++ hwdb/20-pci-vendor-model.hwdb | 138 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 195 insertions(+), 6 deletions(-) diff --git a/hwdb/20-OUI.hwdb b/hwdb/20-OUI.hwdb index 90c0116ffd..8b402f9b4a 100644 --- a/hwdb/20-OUI.hwdb +++ b/hwdb/20-OUI.hwdb @@ -13087,6 +13087,18 @@ OUI:40D855129* OUI:40D85512A* ID_OUI_FROM_DATABASE=Jadpod Communication Company Limited +OUI:40D85512B* + ID_OUI_FROM_DATABASE=Mango DSP, Inc. + +OUI:40D85512C* + ID_OUI_FROM_DATABASE=NSP Europe Ltd + +OUI:40D85512D* + ID_OUI_FROM_DATABASE=Biotage Sweden AB + +OUI:40D85512E* + ID_OUI_FROM_DATABASE=Canfield Scientific, Inc. + OUI:000000* ID_OUI_FROM_DATABASE=XEROX CORPORATION @@ -54574,6 +54586,9 @@ OUI:349D90* OUI:34A183* ID_OUI_FROM_DATABASE=AWare, Inc +OUI:34A3BF* + ID_OUI_FROM_DATABASE=Terewave. Inc. + OUI:34A55D* ID_OUI_FROM_DATABASE=TECHNOSOFT INTERNATIONAL SRL @@ -54757,6 +54772,9 @@ OUI:383F10* OUI:384233* ID_OUI_FROM_DATABASE=Wildeboer Bauteile GmbH +OUI:3842A6* + ID_OUI_FROM_DATABASE=Ingenieurbuero Stahlkopf + OUI:384369* ID_OUI_FROM_DATABASE=Patrol Products Consortium LLC @@ -54814,6 +54832,9 @@ OUI:3872C0* OUI:388345* ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD. +OUI:3889DC* + ID_OUI_FROM_DATABASE=Opticon Sensors Europe B.V. + OUI:388AB7* ID_OUI_FROM_DATABASE=ITC Networks @@ -55033,6 +55054,9 @@ OUI:3C7437* OUI:3C754A* ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. +OUI:3C77E6* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + OUI:3C7DB1* ID_OUI_FROM_DATABASE=Texas Instruments @@ -56104,6 +56128,9 @@ OUI:500E6D* OUI:5011EB* ID_OUI_FROM_DATABASE=SilverNet Ltd +OUI:5017FF* + ID_OUI_FROM_DATABASE=Cisco + OUI:502267* ID_OUI_FROM_DATABASE=PixeLINK @@ -56464,6 +56491,9 @@ OUI:54A9D4* OUI:54B620* ID_OUI_FROM_DATABASE=SUHDOL E&C Co.Ltd. +OUI:54BEF7* + ID_OUI_FROM_DATABASE=PEGATRON CORPORATION + OUI:54CDA7* ID_OUI_FROM_DATABASE=Fujian Shenzhou Electronic Co.,Ltd @@ -56929,6 +56959,9 @@ OUI:5CD998* OUI:5CDAD4* ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. +OUI:5CDD70* + ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited + OUI:5CE0CA* ID_OUI_FROM_DATABASE=FeiTian United (Beijing) System Technology Co., Ltd. @@ -58048,6 +58081,9 @@ OUI:701124* OUI:701404* ID_OUI_FROM_DATABASE=Limited Liability Company +OUI:70188B* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + OUI:701A04* ID_OUI_FROM_DATABASE=Liteon Tech Corp. @@ -59812,6 +59848,9 @@ OUI:8C04FF* OUI:8C078C* ID_OUI_FROM_DATABASE=FLOW DATA INC +OUI:8C088B* + ID_OUI_FROM_DATABASE=Remote Solution + OUI:8C0C90* ID_OUI_FROM_DATABASE=Ruckus Wireless @@ -60328,6 +60367,9 @@ OUI:940149* OUI:940B2D* ID_OUI_FROM_DATABASE=NetView Technologies(Shenzhen) Co., Ltd +OUI:940BD5* + ID_OUI_FROM_DATABASE=Himax Technologies, Inc + OUI:940C6D* ID_OUI_FROM_DATABASE=TP-LINK Technologies Co.,Ltd. @@ -61003,6 +61045,9 @@ OUI:9CE635* OUI:9CE6E7* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +OUI:9CE7BD* + ID_OUI_FROM_DATABASE=Winduskorea co., Ltd + OUI:9CEBE8* ID_OUI_FROM_DATABASE=BizLink (Kunshan) Co.,Ltd @@ -61228,6 +61273,9 @@ OUI:A0B9ED* OUI:A0BAB8* ID_OUI_FROM_DATABASE=Pixon Imaging +OUI:A0BF50* + ID_OUI_FROM_DATABASE=S.C. ADD-PRODUCTION S.R.L. + OUI:A0BFA5* ID_OUI_FROM_DATABASE=CORESYS @@ -61495,6 +61543,9 @@ OUI:A4C2AB* OUI:A4C361* ID_OUI_FROM_DATABASE=Apple +OUI:A4C7DE* + ID_OUI_FROM_DATABASE=Cambridge Industries(Group) Co.,Ltd. + OUI:A4D094* ID_OUI_FROM_DATABASE=Erwin Peters Systemtechnik GmbH @@ -62473,6 +62524,9 @@ OUI:B4C799* OUI:B4C810* ID_OUI_FROM_DATABASE=UMPI Elettronica +OUI:B4CCE9* + ID_OUI_FROM_DATABASE=PROSYST + OUI:B4CFDB* ID_OUI_FROM_DATABASE=Shenzhen Jiuzhou Electric Co.,LTD @@ -63157,6 +63211,9 @@ OUI:C06394* OUI:C06599* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +OUI:C067AF* + ID_OUI_FROM_DATABASE=Cisco + OUI:C06C0F* ID_OUI_FROM_DATABASE=Dobbs Stanford @@ -65248,6 +65305,9 @@ OUI:E0AE5E* OUI:E0AEED* ID_OUI_FROM_DATABASE=LOENK +OUI:E0AF4B* + ID_OUI_FROM_DATABASE=Pluribus Networks, Inc. + OUI:E0B2F1* ID_OUI_FROM_DATABASE=FN-LINK TECHNOLOGY LIMITED @@ -65788,6 +65848,9 @@ OUI:E8D0FA* OUI:E8D483* ID_OUI_FROM_DATABASE=ULTIMATE Europe Transportation Equipment GmbH +OUI:E8D4E0* + ID_OUI_FROM_DATABASE=Beijing BenyWave Technology Co., Ltd. + OUI:E8DA96* ID_OUI_FROM_DATABASE=Zhuhai Tianrui Electrical Power Tech. Co., Ltd. diff --git a/hwdb/20-pci-vendor-model.hwdb b/hwdb/20-pci-vendor-model.hwdb index 99e0f61449..de0b27cb37 100644 --- a/hwdb/20-pci-vendor-model.hwdb +++ b/hwdb/20-pci-vendor-model.hwdb @@ -3663,7 +3663,7 @@ pci:v00001002d00005941sv000017AFsd0000200D* ID_MODEL_FROM_DATABASE=Excalibur Radeon 9200 pci:v00001002d00005941sv000018BCsd00000050* - ID_MODEL_FROM_DATABASE=GeXcube GC-R9200-C3 (Secondary) + ID_MODEL_FROM_DATABASE=GC-R9200-C3 (Secondary) pci:v00001002d00005944* ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE PCI] @@ -3756,7 +3756,7 @@ pci:v00001002d00005961sv000018BCsd00000050* ID_MODEL_FROM_DATABASE=Radeon 9200 Game Buster pci:v00001002d00005961sv000018BCsd00000051* - ID_MODEL_FROM_DATABASE=GeXcube GC-R9200-C3 + ID_MODEL_FROM_DATABASE=GC-R9200-C3 pci:v00001002d00005961sv000018BCsd00000053* ID_MODEL_FROM_DATABASE=Radeon 9200 Game Buster VIVO @@ -8265,7 +8265,7 @@ pci:v00001002d000094C3sv0000174Bsd0000E400* ID_MODEL_FROM_DATABASE=Radeon HD 2400 PRO pci:v00001002d000094C3sv000018BCsd00003550* - ID_MODEL_FROM_DATABASE=GeCube Radeon HD 2400 PRO + ID_MODEL_FROM_DATABASE=Radeon HD 2400 PRO pci:v00001002d000094C4* ID_MODEL_FROM_DATABASE=RV610 LE [Radeon HD 2400 PRO AGP] @@ -8859,7 +8859,7 @@ pci:v00001002d0000AA10sv0000174Bsd0000AA10* ID_MODEL_FROM_DATABASE=Radeon HD 2400 PRO pci:v00001002d0000AA10sv000018BCsd0000AA10* - ID_MODEL_FROM_DATABASE=GeCube Radeon HD 2400 PRO + ID_MODEL_FROM_DATABASE=Radeon HD 2400 PRO pci:v00001002d0000AA18* ID_MODEL_FROM_DATABASE=RV670/680 HDMI Audio [Radeon HD 3690/3800 Series] @@ -16280,6 +16280,9 @@ pci:v00001077d00002432* pci:v00001077d00002532* ID_MODEL_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA +pci:v00001077d00002532sv0000103Csd00003262* + ID_MODEL_FROM_DATABASE=StorageWorks 81Q + pci:v00001077d00002532sv00001077sd00000167* ID_MODEL_FROM_DATABASE=QME2572 Dual Port FC8 HBA Mezzanine @@ -24437,6 +24440,9 @@ pci:v000010DEd00000862* pci:v000010DEd00000863* ID_MODEL_FROM_DATABASE=C79 [GeForce 9400M] +pci:v000010DEd00000863sv0000106Bsd000000AA* + ID_MODEL_FROM_DATABASE=MacBook5,1 + pci:v000010DEd00000864* ID_MODEL_FROM_DATABASE=C79 [GeForce 9300] @@ -25682,6 +25688,9 @@ pci:v000010DEd00001140sv00001025sd0000077E* pci:v000010DEd00001140sv00001025sd0000077F* ID_MODEL_FROM_DATABASE=GeForce 710M +pci:v000010DEd00001140sv00001025sd00000781* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + pci:v000010DEd00001140sv00001025sd00000798* ID_MODEL_FROM_DATABASE=GeForce GT 720M @@ -25799,6 +25808,78 @@ pci:v000010DEd00001140sv00001043sd0000220A* pci:v000010DEd00001140sv00001043sd0000221A* ID_MODEL_FROM_DATABASE=GeForce GT 720M +pci:v000010DEd00001140sv00001179sd0000FA01* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001179sd0000FA02* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001179sd0000FA03* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001179sd0000FA05* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001179sd0000FA11* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001179sd0000FA13* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001179sd0000FA18* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001179sd0000FA19* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001179sd0000FA21* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001179sd0000FA23* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001179sd0000FA2A* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001179sd0000FA32* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001179sd0000FA33* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001179sd0000FA36* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001179sd0000FA38* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001179sd0000FA42* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001179sd0000FA43* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001179sd0000FA45* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001179sd0000FA47* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001179sd0000FA49* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001179sd0000FA58* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001179sd0000FA59* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001179sd0000FA88* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv00001179sd0000FA89* + ID_MODEL_FROM_DATABASE=GeForce 710M + pci:v000010DEd00001140sv0000144Dsd0000C0D5* ID_MODEL_FROM_DATABASE=GeForce GT 630M @@ -42975,7 +43056,13 @@ pci:v000014E4d000016B7* ID_MODEL_FROM_DATABASE=NetXtreme BCM57782 Gigabit Ethernet PCIe pci:v000014E4d000016BC* - ID_MODEL_FROM_DATABASE=NetXtreme BCM57765 Memory Card Reader + ID_MODEL_FROM_DATABASE=BCM57765/57785 SDXC/MMC Card Reader + +pci:v000014E4d000016BE* + ID_MODEL_FROM_DATABASE=BCM57765/57785 MS Card Reader + +pci:v000014E4d000016BF* + ID_MODEL_FROM_DATABASE=BCM57765/57785 xD-Picture Card Reader pci:v000014E4d000016C6* ID_MODEL_FROM_DATABASE=NetXtreme BCM5702A3 Gigabit Ethernet @@ -48549,7 +48636,7 @@ pci:v000018B8d0000B001* ID_MODEL_FROM_DATABASE=AMSO 1100 iWARP/RDMA Gigabit Ethernet Coprocessor pci:v000018BC* - ID_VENDOR_FROM_DATABASE=Info-Tek Corp. + ID_VENDOR_FROM_DATABASE=GeCube Technologies, Inc. pci:v000018C3* ID_VENDOR_FROM_DATABASE=Micronas Semiconductor Holding AG @@ -50411,6 +50498,9 @@ pci:v00001B21d00001042* pci:v00001B21d00001080* ID_MODEL_FROM_DATABASE=ASM1083/1085 PCIe to PCI Bridge +pci:v00001B2C* + ID_VENDOR_FROM_DATABASE=Opal-RT Technologies Inc. + pci:v00001B36* ID_VENDOR_FROM_DATABASE=Red Hat, Inc. @@ -69906,8 +69996,44 @@ pci:v0000DD01* ID_VENDOR_FROM_DATABASE=Digital Devices GmbH pci:v0000DD01d00000003* + ID_MODEL_FROM_DATABASE=Octopus DVB Adapter + +pci:v0000DD01d00000003sv0000DD01sd00000001* + ID_MODEL_FROM_DATABASE=Octopus DVB adapter + +pci:v0000DD01d00000003sv0000DD01sd00000002* ID_MODEL_FROM_DATABASE=Octopus LE DVB adapter +pci:v0000DD01d00000003sv0000DD01sd00000003* + ID_MODEL_FROM_DATABASE=Octopus OEM + +pci:v0000DD01d00000003sv0000DD01sd00000004* + ID_MODEL_FROM_DATABASE=Octopus V3 DVB adapter + +pci:v0000DD01d00000003sv0000DD01sd00000010* + ID_MODEL_FROM_DATABASE=Octopus Mini + +pci:v0000DD01d00000003sv0000DD01sd00000020* + ID_MODEL_FROM_DATABASE=Cine S2 V6 DVB adapter + +pci:v0000DD01d00000003sv0000DD01sd00000021* + ID_MODEL_FROM_DATABASE=Cine S2 V6.5 DVB adapter + +pci:v0000DD01d00000003sv0000DD01sd00000030* + ID_MODEL_FROM_DATABASE=Cine CT V6.1 DVB adapter + +pci:v0000DD01d00000003sv0000DD01sd0000DB03* + ID_MODEL_FROM_DATABASE=Mystique SaTiX-S2 V3 DVB adapter + +pci:v0000DD01d00000011* + ID_MODEL_FROM_DATABASE=Octopus CI DVB Adapter + +pci:v0000DD01d00000011sv0000DD01sd00000040* + ID_MODEL_FROM_DATABASE=Octopus CI + +pci:v0000DD01d00000011sv0000DD01sd00000041* + ID_MODEL_FROM_DATABASE=Octopus CI Single + pci:v0000DEAD* ID_VENDOR_FROM_DATABASE=Indigita Corporation -- cgit v1.2.1 From edeb68c53f1cdc452016b4c8512586a70b1262e3 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Fri, 14 Jun 2013 22:56:39 +0200 Subject: static-nodes: move creation of static nodes from udevd to tmpfiles As of kmod v14, it is possible to export the static node information from /lib/modules/`uname -r`/modules.devname in tmpfiles.d(5) format. Use this functionality to let systemd-tmpfilesd create the static device nodes at boot, and drop the functionality from systemd-udevd. As an effect of this we can move from systemd-udevd to systemd-tmpfiles-setup-dev: * the conditional CAP_MKNOD (replaced by checking if /sys is mounted rw) * ordering before local-fs-pre.target (see 89d09e1b5c65a2d97840f682e0932c8bb499f166) --- Makefile.am | 11 ++++- TODO | 4 -- configure.ac | 4 +- src/udev/udevd.c | 72 ----------------------------- units/.gitignore | 1 + units/kmod-static-nodes.service.in | 16 +++++++ units/systemd-tmpfiles-setup-dev.service.in | 2 +- units/systemd-udevd.service.in | 4 +- 8 files changed, 33 insertions(+), 81 deletions(-) create mode 100644 units/kmod-static-nodes.service.in diff --git a/Makefile.am b/Makefile.am index 290ec1eb60..aa7e830222 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1464,10 +1464,18 @@ nodist_systemunit_DATA += \ SYSINIT_TARGET_WANTS += \ systemd-modules-load.service +if ENABLE_TMPFILES +nodist_systemunit_DATA += \ + units/kmod-static-nodes.service + +SYSINIT_TARGET_WANTS += \ + kmod-static-nodes.service +endif endif EXTRA_DIST += \ - units/systemd-modules-load.service.in + units/systemd-modules-load.service.in \ + units/kmod-static-nodes.service.in # ------------------------------------------------------------------------------ if ENABLE_TMPFILES @@ -4137,6 +4145,7 @@ substitutions = \ '|SUSHELL=$(SUSHELL)|' \ '|DEBUGTTY=$(DEBUGTTY)|' \ '|KILL=$(KILL)|' \ + '|KMOD=$(KMOD)|' \ '|QUOTAON=$(QUOTAON)|' \ '|QUOTACHECK=$(QUOTACHECK)|' \ '|SYSTEM_SYSVINIT_PATH=$(sysvinitdir)|' \ diff --git a/TODO b/TODO index d428fda5f7..0498809ea0 100644 --- a/TODO +++ b/TODO @@ -186,10 +186,6 @@ Features: so that the coredump is properly written to the user's own journal file. -* move /usr/lib/modules/$(uname -r)/modules.devname parsing from udevd to - kmod static-nodes - call kmod as an early service, and drop CAP_MKNOD from udevd.service - * seems that when we follow symlinks to units we prefer the symlink destination path over /etc and /usr. We shouldn't do that. Instead /etc should always override /run+/usr and also any symlink diff --git a/configure.ac b/configure.ac index 6fd5307c7f..be867079c2 100644 --- a/configure.ac +++ b/configure.ac @@ -74,6 +74,8 @@ AC_PATH_PROG([SETCAP], [setcap], [/usr/sbin/setcap]) AC_PATH_PROG([KILL], [kill], [/usr/bin/kill]) +AC_PATH_PROG([KMOD], [kmod], [/usr/bin/kmod]) + # gtkdocize greps for '^GTK_DOC_CHECK', so it needs to be on its own line m4_ifdef([GTK_DOC_CHECK], [ GTK_DOC_CHECK([1.18],[--flavour no-tmpl])], @@ -216,7 +218,7 @@ PKG_CHECK_MODULES(DBUS, [dbus-1 >= 1.3.2]) have_kmod=no AC_ARG_ENABLE(kmod, AS_HELP_STRING([--disable-kmod], [disable loadable modules support])) if test "x$enable_kmod" != "xno"; then - PKG_CHECK_MODULES(KMOD, [ libkmod >= 5 ], + PKG_CHECK_MODULES(KMOD, [ libkmod >= 14 ], [AC_DEFINE(HAVE_KMOD, 1, [Define if kmod is available]) have_kmod=yes], have_kmod=no) if test "x$have_kmod" = xno -a "x$enable_kmod" = xyes; then AC_MSG_ERROR([*** kmod support requested but libraries not found]) diff --git a/src/udev/udevd.c b/src/udev/udevd.c index 7d13b4f532..c4127cd03b 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -812,77 +812,6 @@ static void handle_signal(struct udev *udev, int signo) } } -static void static_dev_create_from_modules(struct udev *udev) -{ - struct utsname kernel; - char modules[UTIL_PATH_SIZE]; - char buf[4096]; - FILE *f; - - if (uname(&kernel) < 0) { - log_error("uname failed: %m"); - return; - } - - strscpyl(modules, sizeof(modules), ROOTPREFIX "/lib/modules/", kernel.release, "/modules.devname", NULL); - f = fopen(modules, "re"); - if (f == NULL) - return; - - while (fgets(buf, sizeof(buf), f) != NULL) { - char *s; - const char *modname; - const char *devname; - const char *devno; - int maj, min; - char type; - mode_t mode; - char filename[UTIL_PATH_SIZE]; - - if (buf[0] == '#') - continue; - - modname = buf; - s = strchr(modname, ' '); - if (s == NULL) - continue; - s[0] = '\0'; - - devname = &s[1]; - s = strchr(devname, ' '); - if (s == NULL) - continue; - s[0] = '\0'; - - devno = &s[1]; - s = strchr(devno, ' '); - if (s == NULL) - s = strchr(devno, '\n'); - if (s != NULL) - s[0] = '\0'; - if (sscanf(devno, "%c%u:%u", &type, &maj, &min) != 3) - continue; - - mode = 0600; - if (type == 'c') - mode |= S_IFCHR; - else if (type == 'b') - mode |= S_IFBLK; - else - continue; - - strscpyl(filename, sizeof(filename), "/dev/", devname, NULL); - mkdir_parents_label(filename, 0755); - label_context_set(filename, mode); - log_debug("mknod '%s' %c%u:%u\n", filename, type, maj, min); - if (mknod(filename, mode, makedev(maj, min)) < 0 && errno == EEXIST) - utimensat(AT_FDCWD, filename, NULL, 0); - label_context_clear(); - } - - fclose(f); -} - static int systemd_fds(struct udev *udev, int *rctrl, int *rnetlink) { int ctrl = -1, netlink = -1; @@ -1067,7 +996,6 @@ int main(int argc, char *argv[]) mkdir("/run/udev", 0755); dev_setup(NULL); - static_dev_create_from_modules(udev); /* before opening new files, make sure std{in,out,err} fds are in a sane state */ if (daemonize) { diff --git a/units/.gitignore b/units/.gitignore index 0bcbb00951..9aee00f2a4 100644 --- a/units/.gitignore +++ b/units/.gitignore @@ -58,3 +58,4 @@ /initrd-udevadm-cleanup-db.service /systemd-nspawn@.service /systemd-machined.service +/kmod-static-nodes.service diff --git a/units/kmod-static-nodes.service.in b/units/kmod-static-nodes.service.in new file mode 100644 index 0000000000..f8a2d474ef --- /dev/null +++ b/units/kmod-static-nodes.service.in @@ -0,0 +1,16 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Create list of required static device nodes for the current kernel +DefaultDependencies=no +Before=sysinit.target systemd-tmpfiles-setup-dev.service + +[Service] +Type=oneshot +ExecStartPre=/usr/bin/mkdir -p /run/tmpfiles.d +ExecStart=@KMOD@ static-nodes --format=tmpfiles --output=/run/tmpfiles.d/kmod.conf diff --git a/units/systemd-tmpfiles-setup-dev.service.in b/units/systemd-tmpfiles-setup-dev.service.in index f029285bc0..8073b1229d 100644 --- a/units/systemd-tmpfiles-setup-dev.service.in +++ b/units/systemd-tmpfiles-setup-dev.service.in @@ -9,7 +9,7 @@ Description=Create static device nodes in /dev Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8) DefaultDependencies=no -Before=sysinit.target systemd-udevd.service +Before=sysinit.target local-fs-pre.target systemd-udevd.service ConditionCapability=CAP_MKNOD [Service] diff --git a/units/systemd-udevd.service.in b/units/systemd-udevd.service.in index ddef423625..99f51304e4 100644 --- a/units/systemd-udevd.service.in +++ b/units/systemd-udevd.service.in @@ -11,8 +11,8 @@ Documentation=man:systemd-udevd.service(8) man:udev(7) DefaultDependencies=no Wants=systemd-udevd-control.socket systemd-udevd-kernel.socket After=systemd-udevd-control.socket systemd-udevd-kernel.socket -Before=sysinit.target local-fs-pre.target -ConditionCapability=CAP_MKNOD +Before=sysinit.target +ConditionPathIsReadWrite=/sys [Service] Type=notify -- cgit v1.2.1 From c4955740969d7ba8ba43b024bca1a0a5b56eb8e8 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Tue, 9 Jul 2013 00:12:35 +0200 Subject: configure: fail if out-of-date kmod found and kmod not disabled Almost everyone wants kmod support, so don't fail silently if the libs are out-of-date. kmod can still be explicitly disabled and if it is not found at all, we still default to disabling it. --- configure.ac | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index be867079c2..7451ea4fd0 100644 --- a/configure.ac +++ b/configure.ac @@ -218,10 +218,14 @@ PKG_CHECK_MODULES(DBUS, [dbus-1 >= 1.3.2]) have_kmod=no AC_ARG_ENABLE(kmod, AS_HELP_STRING([--disable-kmod], [disable loadable modules support])) if test "x$enable_kmod" != "xno"; then - PKG_CHECK_MODULES(KMOD, [ libkmod >= 14 ], - [AC_DEFINE(HAVE_KMOD, 1, [Define if kmod is available]) have_kmod=yes], have_kmod=no) + PKG_CHECK_MODULES(KMOD, [ libkmod ], + [PKG_CHECK_MODULES(KMOD, [ libkmod >= 14 ], + [AC_DEFINE(HAVE_KMOD, 1, [Define if kmod is available]) have_kmod=yes], + AC_MSG_ERROR([*** kmod out-of-date, try --disable-kmod])) + ], + have_kmod=no) if test "x$have_kmod" = xno -a "x$enable_kmod" = xyes; then - AC_MSG_ERROR([*** kmod support requested but libraries not found]) + AC_MSG_ERROR([*** kmod support requested, but libraries not found]) fi fi AM_CONDITIONAL(HAVE_KMOD, [test "$have_kmod" = "yes"]) -- cgit v1.2.1 From 7b870f607bcb8f445d4d29a776d12d9de3bf1487 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Mon, 8 Jul 2013 18:19:02 +0200 Subject: man: wording and grammar updates --- man/machinectl.xml | 14 ++-- man/systemctl.xml | 180 ++++++++++++++++++++--------------------- man/systemd.journal-fields.xml | 8 +- 3 files changed, 101 insertions(+), 101 deletions(-) diff --git a/man/machinectl.xml b/man/machinectl.xml index 2606180d12..8a96d423b9 100644 --- a/man/machinectl.xml +++ b/man/machinectl.xml @@ -91,9 +91,9 @@ When showing - session/user properties, limit - display to certain properties as - specified as argument. If not + session/user properties, limit the + output to certain properties as + specified by the argument. If not specified, all set properties are shown. The argument should be a property name, such as @@ -109,7 +109,7 @@ When showing unit/job/manager properties, show all - properties regardless whether they are + properties regardless of whether they are set or not. @@ -159,8 +159,8 @@ kill-session or kill-user, choose which signal to send to selected - processes. Must be one of the well - known signal specifiers, such as + processes. Must be one of the well-known + signal specifiers, such as SIGTERM, SIGINT or SIGSTOP. If @@ -221,7 +221,7 @@ or more registered virtual machines or containers or the manager itself. If no argument is specified, properties - of the manager will be shown. If a an + of the manager will be shown. If an ID is specified, properties of this virtual machine or container are shown. By default, empty properties diff --git a/man/systemctl.xml b/man/systemctl.xml index 07e7363ab2..f5502153ad 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -99,12 +99,12 @@ along with systemd; If not, see . (types and states can be mixed). If one of the arguments is a unit type, when listing - units, limit display to certain unit types. Otherwise units + units, limit display to certain unit types. Otherwise, units of all types will be shown. If one of the arguments is a unit load state, when listing units, limit display to certain unit - types. Otherwise units of in all load states will be + types. Otherwise, units of in all load states will be shown. As a special case, if one of the arguments is @@ -120,10 +120,10 @@ along with systemd; If not, see . When showing unit/job/manager properties with the show command, limit display to certain - properties as specified as argument. If not specified all + properties as specified as argument. If not specified, all set properties are shown. The argument should be a comma-separated list of property names, such as - MainPID. If specified more than once all + MainPID. If specified more than once, all properties with the specified names are shown. @@ -159,8 +159,8 @@ along with systemd; If not, see . - Show which units are started after, resp. before - with list-dependencies. + Show which units are started after or before + with list-dependencies, respectively. @@ -191,7 +191,7 @@ along with systemd; If not, see . If the requested operation conflicts with a pending - unfinished job, fail the command. If this is not specified + unfinished job, fail the command. If this is not specified, the requested operation will replace the pending job, if necessary. Do not confuse with . @@ -221,8 +221,8 @@ along with systemd; If not, see . - When enqueuing a new job ignore all its dependencies - and execute it immediately. If passed no required units of + When enqueuing a new job, ignore all its dependencies + and execute it immediately. If passed, no required units of the unit passed will be pulled in, and no ordering dependencies will be honored. This is mostly a debugging and rescue tool for the administrator and should not be used by @@ -243,8 +243,8 @@ along with systemd; If not, see . users may override these locks. If any locks are taken, shutdown and sleep state requests will normally fail (regardless if privileged or not) and a list of active locks - is printed. However if - is specified the locks are ignored and not printed, and the + is printed. However, if + is specified, the locks are ignored and not printed, and the operation attempted anyway, possibly requiring additional privileges. @@ -269,9 +269,9 @@ along with systemd; If not, see . Do not synchronously wait for the requested operation - to finish. If this is not specified the job will be + to finish. If this is not specified, the job will be verified, enqueued and systemctl will - wait until it is completed. By passing this argument it is + wait until it is completed. By passing this argument, it is only verified and enqueued. @@ -314,7 +314,7 @@ along with systemd; If not, see . - Don't send wall message before halt, power-off, + Do not send wall message before halt, power-off, reboot. @@ -349,10 +349,10 @@ along with systemd; If not, see . may require input of a password or passphrase string, for example to unlock system hard disks or cryptographic certificates. Unless this option is specified and the - command is invoked from a terminal + command is invoked from a terminal, systemctl will query the user on the terminal for the necessary secrets. Use this option to - switch this behavior off. In this case the password must be + switch this behavior off. In this case, the password must be supplied by some other means (for example graphical password agents) or the service might fail. This also disables querying the user for authentication for privileged @@ -369,7 +369,7 @@ along with systemd; If not, see . processes to kill. Must be one of , or to select whether to kill only the main process of the unit, the - control process or all processes of the unit. If omitted + control process or all processes of the unit. If omitted, defaults to . @@ -383,7 +383,7 @@ along with systemd; If not, see . When used with kill, choose which signal to send to selected processes. Must be one of the well known signal specifiers such as SIGTERM, SIGINT or - SIGSTOP. If omitted defaults to + SIGSTOP. If omitted, defaults to . @@ -398,7 +398,7 @@ along with systemd; If not, see . When used with halt, poweroff, reboot or - kexec execute the selected operation + kexec, execute the selected operation without shutting down all units. However, all processes will be killed forcibly and all file systems are unmounted or remounted read-only. This is hence a drastic but relatively @@ -474,7 +474,7 @@ along with systemd; If not, see . - When used with status controls the + When used with status, controls the number of journal lines to show, counting from the most recent ones. Takes a positive integer argument. Defaults to 10. @@ -486,9 +486,9 @@ along with systemd; If not, see . - When used with status controls the + When used with status, controls the formatting of the journal entries that are shown. For the - available choices see + available choices, see journalctl1. Defaults to short. @@ -498,7 +498,7 @@ along with systemd; If not, see . - When used with list-dependencies + When used with list-dependencies, the output is printed as a list instead of a tree. @@ -539,7 +539,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service 5 sockets listed. Note: because the addresses might contains spaces, this output - is not suitable for programatic consumption. + is not suitable for programmatic consumption. See also the options , @@ -589,7 +589,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service for the example case of Apache, this will reload Apache's httpd.conf in the web server, not the apache.service systemd unit - file. + file. This command should not be confused with the daemon-reload or load @@ -602,7 +602,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service Restart one or more units specified on the command - line. If the units are not running yet they will be + line. If the units are not running yet, they will be started. @@ -611,9 +611,9 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service Restart one or more units specified on the command - line if the units are running. Do nothing if units are not - running. Note that for compatibility with Red Hat init - scripts condrestart is equivalent to this + line if the units are running. This does nothing if units are not + running. Note that, for compatibility with Red Hat init + scripts, condrestart is equivalent to this command. @@ -622,7 +622,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service Reload one or more units if they support it. If not, - restart them instead. If the units are not running yet they + restart them instead. If the units are not running yet, they will be started. @@ -631,8 +631,8 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service Reload one or more units if they support it. If not, - restart them instead. Do nothing if the units are not - running. Note that for compatibility with SysV init scripts + restart them instead. This does nothing if the units are not + running. Note that, for compatibility with SysV init scripts, force-reload is equivalent to this command. @@ -674,7 +674,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service Check whether any of the specified units are active (i.e. running). Returns an exit code 0 if at least one is active, non-zero otherwise. Unless - is specified this will also print the current unit state to + is specified, this will also print the current unit state to STDOUT. @@ -682,9 +682,9 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service is-failed NAME... - Check whether any of the specified units are failed. - Returns an exit code 0 if at least one is failed, non-zero - otherwise. Unless is specified this + Check whether any of the specified units are in a "failed" state. + Returns an exit code 0 if at least one has failed, non-zero + otherwise. Unless is specified, this will also print the current unit state to STDOUT. @@ -697,7 +697,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service more units, followed by most recent log data from the journal. If no units are specified, show all units (subject to limitations specified with ). If a PID - is passed show information about the unit the process + is passed, show information about the unit the process belongs to. This function is intended to generate human-readable @@ -731,12 +731,12 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service specified unit. Takes a unit name and one or more attribute names such as cpu.shares. This will output the current values of the specified attributes, - separated by new-lines. For attributes that take list of - items the output will be new-line-separated, too. This + separated by new-lines. For attributes that take a list of + items, the output will be newline-separated, too. This operation will always try to retrieve the data in question - from the kernel first, and if that is not available use the + from the kernel first, and if that is not available, use the configured values instead. Instead of low-level control - group attribute names high-level pretty names may be used, + group attribute names, high-level pretty names may be used, as used for unit execution environment configuration, see systemd.exec5 for details. For example, passing @@ -759,7 +759,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service setting for later reboots (unless is passed, in which case the setting is not saved persistently and only valid until the next reboot.) Instead - of low-level control group attribute names high-level pretty + of low-level control group attribute names, high-level pretty names may be used, as used for unit execution environment configuration, see systemd.exec5 @@ -772,7 +772,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service append the specified values to the previously set values list (use unset-cgroup-attr to reset the list explicitly). For attributes that take a single value - only the list will be reset implicitly. + only, the list will be reset implicitly. @@ -803,10 +803,10 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service unit name, plus a control group specification in the syntax CONTROLLER:PATH or CONTROLLER. In the latter syntax - (where the path is omitted) the default unit control group + (where the path is omitted), the default unit control group path is implied. Examples: cpu or cpu:/foo/bar. If a unit is removed from a - control group hierarchy all its processes will be moved to the + control group hierarchy, all its processes will be moved to the root group of the hierarchy and all control group attributes will be reset. These operations are immediately reflected in the kernel hierarchy, and stored persistently to disk (unless @@ -819,7 +819,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service Show manual pages for one or more units, if - available. If a PID is given the manual pages for the unit + available. If a PID is given, the manual pages for the unit the process belongs to are shown. @@ -829,10 +829,10 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service Reset the failed state of the - specified units, or if no unit name is passed of all + specified units, or if no unit name is passed, reset the state of all units. When a unit fails in some way (i.e. process exiting with non-zero error code, terminating abnormally or timing - out) it will automatically enter the + out), it will automatically enter the failed state and its exit code and status is recorded for introspection by the administrator until the service is restarted or reset with this command. @@ -855,15 +855,15 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service as specified on the command line. This will create a number of symlinks as encoded in the [Install] sections of the unit files. After the symlinks have been - created the systemd configuration is reloaded (in a way that + created, the systemd configuration is reloaded (in a way that is equivalent to daemon-reload) to ensure the changes are taken into account immediately. Note that this does not have the effect of also - starting starting any of the units beeing enabled. If this - is desired a separate start command must + starting any of the units being enabled. If this + is desired, a separate start command must be invoked for the unit. Also note that in case of instance - enablement, symlinks named same as instances are created in - install location, however they all point to the same + enablement, symlinks named the same as instances are created in + the install location, however they all point to the same template unit file. This command will print the actions executed. This @@ -874,12 +874,12 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service symlinks for the units. While this command is the recommended way to manipulate the unit configuration directory, the administrator is free to make additional - changes manually, by placing or removing symlinks in the + changes manually by placing or removing symlinks in the directory. This is particularly useful to create configurations that deviate from the suggested default - installation. In this case the administrator must make sure + installation. In this case, the administrator must make sure to invoke daemon-reload manually as - necessary, to ensure his changes are taken into account. + necessary to ensure the changes are taken into account. Enabling units should not be confused with starting @@ -895,9 +895,9 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service Depending on whether , or is - specified this enables the unit for the system, for the + specified, this enables the unit for the system, for the calling user only or for all future logins of all - users. Note that in the last case no systemd daemon + users. Note that in the last case, no systemd daemon configuration is reloaded. @@ -915,7 +915,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service enable. This call implicitly reloads the systemd daemon configuration after completing the disabling of the units. Note that this command does not implicitly - stop the units that are being disabled. If this is desired + stop the units that are being disabled. If this is desired, an additional stop command should be executed afterwards. @@ -937,7 +937,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service enabled (as with enable). Returns an exit code of 0 if at least one is enabled, non-zero otherwise. Prints the current enable status. To suppress - this output use . + this output, use . @@ -963,9 +963,9 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service policy files. This has the same effect as disable or enable, depending how the unit is listed in the preset files. For - more information on preset policy format see + more information on the preset policy format, see systemd.preset5. - For more information on the concept of presets please + For more information on the concept of presets, please consult the Preset document. @@ -1006,7 +1006,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service undone with disable. The effect of this command is that a unit file is available for start and other commands although it - isn't installed directly in the unit search path. + is not installed directly in the unit search path. @@ -1034,7 +1034,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service Load one or more units specified on the command line. This will simply load their configuration from disk, - but not start them. To start them you need to use the + but not start them. To start them, you need to use the start command which will implicitly load a unit that has not been loaded yet. Note that systemd garbage collects loaded units that are not active or @@ -1062,7 +1062,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service Cancel one or more jobs specified on the command line - by their numeric job IDs. If no job id is specified, cancel + by their numeric job IDs. If no job ID is specified, cancel all pending jobs. @@ -1081,10 +1081,10 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service Shows required and wanted units of the specified - unit. If no unit is specified + unit. If no unit is specified, default.target is implied. Target units are recursively expanded. When is - passed all other units are recursively expanded as + passed, all other units are recursively expanded as well. @@ -1094,14 +1094,14 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service Create a snapshot. If a snapshot name is specified, the new snapshot will be named after it. If none is - specified an automatic snapshot name is generated. In either + specified, an automatic snapshot name is generated. In either case, the snapshot name used is printed to STDOUT, unless is specified. A snapshot refers to a saved state of the systemd manager. It is implemented itself as a unit that is generated dynamically with this command and has dependencies - on all units active at the time. At a later time the user + on all units active at the time. At a later time, the user may return to this state by using the isolate command on the snapshot unit. @@ -1142,8 +1142,8 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service state again. This command is of little use except for debugging and package upgrades. Sometimes it might be helpful as a heavy-weight daemon-reload. - While the daemon is reexecuted all sockets systemd listens - on on behalf of user configuration will stay accessible. + While the daemon is reexecuted, all sockets systemd listening + on behalf of user configuration will stay accessible. @@ -1171,9 +1171,9 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service Unset one or more systemd manager environment - variables. If only a variable name is specified it will be + variables. If only a variable name is specified, it will be removed regardless of its value. If a variable and a value - are specified the variable is only removed if it has the + are specified, the variable is only removed if it has the specified value. @@ -1190,7 +1190,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service Enter rescue mode. This is mostly equivalent to - isolate rescue.target but also prints a + isolate rescue.target, but also prints a wall message to all users. @@ -1199,7 +1199,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service Enter emergency mode. This is mostly equivalent to - isolate emergency.target but also prints + isolate emergency.target, but also prints a wall message to all users. @@ -1208,13 +1208,13 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service Shut down and halt the system. This is mostly equivalent to - start halt.target --irreversible but also + start halt.target --irreversible, but also prints a wall message to all users. If combined with - shutdown of all running services is + , shutdown of all running services is skipped, however all processes are killed and all file systems are unmounted or mounted read-only, immediately followed by the system halt. If is - specified twice the operation is immediately executed + specified twice, the operation is immediately executed without terminating any processes or unmounting any file systems. This may result in data loss. @@ -1224,13 +1224,13 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service Shut down and power-off the system. This is mostly - equivalent to start poweroff.target --irreversible + equivalent to start poweroff.target --irreversible, but also prints a wall message to all users. If combined with - shutdown of all running services is + , shutdown of all running services is skipped, however all processes are killed and all file systems are unmounted or mounted read-only, immediately followed by the powering off. If is - specified twice the operation is immediately executed + specified twice, the operation is immediately executed without terminating any processes or unmounting any file systems. This may result in data loss. @@ -1240,13 +1240,13 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service Shut down and reboot the system. This is mostly - equivalent to start reboot.target --irreversible + equivalent to start reboot.target --irreversible, but also prints a wall message to all users. If combined with - shutdown of all running services is + , shutdown of all running services is skipped, however all processes are killed and all file systems are unmounted or mounted read-only, immediately followed by the reboot. If is - specified twice the operation is immediately executed + specified twice, the operation is immediately executed without terminating any processes or unmounting any file systems. This may result in data loss. @@ -1256,9 +1256,9 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service Shut down and reboot the system via kexec. This is - mostly equivalent to start kexec.target --irreversible + mostly equivalent to start kexec.target --irreversible, but also prints a wall message to all users. If combined - with shutdown of all running + with , shutdown of all running services is skipped, however all processes are killed and all file systems are unmounted or mounted read-only, immediately followed by the reboot. @@ -1310,13 +1310,13 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service new system manager process below it. This is intended for usage in initial RAM disks ("initrd"), and will transition from the initrd's system manager process (a.k.a "init" - process) to the main system manager process. Takes two - arguments: the directory to make the new root directory, and + process) to the main system manager process. This call takes two + arguments: the directory that is to become the new root directory, and the path to the new system manager binary below it to execute as PID 1. If the latter is omitted or the empty string, a systemd binary will automatically be searched for and used as init. If the system manager path is omitted or - equal to the empty string the state of the initrd's system + equal to the empty string, the state of the initrd's system manager process is passed to the main system manager, which allows later introspection of the state of the services involved in the initrd boot. @@ -1329,7 +1329,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service Exit status - On success 0 is returned, a non-zero failure + On success, 0 is returned, a non-zero failure code otherwise. diff --git a/man/systemd.journal-fields.xml b/man/systemd.journal-fields.xml index ad03282b1e..ed62edc849 100644 --- a/man/systemd.journal-fields.xml +++ b/man/systemd.journal-fields.xml @@ -454,7 +454,7 @@ attach OBJECT_PID= to a message. This will instruct systemd-journald to attach - additional fields on behalf of caller: + additional fields on behalf of the caller: @@ -480,7 +480,7 @@ OBJECT_SYSTEMD_UNIT= OBJECT_SYSTEMD_USER_UNIT= - Additional fields added automatically + These are additional fields added automatically by systemd-journald. Their meaning is the same as _UID=, @@ -495,8 +495,8 @@ _SYSTEMD_UNIT=, _SYSTEMD_USER_UNIT=, and _SYSTEMD_OWNER_UID= - described above, except that - process PID + as described above, except that the + process identified by PID is described, instead of the process which logged the message. -- cgit v1.2.1 From a3f6aa268c7d40f67d4e0d427bc26aef773db8ec Mon Sep 17 00:00:00 2001 From: "Jason St. John" Date: Tue, 9 Jul 2013 13:12:05 +0200 Subject: man: improve word usage and grammar in logind.conf(5) --- man/logind.conf.xml | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/man/logind.conf.xml b/man/logind.conf.xml index 74a100eb1e..8ab6d729a9 100644 --- a/man/logind.conf.xml +++ b/man/logind.conf.xml @@ -72,8 +72,8 @@ Takes a positive integer. Configures how many virtual terminals (VTs) to allocate by default - that -- when switched to and - previously unused -- + that, when switched to and are + previously unused, autovt services are automatically spawned on. These services are instantiated from the @@ -116,14 +116,14 @@ autovt@.service activation (see above). The VT selected with this option will be - marked busy unconditionally so that no + marked busy unconditionally, so that no other subsystem will allocate it. This functionality is useful to ensure that - regardless how many VTs are allocated + regardless of how many VTs are allocated by other subsystems, one login getty is always - available. Defaults to 6 (with other - words: there will always be a + available. Defaults to 6 (in other + words, there will always be a getty available on Alt-F6.). When set to 0, VT reservation is @@ -161,11 +161,11 @@ user sessions correctly report the idle status to the system. The system will execute the action after all - sessions reported that they are idle, - and no idle inhibitor lock is active, - and subsequently the time configured + sessions report that they are idle, + no idle inhibitor lock is active, + and subsequently, the time configured with IdleActionSec= - (see below) has passed. + (see below) has expired. @@ -197,7 +197,7 @@ killed. KillExcludeUsers= defaults to root and takes precedence over - KillOnlyUsers= + KillOnlyUsers=, which defaults to the empty list. @@ -221,8 +221,9 @@ Controllers= and be reset to the root control group in all hierarchies listed in - ResetControllers=. Controllers= - defaults to the empty list, + ResetControllers=. + Controllers= + defaults to the empty list. ResetControllers= defaults to cpu. Note that for @@ -243,8 +244,8 @@ time a system shutdown or sleep request is delayed due to an inhibitor lock of type delay - being active -- before it is ignored - and the operation executed + being active before the inhibitor is + ignored and the operation executes anyway. Defaults to 5s. @@ -311,7 +312,7 @@ SuspendKeyIgnoreInhibited= and HibernateKeyIgnoreInhibited= - defaults to off, + default to off. LidSwitchIgnoreInhibited= defaults to yes. This means -- cgit v1.2.1 From beef8df837fb0ef708143b34aa85a897400e8992 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 9 Jul 2013 15:47:11 +0200 Subject: hwdb: return false if no property is found --- src/udev/udev-builtin-hwdb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/udev/udev-builtin-hwdb.c b/src/udev/udev-builtin-hwdb.c index 314587f2bb..f1c0ca9cb1 100644 --- a/src/udev/udev-builtin-hwdb.c +++ b/src/udev/udev-builtin-hwdb.c @@ -178,9 +178,9 @@ static int builtin_hwdb(struct udev_device *dev, int argc, char *argv[], bool te } else srcdev = dev; - if (udev_builtin_hwdb_search(dev, srcdev, subsystem, prefix, filter, test) < 0) - return EXIT_FAILURE; - return EXIT_SUCCESS; + if (udev_builtin_hwdb_search(dev, srcdev, subsystem, prefix, filter, test) > 0) + return EXIT_SUCCESS; + return EXIT_FAILURE; } /* called at udev startup and reload */ -- cgit v1.2.1 From fade1ec6e05f9f6c3718be622e259d2c8e61508c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 10 Jul 2013 01:33:13 -0400 Subject: man: document four basic slices --- man/machinectl.xml | 3 +- man/systemd-machined.service.xml | 3 +- man/systemd.special.xml | 60 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/man/machinectl.xml b/man/machinectl.xml index 8a96d423b9..ced304d6d8 100644 --- a/man/machinectl.xml +++ b/man/machinectl.xml @@ -294,7 +294,8 @@ See Also systemd-machined.service8, - systemd-logind.service8 + systemd-logind.service8, + systemd.special7. diff --git a/man/systemd-machined.service.xml b/man/systemd-machined.service.xml index 3094315ecb..a9205d018e 100644 --- a/man/systemd-machined.service.xml +++ b/man/systemd-machined.service.xml @@ -69,7 +69,8 @@ See Also systemd1, - machinectl1. + machinectl1, + systemd.special7. diff --git a/man/systemd.special.xml b/man/systemd.special.xml index d1cd81f1d1..7dbc5580e2 100644 --- a/man/systemd.special.xml +++ b/man/systemd.special.xml @@ -100,7 +100,11 @@ system-update.target, time-sync.target, timers.target, - umount.target + umount.target, + -.slice, + system.slice, + user.slice, + machine.slice @@ -1022,6 +1026,59 @@ + + Special Slice Units + + There are four .slice units + which form the basis of the hierarchy for assignment + of resources for services, users, and virtual machines + or containers. + + + + -.slice + + The root slice is the + root of the hierarchy. It does + not contain services directly, + but is used to set defaults + for the whole tree. + + + + + system.slice + + This slice contains + services started by + systemd. + + + + + user.slice + + This slice contains user + processes and services started + on behalf of the user, + including the per-user systemd + instance. + + + + + machine.slice + + This slice contains + virtual machines and + containers registered with + systemd-machined. + + + + + + See Also @@ -1030,6 +1087,7 @@ systemd.service5, systemd.socket5, systemd.target5, + systemd.slice5, bootup7, systemd-fstab-generator8 -- cgit v1.2.1 From f09114bcc7dc9d4699e6ae41150056256bfbabb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 10 Jul 2013 01:24:46 -0400 Subject: man: document systemd-run --- Makefile-man.am | 1 + man/systemd-run.xml | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 man/systemd-run.xml diff --git a/Makefile-man.am b/Makefile-man.am index fef69be58e..bef749af86 100644 --- a/Makefile-man.am +++ b/Makefile-man.am @@ -63,6 +63,7 @@ MANPAGES += \ man/systemd-notify.1 \ man/systemd-nspawn.1 \ man/systemd-remount-fs.service.8 \ + man/systemd-run.1 \ man/systemd-shutdownd.service.8 \ man/systemd-sleep.conf.5 \ man/systemd-suspend.service.8 \ diff --git a/man/systemd-run.xml b/man/systemd-run.xml new file mode 100644 index 0000000000..4ced9bfc00 --- /dev/null +++ b/man/systemd-run.xml @@ -0,0 +1,160 @@ + + + + + + + + + systemd-run + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-run + 1 + + + + systemd-run + Run programs as volatile systemd units + + + + + systemd-run + OPTIONS + COMMAND + ARGS + + + + + + Description + + systemd-run may be used + create a transient .service unit + or a .scope unit and launch the + specified COMMAND as part + of this unit. + + + + Options + + The following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + + Prints a short version + string and exits. + + + + + + + Talk to the systemd manager of the calling + user. + + + + + + + + Create a .scope unit instead of + the default transient .service unit. + + + + + + + + Use this unit name instead of an automatically + generated one. + + + + + + Provide description for the unit. If not + specified, the command itself will be used as a description. + See Description= in + systemd.unit5. + + + + + + + Make the new .service or + .scope unit part of the specified slice, + instead of the system.slice. + + + + + All command-line arguments after the first non-option + argument become part of the commandline of the launched + process. + + + + Exit status + + On success, 0 is returned, a non-zero failure + code otherwise. + + + + See Also + + systemd1, + systemd.unit5, + systemd.service5, + systemd.scope5, + systemd.slice5. + + + + -- cgit v1.2.1 From 06639c0940ad9a81f085cbaff05bbf3f69a7f88f Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 10 Jul 2013 14:59:24 +0200 Subject: hwdb: allow list of lookup keys per given record This allows to specify: dmi:bvn*:bvr*:bd*:svnVENDOR:pn:Model 231*:pvr* dmi:bvn*:bvr*:bd*:svnVENDOR:pn:Series 12*:pvr* KEY_A=value KEY_B=value Instead of: dmi:bvn*:bvr*:bd*:svnVENDOR:pn:Model 231*:pvr* KEY_A=value KEY_B=value dmi:bvn*:bvr*:bd*:svnVENDOR:pn:Series 12*:pvr* KEY_A=value KEY_B=value --- src/udev/udevadm-hwdb.c | 127 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 97 insertions(+), 30 deletions(-) diff --git a/src/udev/udevadm-hwdb.c b/src/udev/udevadm-hwdb.c index 10b490ee2b..4136b17be5 100644 --- a/src/udev/udevadm-hwdb.c +++ b/src/udev/udevadm-hwdb.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "util.h" #include "strbuf.h" @@ -402,56 +403,122 @@ out: return err; } -static int import_file(struct trie *trie, const char *filename) { +static int insert_data(struct trie *trie, struct udev_list *match_list, + char *line, const char *filename) { + char *value; + struct udev_list_entry *entry; + + value = strchr(line, '='); + if (!value) { + log_error("Error, key/value pair expected but got '%s' in '%s':\n", line, filename); + return -EINVAL; + } + + value[0] = '\0'; + value++; + + if (line[0] == '\0' || value[0] == '\0') { + log_error("Error, empty key or value '%s' in '%s':\n", line, filename); + return -EINVAL; + } + + udev_list_entry_foreach(entry, udev_list_get_entry(match_list)) + trie_insert(trie, trie->root, udev_list_entry_get_name(entry), line, value); + + return 0; +} + +static int import_file(struct udev *udev, struct trie *trie, const char *filename) { + enum { + HW_MATCH, + HW_DATA, + HW_NONE, + } state = HW_NONE; FILE *f; char line[LINE_MAX]; - char match[LINE_MAX]; + struct udev_list match_list; + + udev_list_init(udev, &match_list, false); f = fopen(filename, "re"); if (f == NULL) return -errno; - match[0] = '\0'; while (fgets(line, sizeof(line), f)) { size_t len; + char *pos; + /* comment line */ if (line[0] == '#') continue; - /* new line, new record */ - if (line[0] == '\n') { - match[0] = '\0'; - continue; - } + /* strip trailing comment */ + pos = strchr(line, '#'); + if (pos) + pos[0] = '\0'; - /* remove newline */ + /* strip trailing whitespace */ len = strlen(line); - if (len < 2) - continue; - line[len-1] = '\0'; + while (len > 0 && isspace(line[len-1])) + len--; + line[len] = '\0'; + + switch (state) { + case HW_NONE: + if (len == 0) + break; + + if (line[0] == ' ') { + log_error("Error, MATCH expected but got '%s' in '%s':\n", line, filename); + break; + } - /* start of new record */ - if (match[0] == '\0') { - strcpy(match, line); - continue; - } + /* start of record, first match */ + state = HW_MATCH; + udev_list_entry_add(&match_list, line, NULL); + break; - /* value line */ - if (line[0] == ' ') { - char *value; + case HW_MATCH: + if (len == 0) { + log_error("Error, DATA expected but got empty line in '%s':\n", filename); + state = HW_NONE; + udev_list_cleanup(&match_list); + break; + } - value = strchr(line, '='); - if (!value) - continue; - value[0] = '\0'; - value++; - trie_insert(trie, trie->root, match, line, value); - continue; - } + /* another match */ + if (line[0] != ' ') { + udev_list_entry_add(&match_list, line, NULL); + break; + } + + /* first data */ + state = HW_DATA; + insert_data(trie, &match_list, line, filename); + break; + + case HW_DATA: + /* end of record */ + if (len == 0) { + state = HW_NONE; + udev_list_cleanup(&match_list); + break; + } + + if (line[0] != ' ') { + log_error("Error, DATA expected but got '%s' in '%s':\n", line, filename); + state = HW_NONE; + udev_list_cleanup(&match_list); + break; + } - log_error("Error parsing line '%s' in '%s\n", line, filename); + insert_data(trie, &match_list, line, filename); + break; + }; } + fclose(f); + udev_list_cleanup(&match_list); return 0; } @@ -539,7 +606,7 @@ static int adm_hwdb(struct udev *udev, int argc, char *argv[]) { } STRV_FOREACH(f, files) { log_debug("reading file '%s'", *f); - import_file(trie, *f); + import_file(udev, trie, *f); } strv_free(files); -- cgit v1.2.1 From 9d7d42bc406a2ac04639674281ce3ff6beeda790 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 10 Jul 2013 16:02:24 +0200 Subject: udev: add builtin 'keyboard' to manage key mappings --- Makefile.am | 27 +++++++ rules/60-keyboard.rules | 22 ++++++ shell-completion/bash/udevadm | 2 +- src/udev/.gitignore | 4 + src/udev/udev-builtin-keyboard.c | 163 +++++++++++++++++++++++++++++++++++++++ src/udev/udev-builtin.c | 1 + src/udev/udev.h | 2 + 7 files changed, 220 insertions(+), 1 deletion(-) create mode 100644 rules/60-keyboard.rules create mode 100644 src/udev/udev-builtin-keyboard.c diff --git a/Makefile.am b/Makefile.am index aa7e830222..f1dfeedf58 100644 --- a/Makefile.am +++ b/Makefile.am @@ -174,6 +174,7 @@ AM_CPPFLAGS = \ -I $(top_srcdir)/src/core \ -I $(top_srcdir)/src/libudev \ -I $(top_srcdir)/src/udev \ + -I $(top_builddir)/src/udev \ -I $(top_srcdir)/src/libsystemd-bus \ $(OUR_CPPFLAGS) @@ -2094,6 +2095,7 @@ dist_udevrules_DATA += \ rules/99-systemd.rules \ rules/42-usb-hid-pm.rules \ rules/50-udev-default.rules \ + rules/60-keyboard.rules \ rules/60-persistent-storage-tape.rules \ rules/60-persistent-serial.rules \ rules/60-persistent-input.rules \ @@ -2157,6 +2159,19 @@ rootlibexec_PROGRAMS += \ noinst_LTLIBRARIES += \ libudev-core.la +src/udev/keyboard-keys.txt: Makefile + $(AM_V_at)$(MKDIR_P) $(dir $@) + $(AM_V_GEN)$(CPP) $(CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) -dM -include linux/input.h - < /dev/null | $(AWK) '/^#define[ \t]+KEY_[^ ]+[ \t]+[0-9]/ { if ($$2 != "KEY_MAX") { print $$2 } }' | sed 's/^KEY_COFFEE$$/KEY_SCREENLOCK/' > $@ + +src/udev/keyboard-keys-from-name.gperf: src/udev/keyboard-keys.txt Makefile + $(AM_V_GEN)$(AWK) 'BEGIN{ print "struct key { const char* name; unsigned short id; };"; print "%null-strings"; print "%%";} { print tolower(substr($$1 ,5)) ", " $$1 }' < $< > $@ + +src/udev/keyboard-keys-from-name.h: src/udev/keyboard-keys-from-name.gperf Makefile + $(AM_V_GPERF)$(GPERF) -L ANSI-C -t -N keyboard_lookup_key -H hash_key_name -p -C < $< > $@ + +src/udev/keyboard-keys-to-name.h: src/udev/keyboard-keys.txt Makefile + $(AM_V_GEN)$(AWK) 'BEGIN{ print "const char* const key_names[KEY_CNT] = { "} { print "[" $$1 "] = \"" $$1 "\"," } END{print "};"}' < $< > $@ + libudev_core_la_SOURCES = \ src/udev/udev.h \ src/udev/udev-event.c \ @@ -2168,10 +2183,22 @@ libudev_core_la_SOURCES = \ src/udev/udev-builtin-btrfs.c \ src/udev/udev-builtin-hwdb.c \ src/udev/udev-builtin-input_id.c \ + src/udev/udev-builtin-keyboard.c \ src/udev/udev-builtin-net_id.c \ src/udev/udev-builtin-path_id.c \ src/udev/udev-builtin-usb_id.c +nodist_libudev_core_la_SOURCES = \ + src/udev/keyboard-keys-from-name.h \ + src/udev/keyboard-keys-to-name.h + +BUILT_SOURCES += \ + $(nodist_libudev_core_la_SOURCES) + +CLEANFILES += \ + src/udev/keyboard-keys-from-name.gperf \ + src/udev/keyboard-keys.txt + libudev_core_la_CFLAGS = \ $(AM_CFLAGS) \ $(BLKID_CFLAGS) \ diff --git a/rules/60-keyboard.rules b/rules/60-keyboard.rules new file mode 100644 index 0000000000..b925853c3e --- /dev/null +++ b/rules/60-keyboard.rules @@ -0,0 +1,22 @@ +# do not edit this file, it will be overwritten on update + +ACTION!="add", GOTO="keyboard_end" +KERNEL!="event*", GOTO="keyboard_end" +ENV{ID_INPUT_KEY}=="", GOTO="keyboard_end" + +# ignore all bluetooth devices +SUBSYSTEMS=="bluetooth", GOTO="keyboard_end" + +# import key mapping for USB device +SUBSYSTEMS=="usb", IMPORT{builtin}="hwdb --subsystem=usb --lookup-prefix=keyboard:", \ + RUN{program}+="keyboard", GOTO="keyboard_end" + +# import key mapping for AT keyboard from DMI data +DRIVERS=="atkbd", IMPORT{builtin}="hwdb 'keyboard:$attr{[dmi/id]modalias}'", \ + RUN{program}+="keyboard", GOTO="keyboard_end" + +# import key mapping for platform input device +KERNELS=="input*", IMPORT{builtin}="hwdb 'keyboard:name:$attr{name}:$attr{[dmi/id]modalias}'", \ + RUN{program}+="keyboard", GOTO="keyboard_end" + +LABEL="keyboard_end" diff --git a/shell-completion/bash/udevadm b/shell-completion/bash/udevadm index 123fb51633..e9ad179203 100644 --- a/shell-completion/bash/udevadm +++ b/shell-completion/bash/udevadm @@ -93,7 +93,7 @@ _udevadm() { fi elif __contains_word "$verb" ${VERBS[TESTBUILTIN]}; then - comps='blkid btrfs hwdb input_id kmod net_id path_id usb_id uaccess' + comps='blkid btrfs hwdb input_id keyboard kmod net_id path_id usb_id uaccess' fi COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) diff --git a/src/udev/.gitignore b/src/udev/.gitignore index 3e375a7726..a229430e36 100644 --- a/src/udev/.gitignore +++ b/src/udev/.gitignore @@ -1 +1,5 @@ /udev.pc +/keyboard-keys-from-name.gperf +/keyboard-keys-from-name.h +/keyboard-keys-to-name.h +/keyboard-keys.txt diff --git a/src/udev/udev-builtin-keyboard.c b/src/udev/udev-builtin-keyboard.c new file mode 100644 index 0000000000..ddd853594e --- /dev/null +++ b/src/udev/udev-builtin-keyboard.c @@ -0,0 +1,163 @@ +/*** + This file is part of systemd. + + Copyright 2013 Kay Sievers + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +static const struct key *keyboard_lookup_key(const char *str, unsigned int len); +#include "keyboard-keys-from-name.h" +#include "keyboard-keys-to-name.h" + +static int install_force_release(struct udev_device *dev, const unsigned int *release, unsigned int release_count) { + struct udev_device *atkbd; + const char *cur; + char codes[4096]; + char *s; + size_t l; + unsigned int i; + int ret; + + atkbd = udev_device_get_parent_with_subsystem_devtype(dev, "serio", NULL); + if (!atkbd) + return -ENODEV; + + cur = udev_device_get_sysattr_value(atkbd, "force_release"); + if (!cur) + return -ENODEV; + + s = codes; + l = sizeof(codes); + + /* copy current content */ + l = strpcpy(&s, l, cur); + + /* append new codes */ + for (i = 0; i < release_count; i++) + l = strpcpyf(&s, l, ",%d", release[i]); + + log_debug("keyboard: updating force-release list with '%s'\n", codes); + ret = udev_device_set_sysattr_value(atkbd, "force_release", codes); + if (ret < 0) + log_error("Error writing force-release attribute: %s", strerror(-ret)); + return ret; +} + +static int builtin_keyboard(struct udev_device *dev, int argc, char *argv[], bool test) { + struct udev_list_entry *entry; + struct { + unsigned int scan; + unsigned int key; + } map[1024]; + unsigned int map_count = 0; + unsigned int release[1024]; + unsigned int release_count = 0; + + udev_list_entry_foreach(entry, udev_device_get_properties_list_entry(dev)) { + const char *key; + unsigned int scancode; + char *endptr; + const char *keycode; + const struct key *k; + + key = udev_list_entry_get_name(entry); + if (!startswith(key, "KEYBOARD_KEY_")) + continue; + + /* KEYBOARD_KEY_= */ + scancode = strtol(key + 13, &endptr, 16); + if (endptr[0] != '\0') { + log_error("Error, unable to parse scan code from '%s'\n", key); + continue; + } + + keycode = udev_list_entry_get_value(entry); + + /* a leading '!' needs a force-release entry */ + if (keycode[0] == '!') { + keycode++; + + release[release_count] = scancode; + if (release_count < ELEMENTSOF(release)-1) + release_count++; + + if (keycode[0] == '\0') + continue; + } + + /* translate identifier to key code */ + k = keyboard_lookup_key(keycode, strlen(keycode)); + if (!k) { + log_error("Error, unknown key identifier '%s'\n", keycode); + continue; + } + + map[map_count].scan = scancode; + map[map_count].key = k->id; + if (map_count < ELEMENTSOF(map)-1) + map_count++; + } + + if (map_count > 0 || release_count > 0) { + const char *node; + int fd; + unsigned int i; + + node = udev_device_get_devnode(dev); + if (!node) { + log_error("Error, no device node for '%s'\n", udev_device_get_syspath(dev)); + return EXIT_FAILURE; + } + + fd = open(udev_device_get_devnode(dev), O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); + if (fd < 0) { + log_error("Error, opening device '%s': %m\n", node); + return EXIT_FAILURE; + } + + /* install list of map codes */ + for (i = 0; i < map_count; i++) { + log_debug("keyboard: mapping scan code %d (0x%x) to key code %d (0x%x)\n", + map[i].scan, map[i].scan, map[i].key, map[i].key); + if (ioctl(fd, EVIOCSKEYCODE, &map[i]) < 0) + log_error("Error calling EVIOCSKEYCODE: %m\n"); + } + + /* install list of force-release codes */ + if (release_count > 0) + install_force_release(dev, release, release_count); + + close(fd); + } + + return EXIT_SUCCESS; +} + +const struct udev_builtin udev_builtin_keyboard = { + .name = "keyboard", + .cmd = builtin_keyboard, + .help = "keyboard scan code to key mapping", +}; diff --git a/src/udev/udev-builtin.c b/src/udev/udev-builtin.c index c7d431988d..6b3a518c2e 100644 --- a/src/udev/udev-builtin.c +++ b/src/udev/udev-builtin.c @@ -39,6 +39,7 @@ static const struct udev_builtin *builtins[] = { #endif [UDEV_BUILTIN_HWDB] = &udev_builtin_hwdb, [UDEV_BUILTIN_INPUT_ID] = &udev_builtin_input_id, + [UDEV_BUILTIN_KEYBOARD] = &udev_builtin_keyboard, #ifdef HAVE_KMOD [UDEV_BUILTIN_KMOD] = &udev_builtin_kmod, #endif diff --git a/src/udev/udev.h b/src/udev/udev.h index 4f10c452e6..c9408f2d46 100644 --- a/src/udev/udev.h +++ b/src/udev/udev.h @@ -145,6 +145,7 @@ enum udev_builtin_cmd { #endif UDEV_BUILTIN_HWDB, UDEV_BUILTIN_INPUT_ID, + UDEV_BUILTIN_KEYBOARD, #ifdef HAVE_KMOD UDEV_BUILTIN_KMOD, #endif @@ -174,6 +175,7 @@ extern const struct udev_builtin udev_builtin_firmware; #endif extern const struct udev_builtin udev_builtin_hwdb; extern const struct udev_builtin udev_builtin_input_id; +extern const struct udev_builtin udev_builtin_keyboard; #ifdef HAVE_KMOD extern const struct udev_builtin udev_builtin_kmod; #endif -- cgit v1.2.1 From bdeeb6b543a2a2d0a494f17b85f1498859cdfc2f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 10 Jul 2013 02:01:14 +0200 Subject: update TODO --- TODO | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/TODO b/TODO index 0498809ea0..7d413a8de1 100644 --- a/TODO +++ b/TODO @@ -38,6 +38,18 @@ Features: * when a kernel driver logs in a tight loop we should ratelimit that too. +* journald: when we drop syslog messages because the syslog socket is + full, make sure to write how many messages are lost as first thing + to syslog when it works again. + +* prohibit Restart= set with Type=oneshot + +* man: the documentation of Restart= currently is very misleading and suggests the tools from ExecStartPre= might get restarted. + +* load .d/*.conf dropins for device units + +* user@.service and session-*.scope should get posession of their own cgroups + * move systemctl set-log-level to systemd-analyze? * fix killing spree logic in systemd-user-sessions -- cgit v1.2.1 From 376dd21dc0757e8a6d3f60d6d21bb802a90f1983 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 10 Jul 2013 02:01:29 +0200 Subject: cgroup: downgrade error message when we cannot remove a cgroup to debug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some units set KillMode=none to survive the initrd→rootfs transition. We cannot remove their cgroups, but that shouldn't really be considered an issue, so let's downgrade the error message. --- src/core/cgroup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/cgroup.c b/src/core/cgroup.c index c7f1e77c6c..b5d1347856 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -533,7 +533,7 @@ void unit_destroy_cgroup(Unit *u) { r = cg_trim_with_mask(u->cgroup_mask, u->cgroup_path, true); if (r < 0) - log_error("Failed to destroy cgroup %s: %s", u->cgroup_path, strerror(-r)); + log_debug("Failed to destroy cgroup %s: %s", u->cgroup_path, strerror(-r)); hashmap_remove(u->manager->cgroup_unit, u->cgroup_path); -- cgit v1.2.1 From 6fa4853328e3d78d092172fa54effb7e785d0a85 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 10 Jul 2013 19:24:03 +0200 Subject: core: serialize/deserialize bus subscribers --- src/core/dbus-manager.c | 14 ++----- src/core/dbus.c | 94 ++++++++++++++++++++++++++++++++++++---------- src/core/dbus.h | 5 +++ src/core/main.c | 2 +- src/core/manager.c | 14 ++++--- src/core/manager.h | 2 +- src/core/unit.c | 3 +- src/login/logind-dbus.c | 1 + src/shared/set.c | 5 ++- src/test/test-engine.c | 2 +- src/test/test-sched-prio.c | 2 +- src/test/test-unit-name.c | 2 +- 12 files changed, 104 insertions(+), 42 deletions(-) diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index fe2f749803..742f6bbd85 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -1057,17 +1057,9 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, SELINUX_ACCESS_CHECK(connection, message, "status"); - s = BUS_CONNECTION_SUBSCRIBED(m, connection); - if (!s) { - s = set_new(string_hash_func, string_compare_func); - if (!s) - goto oom; - - if (!dbus_connection_set_data(connection, m->subscribed_data_slot, s, NULL)) { - set_free(s); - goto oom; - } - } + s = bus_acquire_subscribed(m, connection); + if (!s) + goto oom; client = strdup(bus_message_get_sender_with_fallback(message)); if (!client) diff --git a/src/core/dbus.c b/src/core/dbus.c index c2097a4dbf..5180d89b2c 100644 --- a/src/core/dbus.c +++ b/src/core/dbus.c @@ -1135,19 +1135,19 @@ int bus_init(Manager *m, bool try_bus_connect) { if (set_ensure_allocated(&m->bus_connections, trivial_hash_func, trivial_compare_func) < 0 || set_ensure_allocated(&m->bus_connections_for_dispatch, trivial_hash_func, trivial_compare_func) < 0) - goto oom; + return log_oom(); if (m->name_data_slot < 0) if (!dbus_pending_call_allocate_data_slot(&m->name_data_slot)) - goto oom; + return log_oom(); if (m->conn_data_slot < 0) if (!dbus_pending_call_allocate_data_slot(&m->conn_data_slot)) - goto oom; + return log_oom(); if (m->subscribed_data_slot < 0) if (!dbus_connection_allocate_data_slot(&m->subscribed_data_slot)) - goto oom; + return log_oom(); if (try_bus_connect) { if ((r = bus_init_system(m)) < 0 || @@ -1155,16 +1155,14 @@ int bus_init(Manager *m, bool try_bus_connect) { return r; } - if ((r = bus_init_private(m)) < 0) + r = bus_init_private(m); + if (r < 0) return r; return 0; -oom: - return log_oom(); } static void shutdown_connection(Manager *m, DBusConnection *c) { - Set *s; Job *j; Iterator i; @@ -1180,15 +1178,7 @@ static void shutdown_connection(Manager *m, DBusConnection *c) { set_remove(m->bus_connections, c); set_remove(m->bus_connections_for_dispatch, c); - - if ((s = BUS_CONNECTION_SUBSCRIBED(m, c))) { - char *t; - - while ((t = set_steal_first(s))) - free(t); - - set_free(s); - } + set_free_free(BUS_CONNECTION_SUBSCRIBED(m, c)); if (m->queued_message_connection == c) { m->queued_message_connection = NULL; @@ -1259,10 +1249,10 @@ void bus_done(Manager *m) { set_free(m->bus_connections_for_dispatch); if (m->name_data_slot >= 0) - dbus_pending_call_free_data_slot(&m->name_data_slot); + dbus_pending_call_free_data_slot(&m->name_data_slot); if (m->conn_data_slot >= 0) - dbus_pending_call_free_data_slot(&m->conn_data_slot); + dbus_pending_call_free_data_slot(&m->conn_data_slot); if (m->subscribed_data_slot >= 0) dbus_connection_free_data_slot(&m->subscribed_data_slot); @@ -1488,3 +1478,69 @@ finish: if (message) dbus_message_unref(message); } + +Set *bus_acquire_subscribed(Manager *m, DBusConnection *c) { + Set *s; + + assert(m); + assert(c); + + s = BUS_CONNECTION_SUBSCRIBED(m, c); + if (s) + return s; + + s = set_new(string_hash_func, string_compare_func); + if (!s) + return NULL; + + if (!dbus_connection_set_data(c, m->subscribed_data_slot, s, NULL)) { + set_free(s); + return NULL; + } + + return s; +} + +void bus_serialize(Manager *m, FILE *f) { + char *client; + Iterator i; + Set *s; + + assert(m); + assert(f); + + if (!m->api_bus) + return; + + s = BUS_CONNECTION_SUBSCRIBED(m, m->api_bus); + SET_FOREACH(client, s, i) + fprintf(f, "subscribed=%s\n", client); +} + +int bus_deserialize_item(Manager *m, const char *line) { + const char *e; + char *b; + Set *s; + + assert(m); + assert(line); + + if (!m->api_bus) + return 0; + + e = startswith(line, "subscribed="); + if (!e) + return 0; + + s = bus_acquire_subscribed(m, m->api_bus); + if (!s) + return -ENOMEM; + + b = strdup(e); + if (!b) + return -ENOMEM; + + set_consume(s, b); + + return 1; +} diff --git a/src/core/dbus.h b/src/core/dbus.h index c7a058e198..b5c28c6ab6 100644 --- a/src/core/dbus.h +++ b/src/core/dbus.h @@ -44,6 +44,11 @@ int bus_fdset_add_all(Manager *m, FDSet *fds); void bus_broadcast_finished(Manager *m, usec_t firmware_usec, usec_t loader_usec, usec_t kernel_usec, usec_t initrd_usec, usec_t userspace_usec, usec_t total_usec); +Set *bus_acquire_subscribed(Manager *m, DBusConnection *c); + +void bus_serialize(Manager *m, FILE *f); +int bus_deserialize_item(Manager *m, const char *line); + #define BUS_CONNECTION_SUBSCRIBED(m, c) dbus_connection_get_data((c), (m)->subscribed_data_slot) #define BUS_PENDING_CALL_NAME(m, p) dbus_pending_call_get_data((p), (m)->name_data_slot) diff --git a/src/core/main.c b/src/core/main.c index 243855fa15..1d188e0bfe 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1613,7 +1613,7 @@ int main(int argc, char *argv[]) { if (arg_running_as == SYSTEMD_SYSTEM) bump_rlimit_nofile(&saved_rlimit_nofile); - r = manager_new(arg_running_as, &m); + r = manager_new(arg_running_as, !!serialization, &m); if (r < 0) { log_error("Failed to allocate manager object: %s", strerror(-r)); goto finish; diff --git a/src/core/manager.c b/src/core/manager.c index 6128194427..51f03de098 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -424,7 +424,7 @@ static void manager_strip_environment(Manager *m) { strv_env_clean(m->environment); } -int manager_new(SystemdRunningAs running_as, Manager **_m) { +int manager_new(SystemdRunningAs running_as, bool reexecuting, Manager **_m) { Manager *m; int r = -ENOMEM; @@ -476,7 +476,8 @@ int manager_new(SystemdRunningAs running_as, Manager **_m) { if (!m->cgroup_unit) goto fail; - if (!(m->watch_bus = hashmap_new(string_hash_func, string_compare_func))) + m->watch_bus = hashmap_new(string_hash_func, string_compare_func); + if (!m->watch_bus) goto fail; m->epoll_fd = epoll_create1(EPOLL_CLOEXEC); @@ -502,7 +503,7 @@ int manager_new(SystemdRunningAs running_as, Manager **_m) { /* Try to connect to the busses, if possible. */ if ((running_as == SYSTEMD_USER && getenv("DBUS_SESSION_BUS_ADDRESS")) || running_as == SYSTEMD_SYSTEM) { - r = bus_init(m, running_as != SYSTEMD_SYSTEM); + r = bus_init(m, reexecuting || running_as != SYSTEMD_SYSTEM); if (r < 0) goto fail; } else @@ -2041,6 +2042,8 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) { } } + bus_serialize(m, f); + fputc('\n', f); HASHMAP_FOREACH_KEY(u, t, m->units, i) { @@ -2054,7 +2057,8 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) { fputs(u->id, f); fputc('\n', f); - if ((r = unit_serialize(u, f, fds, !switching_root)) < 0) { + r = unit_serialize(u, f, fds, !switching_root); + if (r < 0) { m->n_reloading --; return r; } @@ -2159,7 +2163,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) { strv_free(m->environment); m->environment = e; - } else + } else if (bus_deserialize_item(m, l) == 0) log_debug("Unknown serialization item '%s'", l); } diff --git a/src/core/manager.h b/src/core/manager.h index 57a0a8d251..31da04e47c 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -248,7 +248,7 @@ struct Manager { char *switch_root_init; }; -int manager_new(SystemdRunningAs running_as, Manager **m); +int manager_new(SystemdRunningAs running_as, bool reexecuting, Manager **m); void manager_free(Manager *m); int manager_enumerate(Manager *m); diff --git a/src/core/unit.c b/src/core/unit.c index 447f2015ab..70cdd3d943 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -2128,7 +2128,8 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) { if (!unit_can_serialize(u)) return 0; - if ((r = UNIT_VTABLE(u)->serialize(u, f, fds)) < 0) + r = UNIT_VTABLE(u)->serialize(u, f, fds); + if (r < 0) return r; diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index eeff84394e..29a196323b 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -2411,6 +2411,7 @@ DBusHandlerResult bus_message_filter( if (u) user_add_to_gc_queue(u); } + } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Manager", "UnitRemoved")) { const char *path, *unit; diff --git a/src/shared/set.c b/src/shared/set.c index c338dc3a44..5a4bf11bdf 100644 --- a/src/shared/set.c +++ b/src/shared/set.c @@ -50,9 +50,12 @@ int set_put(Set *s, void *value) { } int set_consume(Set *s, void *value) { - int r = set_put(s, value); + int r; + + r = set_put(s, value); if (r < 0) free(value); + return r; } diff --git a/src/test/test-engine.c b/src/test/test-engine.c index 0f3862226a..20ae103a19 100644 --- a/src/test/test-engine.c +++ b/src/test/test-engine.c @@ -33,7 +33,7 @@ int main(int argc, char *argv[]) { assert_se(set_unit_path("test") >= 0); - assert_se(manager_new(SYSTEMD_SYSTEM, &m) >= 0); + assert_se(manager_new(SYSTEMD_SYSTEM, false, &m) >= 0); printf("Load1:\n"); assert_se(manager_load_unit(m, "a.service", NULL, NULL, &a) >= 0); diff --git a/src/test/test-sched-prio.c b/src/test/test-sched-prio.c index ba0aacf79d..7af740757a 100644 --- a/src/test/test-sched-prio.c +++ b/src/test/test-sched-prio.c @@ -34,7 +34,7 @@ int main(int argc, char *argv[]) { /* prepare the test */ assert_se(set_unit_path(TEST_DIR) >= 0); - r = manager_new(SYSTEMD_USER, &m); + r = manager_new(SYSTEMD_USER, false, &m); if (r == -EPERM) { puts("manager_new: Permission denied. Skipping test."); return EXIT_TEST_SKIP; diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c index 86cb2b8da6..93bf28aace 100644 --- a/src/test/test-unit-name.c +++ b/src/test/test-unit-name.c @@ -123,7 +123,7 @@ static int test_unit_printf(void) { assert_se((root = getpwnam("root"))); assert_se(asprintf(&root_uid, "%d", (int) root->pw_uid) > 0); - r = manager_new(SYSTEMD_USER, &m); + r = manager_new(SYSTEMD_USER, false, &m); if (r == -EPERM) { puts("manager_new: Permission denied. Skipping test."); return EXIT_TEST_SKIP; -- cgit v1.2.1 From b170dd803d334234ad7edd0dc7bb34860832bc07 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 10 Jul 2013 20:33:11 +0200 Subject: core: while we are reloading don't suppress bus signals While we are reloading we shouldn't suppress adding units to the bus queue when there are no subscribers, simply because we might not have deserialized the subscribers list yet. Hence, during reloading always assume we have subscribers. --- src/core/dbus-unit.c | 52 ++++++++++++++++++++++++++++++++-------------------- src/core/dbus.c | 6 ++++++ 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index 5831046305..4605b2fe07 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -568,8 +568,9 @@ const DBusObjectPathVTable bus_unit_vtable = { }; void bus_unit_send_change_signal(Unit *u) { - _cleanup_free_ char *p = NULL; _cleanup_dbus_message_unref_ DBusMessage *m = NULL; + _cleanup_free_ char *p = NULL; + int r; assert(u); @@ -587,8 +588,10 @@ void bus_unit_send_change_signal(Unit *u) { } p = unit_dbus_path(u); - if (!p) - goto oom; + if (!p) { + log_oom(); + return; + } if (u->sent_dbus_new_signal) { /* Send a properties changed signal. First for the @@ -601,19 +604,26 @@ void bus_unit_send_change_signal(Unit *u) { m = bus_properties_changed_new(p, UNIT_VTABLE(u)->bus_interface, UNIT_VTABLE(u)->bus_invalidating_properties); - if (!m) - goto oom; + if (!m) { + log_oom(); + return; + } - if (bus_broadcast(u->manager, m) < 0) - goto oom; + r = bus_broadcast(u->manager, m); + if (r < 0) { + log_error("Failed to broadcast change message: %s", strerror(-r)); + return; + } dbus_message_unref(m); } m = bus_properties_changed_new(p, "org.freedesktop.systemd1.Unit", INVALIDATING_PROPERTIES); - if (!m) - goto oom; + if (!m) { + log_oom(); + return; + } } else { /* Send a new signal */ @@ -621,25 +631,27 @@ void bus_unit_send_change_signal(Unit *u) { m = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitNew"); - if (!m) - goto oom; + if (!m) { + log_oom(); + return; + } if (!dbus_message_append_args(m, DBUS_TYPE_STRING, &u->id, DBUS_TYPE_OBJECT_PATH, &p, - DBUS_TYPE_INVALID)) - goto oom; + DBUS_TYPE_INVALID)) { + log_oom(); + return; + } } - if (bus_broadcast(u->manager, m) < 0) - goto oom; + r = bus_broadcast(u->manager, m); + if (r < 0) { + log_error("Failed to broadcast UnitNew/PropertiesChanged message."); + return; + } u->sent_dbus_new_signal = true; - - return; - -oom: - log_oom(); } void bus_unit_send_removed_signal(Unit *u) { diff --git a/src/core/dbus.c b/src/core/dbus.c index 5180d89b2c..c1bf25c69b 100644 --- a/src/core/dbus.c +++ b/src/core/dbus.c @@ -1379,6 +1379,12 @@ bool bus_has_subscriber(Manager *m) { assert(m); + /* If we are reloading then we might not have deserialized the + subscribers yet, hence let's assume that there are some */ + + if (m->n_reloading > 0) + return true; + SET_FOREACH(c, m->bus_connections_for_dispatch, i) if (bus_connection_has_subscriber(m, c)) return true; -- cgit v1.2.1 From 0c5778a26b14093c79bfc9e8b34e2aeeb1d79b87 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 10 Jul 2013 20:35:57 +0200 Subject: scope: don't require an initialized PIDs set when deserializing When a scope unit is created due to deserialization rather than client request don't enforce that the PIDs set must be non-empty, since the cgroup is already populated. --- src/core/scope.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/scope.c b/src/core/scope.c index e0de951b11..20a969d913 100644 --- a/src/core/scope.c +++ b/src/core/scope.c @@ -112,7 +112,7 @@ static int scope_verify(Scope *s) { if (UNIT(s)->load_state != UNIT_LOADED) return 0; - if (set_size(s->pids) <= 0) { + if (set_size(s->pids) <= 0 && UNIT(s)->manager->n_reloading <= 0) { log_error_unit(UNIT(s)->id, "Scope %s has no PIDs. Refusing.", UNIT(s)->id); return -EINVAL; } -- cgit v1.2.1 From 94c01aeb1049a87435e046245b8e5d975b778c60 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 10 Jul 2013 20:37:19 +0200 Subject: systemctl: suppress error messages when checking whether a unit needs to be reloaded --- src/systemctl/systemctl.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 04464deec8..e3818cd6df 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -1454,8 +1454,9 @@ static int cancel_job(DBusConnection *bus, char **args) { return 0; } -static bool need_daemon_reload(DBusConnection *bus, const char *unit) { +static int need_daemon_reload(DBusConnection *bus, const char *unit) { _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + _cleanup_dbus_error_free_ DBusError error; dbus_bool_t b = FALSE; DBusMessageIter iter, sub; const char @@ -1465,6 +1466,8 @@ static bool need_daemon_reload(DBusConnection *bus, const char *unit) { _cleanup_free_ char *n = NULL; int r; + dbus_error_init(&error); + /* We ignore all errors here, since this is used to show a warning only */ n = unit_name_mangle(unit); @@ -1478,7 +1481,7 @@ static bool need_daemon_reload(DBusConnection *bus, const char *unit) { "org.freedesktop.systemd1.Manager", "GetUnit", &reply, - NULL, + &error, DBUS_TYPE_STRING, &n, DBUS_TYPE_INVALID); if (r < 0) @@ -1499,7 +1502,7 @@ static bool need_daemon_reload(DBusConnection *bus, const char *unit) { "org.freedesktop.DBus.Properties", "Get", &reply, - NULL, + &error, DBUS_TYPE_STRING, &interface, DBUS_TYPE_STRING, &property, DBUS_TYPE_INVALID); @@ -1919,7 +1922,7 @@ static int start_unit_one( return -EIO; } - if (need_daemon_reload(bus, n)) + if (need_daemon_reload(bus, n) > 0) log_warning("Warning: Unit file of %s changed on disk, 'systemctl %sdaemon-reload' recommended.", n, arg_scope == UNIT_FILE_SYSTEM ? "" : "--user "); -- cgit v1.2.1 From d0ede8f1c555500dceebd3cc8a8e877ed1d89de6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 10 Jul 2013 20:44:21 +0200 Subject: systemctl: suppress error message when doing "systemctl daemon-reexec" When we issue a reexecution request via the private socket we need to expect a "Disconnected" in addition to "NoReply" when the connection is terminated. --- src/shared/dbus-common.c | 2 ++ src/systemctl/systemctl.c | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/shared/dbus-common.c b/src/shared/dbus-common.c index f579567321..c727cae7cd 100644 --- a/src/shared/dbus-common.c +++ b/src/shared/dbus-common.c @@ -1383,6 +1383,8 @@ int bus_method_call_with_reply( r = -EACCES; else if (dbus_error_has_name(&error, DBUS_ERROR_NO_REPLY)) r = -ETIMEDOUT; + else if (dbus_error_has_name(&error, DBUS_ERROR_DISCONNECTED)) + r = -ECONNRESET; else r = -EIO; goto finish; diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index e3818cd6df..d25b7d6fae 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -3938,9 +3938,9 @@ static int daemon_reload(DBusConnection *bus, char **args) { /* There's always a fallback possible for * legacy actions. */ r = -EADDRNOTAVAIL; - else if (r == -ETIMEDOUT && streq(method, "Reexecute")) - /* On reexecution, we expect a disconnect, not - * a reply */ + else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute")) + /* On reexecution, we expect a disconnect, not a + * reply */ r = 0; else if (r < 0) log_error("Failed to issue method call: %s", bus_error_message(&error)); -- cgit v1.2.1 From 71445ae75b0e9954d141e5f0ee97803b406ea332 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 10 Jul 2013 21:10:53 +0200 Subject: core: send out "Reloading" signal before and after doing a full reload/reexec of PID 1 Since we'll unload all units/job during a reload, and then readd them it is really useful for clients to be aware of this phase hence sent a signal out before and after. This signal is called "Reloading" (despite the fact that it is also sent out during reexecution, which we consider a special case in this context) and has one boolean parameter which is true for the signal sent before the reload, and false for the signal after the reload. The UnitRemoved/JobRremoved and UnitNew/JobNew due to the reloading are guranteed to be between the pair of Reloading messages. --- src/core/dbus-manager.c | 5 ++++- src/core/dbus.c | 36 ++++++++++++++++++++++++++++++------ src/core/dbus.h | 1 + src/core/main.c | 7 ++++--- src/core/manager.c | 15 +++++++++++++++ src/core/manager.h | 2 ++ 6 files changed, 56 insertions(+), 10 deletions(-) diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 742f6bbd85..d7604b1ab9 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -276,7 +276,10 @@ " \n" \ " \n" \ " " \ - " \n" + " \n" \ + " \n" \ + " \n" \ + " " #define BUS_MANAGER_INTERFACE_PROPERTIES_GENERAL \ " \n" \ diff --git a/src/core/dbus.c b/src/core/dbus.c index c1bf25c69b..aa3d93bf06 100644 --- a/src/core/dbus.c +++ b/src/core/dbus.c @@ -1451,7 +1451,7 @@ void bus_broadcast_finished( usec_t userspace_usec, usec_t total_usec) { - DBusMessage *message; + _cleanup_dbus_message_unref_ DBusMessage *message = NULL; assert(m); @@ -1471,18 +1471,42 @@ void bus_broadcast_finished( DBUS_TYPE_UINT64, &total_usec, DBUS_TYPE_INVALID)) { log_oom(); - goto finish; + return; } if (bus_broadcast(m, message) < 0) { log_oom(); - goto finish; + return; } +} -finish: - if (message) - dbus_message_unref(message); +void bus_broadcast_reloading(Manager *m, bool active) { + + _cleanup_dbus_message_unref_ DBusMessage *message = NULL; + dbus_bool_t b = active; + + assert(m); + + message = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading"); + if (!message) { + log_oom(); + return; + } + + assert_cc(sizeof(usec_t) == sizeof(uint64_t)); + if (!dbus_message_append_args(message, + DBUS_TYPE_BOOLEAN, &b, + DBUS_TYPE_INVALID)) { + log_oom(); + return; + } + + + if (bus_broadcast(m, message) < 0) { + log_oom(); + return; + } } Set *bus_acquire_subscribed(Manager *m, DBusConnection *c) { diff --git a/src/core/dbus.h b/src/core/dbus.h index b5c28c6ab6..6500cd7455 100644 --- a/src/core/dbus.h +++ b/src/core/dbus.h @@ -43,6 +43,7 @@ bool bus_connection_has_subscriber(Manager *m, DBusConnection *c); int bus_fdset_add_all(Manager *m, FDSet *fds); void bus_broadcast_finished(Manager *m, usec_t firmware_usec, usec_t loader_usec, usec_t kernel_usec, usec_t initrd_usec, usec_t userspace_usec, usec_t total_usec); +void bus_broadcast_reloading(Manager *m, bool active); Set *bus_acquire_subscribed(Manager *m, DBusConnection *c); diff --git a/src/core/main.c b/src/core/main.c index 1d188e0bfe..efc5791bbc 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1055,15 +1055,16 @@ static int prepare_reexecute(Manager *m, FILE **_f, FDSet **_fds, bool switching assert(_f); assert(_fds); - /* Make sure nothing is really destructed when we shut down */ - m->n_reloading ++; - r = manager_open_serialization(m, &f); if (r < 0) { log_error("Failed to create serialization file: %s", strerror(-r)); goto fail; } + /* Make sure nothing is really destructed when we shut down */ + m->n_reloading ++; + bus_broadcast_reloading(m, true); + fds = fdset_new(); if (!fds) { r = -ENOMEM; diff --git a/src/core/manager.c b/src/core/manager.c index 51f03de098..2e98181b37 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -864,6 +864,11 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) { if (serialization) { assert(m->n_reloading > 0); m->n_reloading --; + + /* Let's wait for the UnitNew/JobNew messages being + * sent, before we notify that the reload is + * finished */ + m->send_reloading_done = true; } return r; @@ -1163,6 +1168,13 @@ unsigned manager_dispatch_dbus_queue(Manager *m) { } m->dispatching_dbus_queue = false; + + if (m->send_reloading_done) { + m->send_reloading_done = false; + + bus_broadcast_reloading(m, false); + } + return n; } @@ -2238,6 +2250,7 @@ int manager_reload(Manager *m) { return r; m->n_reloading ++; + bus_broadcast_reloading(m, true); fds = fdset_new(); if (!fds) { @@ -2297,6 +2310,8 @@ int manager_reload(Manager *m) { assert(m->n_reloading > 0); m->n_reloading--; + m->send_reloading_done = true; + finish: if (f) fclose(f); diff --git a/src/core/manager.h b/src/core/manager.h index 31da04e47c..6d5241497d 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -195,6 +195,8 @@ struct Manager { int32_t conn_data_slot; int32_t subscribed_data_slot; + bool send_reloading_done; + uint32_t current_job_id; uint32_t default_unit_job_id; -- cgit v1.2.1 From b9316fb0f39fff3df792e4e72eb491ec4265b91f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 10 Jul 2013 21:13:56 +0200 Subject: unit: save description/slice of transient units to /run This is necessary so that these properties survive a daemon reload. --- src/core/dbus-unit.c | 15 +++++++++++++++ src/core/load-fragment-gperf.gperf.m4 | 2 ++ 2 files changed, 17 insertions(+) diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index 4605b2fe07..e07a28e32d 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -794,6 +794,7 @@ static int bus_unit_set_transient_property( return -EINVAL; if (mode != UNIT_CHECK) { + _cleanup_free_ char *contents = NULL; const char *description; dbus_message_iter_get_basic(i, &description); @@ -801,6 +802,12 @@ static int bus_unit_set_transient_property( r = unit_set_description(u, description); if (r < 0) return r; + + contents = strjoin("[Unit]\nDescription=", description, "\n", NULL); + if (!contents) + return -ENOMEM; + + unit_write_drop_in(u, mode, "Description", contents); } return 1; @@ -818,6 +825,8 @@ static int bus_unit_set_transient_property( if (mode != UNIT_CHECK) unit_ref_unset(&u->slice); } else { + _cleanup_free_ char *contents = NULL; + r = manager_load_unit(u->manager, s, NULL, error, &slice); if (r < 0) return r; @@ -827,6 +836,12 @@ static int bus_unit_set_transient_property( if (mode != UNIT_CHECK) unit_ref_set(&u->slice, slice); + + contents = strjoin("[", UNIT_VTABLE(u)->private_section, "]\nSlice=", s, NULL); + if (!contents) + return -ENOMEM; + + unit_write_drop_in(u, mode, "Slice", contents); } return 1; } diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index 2325d6aa9a..76fc9c48ac 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -259,6 +259,8 @@ Path.MakeDirectory, config_parse_bool, 0, Path.DirectoryMode, config_parse_mode, 0, offsetof(Path, directory_mode) m4_dnl CGROUP_CONTEXT_CONFIG_ITEMS(Slice)m4_dnl +m4_dnl +CGROUP_CONTEXT_CONFIG_ITEMS(Scope)m4_dnl m4_dnl The [Install] section is ignored here. Install.Alias, NULL, 0, 0 Install.WantedBy, NULL, 0, 0 -- cgit v1.2.1 From 72673e866a83e6aafdbb599eb3eff2617b7dc79d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 10 Jul 2013 21:17:37 +0200 Subject: unit: when deserializing cgroup path add it back into cgroup hashmap Also, properly remove cgroup path from hashmap when freeing unit. --- src/core/unit.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/core/unit.c b/src/core/unit.c index 70cdd3d943..5bc57e25c6 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -433,7 +433,11 @@ void unit_free(Unit *u) { if (u->in_cgroup_queue) LIST_REMOVE(Unit, cgroup_queue, u->manager->cgroup_queue, u); - free(u->cgroup_path); + if (u->cgroup_path) { + hashmap_remove(u->manager->cgroup_unit, u->cgroup_path); + free(u->cgroup_path); + } + free(u->description); strv_free(u->documentation); free(u->fragment_path); @@ -2308,6 +2312,8 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) { free(u->cgroup_path); u->cgroup_path = s; + + hashmap_put(u->manager->cgroup_unit, s, u); continue; } -- cgit v1.2.1 From 6797c324a653f119a3d7133122648aaa4878ddd6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 10 Jul 2013 23:31:40 +0200 Subject: logind: don't misunderstand UnitRemoved signals during reloading When PID 1 reloads the units logind/machined will see UnitRemoved signals for all units. Instead of trusting these immediately, let's check the actual unit state before considering a unit gone, so that reloading PID 1 is not mistaken as the end of all sessions. --- src/login/logind-dbus.c | 72 ++++++++++++++++++++++++++++++++------------- src/login/logind.c | 13 +++++++- src/machine/machined-dbus.c | 51 +++++++++++++++++++++++++++----- src/machine/machined.c | 12 ++++++++ 4 files changed, 120 insertions(+), 28 deletions(-) diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 29a196323b..ec46fdc232 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -2427,28 +2427,32 @@ DBusHandlerResult bus_message_filter( } session = hashmap_get(m->session_units, unit); - if (session) { - hashmap_remove(m->session_units, session->scope); - free(session->scope); - session->scope = NULL; + if (session) + session_add_to_gc_queue(session); - session_add_to_gc_queue(session); + user = hashmap_get(m->user_units, unit); + if (user) + user_add_to_gc_queue(user); + + } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Manager", "Reloading")) { + dbus_bool_t b; + + if (!dbus_message_get_args(message, &error, + DBUS_TYPE_BOOLEAN, &b, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse Reloading message: %s", bus_error_message(&error)); + goto finish; } - user = hashmap_get(m->user_units, unit); - if (user) { - - if (streq_ptr(unit, user->service)) { - hashmap_remove(m->user_units, user->service); - free(user->service); - user->service = NULL; - } else if (streq_ptr(unit, user->slice)) { - hashmap_remove(m->user_units, user->slice); - free(user->slice); - user->slice = NULL; - } + /* systemd finished reloading, let's recheck all our sessions */ + if (!b) { + Session *session; + Iterator i; - user_add_to_gc_queue(user); + log_debug("System manager has been reloaded, rechecking sessions..."); + + HASHMAP_FOREACH(session, m->sessions, i) + session_add_to_gc_queue(session); } } @@ -2682,6 +2686,16 @@ int manager_stop_unit(Manager *manager, const char *unit, DBusError *error, char DBUS_TYPE_STRING, &fail, DBUS_TYPE_INVALID); if (r < 0) { + if (dbus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) || + dbus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) { + + if (job) + *job = NULL; + + dbus_error_free(error); + return 0; + } + log_error("Failed to stop unit %s: %s", unit, bus_error(error, r)); return r; } @@ -2704,7 +2718,7 @@ int manager_stop_unit(Manager *manager, const char *unit, DBusError *error, char *job = copy; } - return 0; + return 1; } int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, DBusError *error) { @@ -2769,8 +2783,26 @@ int manager_unit_is_active(Manager *manager, const char *unit) { DBUS_TYPE_STRING, &interface, DBUS_TYPE_STRING, &property, DBUS_TYPE_INVALID); - if (r < 0) { + if (dbus_error_has_name(&error, DBUS_ERROR_NO_REPLY) || + dbus_error_has_name(&error, DBUS_ERROR_DISCONNECTED)) { + /* systemd might have droppped off + * momentarily, let's not make this an + * error */ + + dbus_error_free(&error); + return true; + } + + if (dbus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) || + dbus_error_has_name(&error, BUS_ERROR_LOAD_FAILED)) { + /* If the unit is already unloaded then it's + * not active */ + + dbus_error_free(&error); + return false; + } + log_error("Failed to query ActiveState: %s", bus_error(&error, r)); dbus_error_free(&error); return r; diff --git a/src/login/logind.c b/src/login/logind.c index fcb3ccf4a5..a79ba333d2 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -1038,12 +1038,23 @@ static int manager_connect_bus(Manager *m) { "interface='org.freedesktop.DBus.Properties'," "member='PropertiesChanged'", &error); - if (dbus_error_is_set(&error)) { log_error("Failed to add match for PropertiesChanged: %s", bus_error_message(&error)); dbus_error_free(&error); } + dbus_bus_add_match(m->bus, + "type='signal'," + "sender='org.freedesktop.systemd1'," + "interface='org.freedesktop.systemd1.Manager'," + "member='Reloading'," + "path='/org/freedesktop/systemd1'", + &error); + if (dbus_error_is_set(&error)) { + log_error("Failed to add match for Reloading: %s", bus_error_message(&error)); + dbus_error_free(&error); + } + r = bus_method_call_with_reply( m->bus, "org.freedesktop.systemd1", diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c index 1b1eb3a333..4664c73a9c 100644 --- a/src/machine/machined-dbus.c +++ b/src/machine/machined-dbus.c @@ -583,12 +583,28 @@ DBusHandlerResult bus_message_filter( } mm = hashmap_get(m->machine_units, unit); - if (mm) { - hashmap_remove(m->machine_units, mm->scope); - free(mm->scope); - mm->scope = NULL; - + if (mm) machine_add_to_gc_queue(mm); + + } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Manager", "Reloading")) { + dbus_bool_t b; + + if (!dbus_message_get_args(message, &error, + DBUS_TYPE_BOOLEAN, &b, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse Reloading message: %s", bus_error_message(&error)); + goto finish; + } + + /* systemd finished reloading, let's recheck all our machines */ + if (!b) { + Machine *mm; + Iterator i; + + log_debug("System manager has been reloaded, rechecking machines..."); + + HASHMAP_FOREACH(mm, m->machines, i) + machine_add_to_gc_queue(mm); } } @@ -727,6 +743,16 @@ int manager_stop_unit(Manager *manager, const char *unit, DBusError *error, char DBUS_TYPE_STRING, &fail, DBUS_TYPE_INVALID); if (r < 0) { + if (dbus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) || + dbus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) { + + if (job) + *job = NULL; + + dbus_error_free(error); + return 0; + } + log_error("Failed to stop unit %s: %s", unit, bus_error(error, r)); return r; } @@ -749,7 +775,7 @@ int manager_stop_unit(Manager *manager, const char *unit, DBusError *error, char *job = copy; } - return 0; + return 1; } int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, DBusError *error) { @@ -814,8 +840,19 @@ int manager_unit_is_active(Manager *manager, const char *unit) { DBUS_TYPE_STRING, &interface, DBUS_TYPE_STRING, &property, DBUS_TYPE_INVALID); - if (r < 0) { + if (dbus_error_has_name(&error, DBUS_ERROR_NO_REPLY) || + dbus_error_has_name(&error, DBUS_ERROR_DISCONNECTED)) { + dbus_error_free(&error); + return true; + } + + if (dbus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) || + dbus_error_has_name(&error, BUS_ERROR_LOAD_FAILED)) { + dbus_error_free(&error); + return false; + } + log_error("Failed to query ActiveState: %s", bus_error(&error, r)); dbus_error_free(&error); return r; diff --git a/src/machine/machined.c b/src/machine/machined.c index f2803a18c9..c7c4ecc375 100644 --- a/src/machine/machined.c +++ b/src/machine/machined.c @@ -233,6 +233,18 @@ static int manager_connect_bus(Manager *m) { dbus_error_free(&error); } + dbus_bus_add_match(m->bus, + "type='signal'," + "sender='org.freedesktop.systemd1'," + "interface='org.freedesktop.systemd1.Manager'," + "member='Reloading'," + "path='/org/freedesktop/systemd1'", + &error); + if (dbus_error_is_set(&error)) { + log_error("Failed to add match for Reloading: %s", bus_error_message(&error)); + dbus_error_free(&error); + } + r = bus_method_call_with_reply( m->bus, "org.freedesktop.systemd1", -- cgit v1.2.1 From f2d4f98d5873e0649b79b04b967fc9625ab3a350 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 10 Jul 2013 23:33:17 +0200 Subject: logind: when creating the scope job fails, return this immediately to the client that wants to register the session Otherwise we'll hanging for the job to finish without any job existing. Similar, for machined. --- src/login/logind-session.c | 1 + src/machine/machine.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 2892c38417..3c67f86b17 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -480,6 +480,7 @@ static int session_start_scope(Session *s) { dbus_error_free(&error); free(scope); + return r; } else { s->scope = scope; diff --git a/src/machine/machine.c b/src/machine/machine.c index d75c338189..591a656f1e 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -247,6 +247,7 @@ static int machine_start_scope(Machine *m) { dbus_error_free(&error); free(scope); + return r; } else { m->scope = scope; -- cgit v1.2.1 From 7fb3ee51c1b37738fd0ea2c81dfd6c336144698a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 10 Jul 2013 23:39:46 +0200 Subject: user-sessions: rely on PID 1 to kill sessions As we want to centralized cgroup access we should stop killing the user sessions directly from the systemd-user-sessions service. Instead, rely on PID 1 doing this by adding the right ordering dependencies to the session scope units. --- src/core/dbus-unit.c | 57 +++++++++++++++++++++++ src/login/logind-dbus.c | 15 ++++++ src/login/logind-session.c | 2 +- src/login/logind.h | 2 +- src/login/user-sessions.c | 111 +-------------------------------------------- 5 files changed, 75 insertions(+), 112 deletions(-) diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index e07a28e32d..57fac00d19 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -844,6 +844,63 @@ static int bus_unit_set_transient_property( unit_write_drop_in(u, mode, "Slice", contents); } return 1; + + } else if (streq(name, "Requires") || + streq(name, "RequiresOverridable") || + streq(name, "Requisite") || + streq(name, "RequisiteOverridable") || + streq(name, "Wants") || + streq(name, "BindsTo") || + streq(name, "Conflicts") || + streq(name, "Before") || + streq(name, "After") || + streq(name, "OnFailure") || + streq(name, "PropagatesReloadTo") || + streq(name, "ReloadPropagatedFrom") || + streq(name, "PartOf")) { + + UnitDependency d; + DBusMessageIter sub; + + d = unit_dependency_from_string(name); + if (d < 0) + return -EINVAL; + + if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(i) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_recurse(i, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING) { + const char *other; + + dbus_message_iter_get_basic(&sub, &other); + + if (!unit_name_is_valid(other, false)) + return -EINVAL; + + if (mode != UNIT_CHECK) { + _cleanup_free_ char *label = NULL, *contents = NULL; + + r = unit_add_dependency_by_name(u, d, other, NULL, true); + if (r < 0) + return r; + + label = strjoin(name, "-", other, NULL); + if (!label) + return -ENOMEM; + + contents = strjoin("[Unit]\n", name, "=", other, "\n", NULL); + if (!contents) + return -ENOMEM; + + unit_write_drop_in(u, mode, label, contents); + } + + dbus_message_iter_next(&sub); + } + + return 1; } return 0; diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index ec46fdc232..39af637d1b 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -2518,6 +2518,7 @@ int manager_start_scope( pid_t pid, const char *slice, const char *description, + const char *after, DBusError *error, char **job) { @@ -2575,6 +2576,20 @@ int manager_start_scope( return log_oom(); } + if (!isempty(after)) { + const char *after_property = "After"; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &after_property) || + !dbus_message_iter_open_container(&sub2, DBUS_TYPE_VARIANT, "as", &sub3) || + !dbus_message_iter_open_container(&sub3, DBUS_TYPE_ARRAY, "s", &sub4) || + !dbus_message_iter_append_basic(&sub4, DBUS_TYPE_STRING, &after) || + !dbus_message_iter_close_container(&sub3, &sub4) || + !dbus_message_iter_close_container(&sub2, &sub3) || + !dbus_message_iter_close_container(&sub, &sub2)) + return log_oom(); + } + /* cgroup empty notification is not available in containers * currently. To make this less problematic, let's shorten the * stop timeout for sessions, so that we don't wait diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 3c67f86b17..db22150825 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -474,7 +474,7 @@ static int session_start_scope(Session *s) { description = strjoin("Session ", s->id, " of user ", s->user->name, NULL); - r = manager_start_scope(s->manager, scope, s->leader, s->user->slice, description, &error, &job); + r = manager_start_scope(s->manager, scope, s->leader, s->user->slice, description, "systemd-user-sessions.service", &error, &job); if (r < 0) { log_error("Failed to start session scope: %s %s", bus_error(&error, r), error.name); dbus_error_free(&error); diff --git a/src/login/logind.h b/src/login/logind.h index f7457c0537..9c41cdf70c 100644 --- a/src/login/logind.h +++ b/src/login/logind.h @@ -178,7 +178,7 @@ int manager_send_changed(Manager *manager, const char *properties); int manager_dispatch_delayed(Manager *manager); -int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, DBusError *error, char **job); +int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, const char *after, DBusError *error, char **job); int manager_start_unit(Manager *manager, const char *unit, DBusError *error, char **job); int manager_stop_unit(Manager *manager, const char *unit, DBusError *error, char **job); int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, DBusError *error); diff --git a/src/login/user-sessions.c b/src/login/user-sessions.c index 18066ccc39..45fb427671 100644 --- a/src/login/user-sessions.c +++ b/src/login/user-sessions.c @@ -25,109 +25,8 @@ #include "log.h" #include "util.h" -#include "cgroup-util.h" #include "fileio.h" -static int kill_all_users(void) { - _cleanup_closedir_ DIR *d = NULL; - struct dirent *de; - int r = 0; - - d = opendir("/run/systemd/users"); - if (!d) { - if (errno == ENOENT) - return 0; - - log_error("Failed to open /run/systemd/users: %m"); - return -errno; - } - - FOREACH_DIRENT(de, d, return -errno) { - _cleanup_free_ char *cgroup = NULL; - char *a; - int k; - - if (!dirent_is_file(de)) - continue; - - a = strappenda("/run/systemd/users/", de->d_name); - - k = parse_env_file(a, NEWLINE, "CGROUP", &cgroup, NULL); - if (k < 0) { - if (k != -ENOENT) { - log_error("Failed to read user data: %s", strerror(-k)); - r = k; - } - - continue; - } - - if (!cgroup) { - log_error("User data did not contain cgroup field."); - r = -ENOENT; - continue; - } - - k = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, cgroup, true); - if (k < 0) { - log_error("Failed to kill cgroup %s: %s", cgroup, strerror(-k)); - r = k; - } - } - - return r; -} - -static int kill_all_sessions(void) { - _cleanup_closedir_ DIR *d = NULL; - struct dirent *de; - int r = 0; - - d = opendir("/run/systemd/sessions"); - if (!d) { - if (errno == ENOENT) - return 0; - - log_error("Failed to open /run/systemd/sessions: %m"); - return -errno; - } - - FOREACH_DIRENT(de, d, return -errno) { - _cleanup_free_ char *cgroup = NULL; - char *a; - int k; - - if (!dirent_is_file(de)) - continue; - - a = strappenda("/run/systemd/sessions/", de->d_name); - - k = parse_env_file(a, NEWLINE, "CGROUP", &cgroup, NULL); - if (k < 0) { - if (k != -ENOENT) { - log_error("Failed to read session data: %s", strerror(-k)); - r = k; - } - - continue; - } - - if (!cgroup) { - log_error("Session data did not contain cgroup field."); - r = -ENOENT; - continue; - } - - k = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, cgroup, true); - if (k < 0) { - log_error("Failed to kill cgroup %s: %s", cgroup, strerror(-k)); - r = k; - } - } - - return r; -} - int main(int argc, char*argv[]) { int ret = EXIT_FAILURE; @@ -167,20 +66,12 @@ int main(int argc, char*argv[]) { goto finish; } else if (streq(argv[1], "stop")) { - int r, q; + int r; r = write_string_file_atomic("/run/nologin", "System is going down."); if (r < 0) log_error("Failed to create /run/nologin: %s", strerror(-r)); - q = kill_all_users(); - if (q < 0 && r >= 0) - r = q; - - q = kill_all_sessions(); - if (q < 0 && r >= 0) - r = q; - } else { log_error("Unknown verb %s.", argv[1]); goto finish; -- cgit v1.2.1 From 49998ede042907b0ba7f5e85e02fa569da26bc04 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 10 Jul 2013 23:46:30 +0200 Subject: update TODO --- TODO | 5 ----- 1 file changed, 5 deletions(-) diff --git a/TODO b/TODO index 7d413a8de1..420f0ccb8f 100644 --- a/TODO +++ b/TODO @@ -90,14 +90,9 @@ Features: * journald: make sure ratelimit is actually really per-service with the new cgroup changes -* move systemctl dump to systemd-analyze - * libsystemd-logind: sd_session_is_active() and friends: verify validity of session name before appending it to a path -* logind: when a PAM client calls ReleaseSession() start a timeout and - kill the session entirely after that is reached. - * gparted needs to disable auto-activation of mount units somehow, or maybe we should stop doing auto-activiation of this after boot entirely. https://bugzilla.gnome.org/show_bug.cgi?id=701676 -- cgit v1.2.1 From ac9ef33358b6e6277cfca86a85a49a022824549e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 10 Jul 2013 23:47:15 +0200 Subject: cgroup: when uninstalling agent, actually turn it off first --- src/shared/cgroup-util.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index 73013d1d97..8f3c64fdc5 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -794,6 +794,17 @@ int cg_uninstall_release_agent(const char *controller) { _cleanup_free_ char *fs = NULL; int r; + r = cg_get_path(controller, NULL, "notify_on_release", &fs); + if (r < 0) + return r; + + r = write_string_file(fs, "0"); + if (r < 0) + return r; + + free(fs); + fs = NULL; + r = cg_get_path(controller, NULL, "release_agent", &fs); if (r < 0) return r; @@ -802,7 +813,7 @@ int cg_uninstall_release_agent(const char *controller) { if (r < 0) return r; - return 0; + return 0; } int cg_is_empty(const char *controller, const char *path, bool ignore_self) { -- cgit v1.2.1 From 66713f77e851c12452729d37e22ef66673852b8f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 10 Jul 2013 23:50:28 +0200 Subject: core: uninstall cgroup agent only if we are running outside of a container Since the cgroupfs is currently not virtualized for containers we shouldn't reset the hosts agent from the container. --- src/core/main.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index efc5791bbc..0ba1d15033 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1943,9 +1943,11 @@ finish: watchdog_close(true); } - /* avoid the creation of new processes forked by the kernel; at this - * point, we will not listen to the signals anyway */ - cg_uninstall_release_agent(SYSTEMD_CGROUP_CONTROLLER); + /* Avoid the creation of new processes forked by the + * kernel; at this point, we will not listen to the + * signals anyway */ + if (detect_container(NULL) <= 0) + cg_uninstall_release_agent(SYSTEMD_CGROUP_CONTROLLER); execve(SYSTEMD_SHUTDOWN_BINARY_PATH, (char **) command_line, env_block); free(env_block); -- cgit v1.2.1 From 8577e67245fc5d38bfdc32349388769895202bc4 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 11 Jul 2013 00:13:46 +0200 Subject: shutdown: fix /proc/cmdline reading of 'quiet' --- src/core/shutdown.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/core/shutdown.c b/src/core/shutdown.c index c02a14d66e..fe7a0739db 100644 --- a/src/core/shutdown.c +++ b/src/core/shutdown.c @@ -144,11 +144,18 @@ int main(int argc, char *argv[]) { char *w, *state; size_t l; - FOREACH_WORD_QUOTED(w, l, line, state) - if (streq(w, "quiet")) { + FOREACH_WORD_QUOTED(w, l, line, state) { + _cleanup_free_ char *word; + + word = strndup(w, l); + if (!word) + break; + + if (streq(word, "quiet")) { log_set_max_level(LOG_WARNING); break; } + } } log_parse_environment(); -- cgit v1.2.1 From aa1936ea1a89c2bb968ba33e3274898a4eeae771 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 11 Jul 2013 00:27:54 +0200 Subject: loginctl: restore cgroup display for status output Same for machinectl. --- src/login/loginctl.c | 135 +++++++++++++++++++++++++++-------------------- src/machine/machinectl.c | 105 +++++++++++++++++++++++++----------- 2 files changed, 154 insertions(+), 86 deletions(-) diff --git a/src/login/loginctl.c b/src/login/loginctl.c index e118deffda..93f4beed37 100644 --- a/src/login/loginctl.c +++ b/src/login/loginctl.c @@ -34,6 +34,7 @@ #include "dbus-common.h" #include "build.h" #include "strv.h" +#include "unit-name.h" #include "cgroup-show.h" #include "sysfs-show.h" #include "spawn-polkit-agent.h" @@ -261,12 +262,76 @@ static int list_seats(DBusConnection *bus, char **args, unsigned n) { return 0; } +static int show_unit_cgroup(DBusConnection *bus, const char *interface, const char *unit) { + const char *property = "ControlGroup"; + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + _cleanup_free_ char *path = NULL; + DBusMessageIter iter, sub; + const char *cgroup; + DBusError error; + int r, output_flags; + unsigned c; + + assert(bus); + assert(unit); + + if (arg_transport == TRANSPORT_SSH) + return 0; + + path = unit_dbus_path_from_name(unit); + if (!path) + return log_oom(); + + r = bus_method_call_with_reply( + bus, + "org.freedesktop.systemd1", + path, + "org.freedesktop.DBus.Properties", + "Get", + &reply, + &error, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_STRING, &property, + DBUS_TYPE_INVALID); + if (r < 0) { + log_error("Failed to query ControlGroup: %s", bus_error(&error, r)); + dbus_error_free(&error); + return r; + } + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) { + log_error("Failed to parse reply."); + return -EINVAL; + } + + dbus_message_iter_recurse(&iter, &sub); + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) { + log_error("Failed to parse reply."); + return -EINVAL; + } + + dbus_message_iter_get_basic(&sub, &cgroup); + + output_flags = + arg_all * OUTPUT_SHOW_ALL | + arg_full * OUTPUT_FULL_WIDTH; + + c = columns(); + if (c > 18) + c -= 18; + else + c = 0; + + show_cgroup_by_path(cgroup, "\t\t ", c, false, output_flags); + return 0; +} + typedef struct SessionStatusInfo { const char *id; uid_t uid; const char *name; usec_t timestamp; - const char *default_control_group; int vtnr; const char *seat; const char *tty; @@ -279,14 +344,13 @@ typedef struct SessionStatusInfo { const char *type; const char *class; const char *state; - const char *slice; + const char *scope; } SessionStatusInfo; typedef struct UserStatusInfo { uid_t uid; const char *name; usec_t timestamp; - const char *default_control_group; const char *state; char **sessions; const char *display; @@ -299,7 +363,7 @@ typedef struct SeatStatusInfo { char **sessions; } SeatStatusInfo; -static void print_session_status_info(SessionStatusInfo *i) { +static void print_session_status_info(DBusConnection *bus, SessionStatusInfo *i) { char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1; char since2[FORMAT_TIMESTAMP_MAX], *s2; assert(i); @@ -375,33 +439,13 @@ static void print_session_status_info(SessionStatusInfo *i) { if (i->state) printf("\t State: %s\n", i->state); - if (i->slice) - printf("\t Slice: %s\n", i->slice); - - if (i->default_control_group) { - unsigned c; - int output_flags = - arg_all * OUTPUT_SHOW_ALL | - arg_full * OUTPUT_FULL_WIDTH; - - printf("\t CGroup: %s\n", i->default_control_group); - - if (arg_transport != TRANSPORT_SSH) { - c = columns(); - if (c > 18) - c -= 18; - else - c = 0; - - show_cgroup_and_extra_by_spec(i->default_control_group, - "\t\t ", c, false, &i->leader, - i->leader > 0 ? 1 : 0, - output_flags); - } + if (i->scope) { + printf("\t Unit: %s\n", i->scope); + show_unit_cgroup(bus, "org.freedesktop.systemd1.Scope", i->scope); } } -static void print_user_status_info(UserStatusInfo *i) { +static void print_user_status_info(DBusConnection *bus, UserStatusInfo *i) { char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1; char since2[FORMAT_TIMESTAMP_MAX], *s2; assert(i); @@ -422,8 +466,6 @@ static void print_user_status_info(UserStatusInfo *i) { if (!isempty(i->state)) printf("\t State: %s\n", i->state); - if (i->slice) - printf("\t Slice: %s\n", i->slice); if (!strv_isempty(i->sessions)) { char **l; @@ -439,24 +481,9 @@ static void print_user_status_info(UserStatusInfo *i) { printf("\n"); } - if (i->default_control_group) { - unsigned c; - int output_flags = - arg_all * OUTPUT_SHOW_ALL | - arg_full * OUTPUT_FULL_WIDTH; - - printf("\t CGroup: %s\n", i->default_control_group); - - if (arg_transport != TRANSPORT_SSH) { - c = columns(); - if (c > 18) - c -= 18; - else - c = 0; - - show_cgroup_by_path(i->default_control_group, "\t\t ", - c, false, output_flags); - } + if (i->slice) { + printf("\t Unit: %s\n", i->slice); + show_unit_cgroup(bus, "org.freedesktop.systemd1.Slice", i->slice); } } @@ -511,8 +538,6 @@ static int status_property_session(const char *name, DBusMessageIter *iter, Sess i->id = s; else if (streq(name, "Name")) i->name = s; - else if (streq(name, "DefaultControlGroup")) - i->default_control_group = s; else if (streq(name, "TTY")) i->tty = s; else if (streq(name, "Display")) @@ -527,8 +552,8 @@ static int status_property_session(const char *name, DBusMessageIter *iter, Sess i->type = s; else if (streq(name, "Class")) i->class = s; - else if (streq(name, "Slice")) - i->slice = s; + else if (streq(name, "Scope")) + i->scope = s; else if (streq(name, "State")) i->state = s; } @@ -612,8 +637,6 @@ static int status_property_user(const char *name, DBusMessageIter *iter, UserSta if (!isempty(s)) { if (streq(name, "Name")) i->name = s; - else if (streq(name, "DefaultControlGroup")) - i->default_control_group = s; else if (streq(name, "Slice")) i->slice = s; else if (streq(name, "State")) @@ -924,9 +947,9 @@ static int show_one(const char *verb, DBusConnection *bus, const char *path, boo if (!show_properties) { if (strstr(verb, "session")) - print_session_status_info(&session_info); + print_session_status_info(bus, &session_info); else if (strstr(verb, "user")) - print_user_status_info(&user_info); + print_user_status_info(bus, &user_info); else print_seat_status_info(&seat_info); } diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c index 34bbe36109..cd640e76ae 100644 --- a/src/machine/machinectl.c +++ b/src/machine/machinectl.c @@ -34,6 +34,7 @@ #include "dbus-common.h" #include "build.h" #include "strv.h" +#include "unit-name.h" #include "cgroup-show.h" #include "spawn-polkit-agent.h" @@ -124,19 +125,84 @@ static int list_machines(DBusConnection *bus, char **args, unsigned n) { return 0; } +static int show_scope_cgroup(DBusConnection *bus, const char *unit) { + const char *interface = "org.freedesktop.systemd1.Scope"; + const char *property = "ControlGroup"; + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + _cleanup_free_ char *path = NULL; + DBusMessageIter iter, sub; + const char *cgroup; + DBusError error; + int r, output_flags; + unsigned c; + + assert(bus); + assert(unit); + + if (arg_transport == TRANSPORT_SSH) + return 0; + + path = unit_dbus_path_from_name(unit); + if (!path) + return log_oom(); + + r = bus_method_call_with_reply( + bus, + "org.freedesktop.systemd1", + path, + "org.freedesktop.DBus.Properties", + "Get", + &reply, + &error, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_STRING, &property, + DBUS_TYPE_INVALID); + if (r < 0) { + log_error("Failed to query ControlGroup: %s", bus_error(&error, r)); + dbus_error_free(&error); + return r; + } + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) { + log_error("Failed to parse reply."); + return -EINVAL; + } + + dbus_message_iter_recurse(&iter, &sub); + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) { + log_error("Failed to parse reply."); + return -EINVAL; + } + + dbus_message_iter_get_basic(&sub, &cgroup); + + output_flags = + arg_all * OUTPUT_SHOW_ALL | + arg_full * OUTPUT_FULL_WIDTH; + + c = columns(); + if (c > 18) + c -= 18; + else + c = 0; + + show_cgroup_by_path(cgroup, "\t\t ", c, false, output_flags); + return 0; +} + typedef struct MachineStatusInfo { const char *name; sd_id128_t id; - const char *default_control_group; const char *class; const char *service; - const char *slice; + const char *scope; const char *root_directory; pid_t leader; usec_t timestamp; } MachineStatusInfo; -static void print_machine_status_info(MachineStatusInfo *i) { +static void print_machine_status_info(DBusConnection *bus, MachineStatusInfo *i) { char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1; char since2[FORMAT_TIMESTAMP_MAX], *s2; assert(i); @@ -178,31 +244,12 @@ static void print_machine_status_info(MachineStatusInfo *i) { } else if (i->class) printf("\t Class: %s\n", i->class); - if (i->slice) - printf("\t Slice: %s\n", i->slice); if (i->root_directory) printf("\t Root: %s\n", i->root_directory); - if (i->default_control_group) { - unsigned c; - int output_flags = - arg_all * OUTPUT_SHOW_ALL | - arg_full * OUTPUT_FULL_WIDTH; - - printf("\t CGroup: %s\n", i->default_control_group); - - if (arg_transport != TRANSPORT_SSH) { - c = columns(); - if (c > 18) - c -= 18; - else - c = 0; - - show_cgroup_and_extra_by_spec(i->default_control_group, - "\t\t ", c, false, &i->leader, - i->leader > 0 ? 1 : 0, - output_flags); - } + if (i->scope) { + printf("\t Unit: %s\n", i->scope); + show_scope_cgroup(bus, i->scope); } } @@ -221,14 +268,12 @@ static int status_property_machine(const char *name, DBusMessageIter *iter, Mach if (!isempty(s)) { if (streq(name, "Name")) i->name = s; - else if (streq(name, "DefaultControlGroup")) - i->default_control_group = s; else if (streq(name, "Class")) i->class = s; else if (streq(name, "Service")) i->service = s; - else if (streq(name, "Slice")) - i->slice = s; + else if (streq(name, "Scope")) + i->scope = s; else if (streq(name, "RootDirectory")) i->root_directory = s; } @@ -373,7 +418,7 @@ static int show_one(const char *verb, DBusConnection *bus, const char *path, boo } if (!show_properties) - print_machine_status_info(&machine_info); + print_machine_status_info(bus, &machine_info); r = 0; -- cgit v1.2.1 From bafb15bab99887d1b6b8a35136531bac6c3876a6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 11 Jul 2013 00:28:35 +0200 Subject: update TODO --- TODO | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/TODO b/TODO index 420f0ccb8f..27d5df6ae1 100644 --- a/TODO +++ b/TODO @@ -34,6 +34,32 @@ Fedora 19: * when installing fedora with yum --installroot /var/run is a directory, not a symlink +CGroup Rework Completion: + +* user@.service and session-*.scope should get posession of their own cgroups + +* introduce "mainpid" for scopes + +* implement system-wide DefaultCPUAccounting=1 switch (and similar for blockio, memory?) + +* implement per-slice CPUFairScheduling=1 switch + +* handle jointly mounted controllers correctly + +* logind: implement session kill exceptions + +* fix machine regstration to forward property array + +* add implicit slice for instantiated services + +* make BlockIODeviceWeight=, BlockIODeviceBandwidth= runtime settable + +* split up BlockIOWeight= and BlockIODeviceWeight= + +* introduce high-level settings for RT budget, swapiness + +* man: document new bus apis + Features: * when a kernel driver logs in a tight loop we should ratelimit that too. @@ -48,46 +74,20 @@ Features: * load .d/*.conf dropins for device units -* user@.service and session-*.scope should get posession of their own cgroups - * move systemctl set-log-level to systemd-analyze? -* fix killing spree logic in systemd-user-sessions - -* logind: implement session kill exceptions - -* fix machine regstration to forward property array - -* fix loginctl cgroup enumeration - * move "systemctl dump" to systemd-analyze -* introduce "mainpid" for scopes - * add a fixed dbus path for "my own unit", "my own session", ... to PID1, logind, ... -* add implicit slice for instantiated services - * service_coldplug() appears to reinstall the wrong stop timeout watch? * transient units: allow creating auxiliary units with the same call -* make BlockIODeviceWeight=, BlockIODeviceBandwidth= runtime settable - -* split up BlockIOWeight= and BlockIODeviceWeight= - -* introduce high-level settings for RT budget, swapiness - * how to reset dynamically changed attributes sanely? * when reloading configuration, apply new cgroup configuration -* implement system-wide DefaultCPUAccounting=1 switch (and similar for blockio, memory?) - -* implement per-slice CPUFairScheduling=1 switch - -* handle jointly mounted controllers correctly - * journald: make sure ratelimit is actually really per-service with the new cgroup changes * libsystemd-logind: sd_session_is_active() and friends: verify -- cgit v1.2.1 From f6940be7825755d77ade4cd42231aab9e3580623 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 11 Jul 2013 00:35:01 +0200 Subject: shutdown: avoid malloc() if we can --- src/core/shutdown.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/core/shutdown.c b/src/core/shutdown.c index fe7a0739db..10a52bd117 100644 --- a/src/core/shutdown.c +++ b/src/core/shutdown.c @@ -145,13 +145,7 @@ int main(int argc, char *argv[]) { size_t l; FOREACH_WORD_QUOTED(w, l, line, state) { - _cleanup_free_ char *word; - - word = strndup(w, l); - if (!word) - break; - - if (streq(word, "quiet")) { + if (l == 5 && memcmp(w, "quiet", 5) == 0) { log_set_max_level(LOG_WARNING); break; } -- cgit v1.2.1 From befb5b6a71c175d523644edbddd01b4b722fe956 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 11 Jul 2013 00:48:52 +0200 Subject: core: rearrange if blocks a bit --- src/core/main.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index 0ba1d15033..749397578a 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1515,12 +1515,7 @@ int main(int argc, char *argv[]) { /* All other variables are left as is, so that clients * can still read them via /proc/1/environ */ - } - - /* Move out of the way, so that we won't block unmounts */ - assert_se(chdir("/") == 0); - if (arg_running_as == SYSTEMD_SYSTEM) { /* Become a session leader if we aren't one yet. */ setsid(); @@ -1528,6 +1523,9 @@ int main(int argc, char *argv[]) { umask(0); } + /* Move out of the way, so that we won't block unmounts */ + assert_se(chdir("/") == 0); + /* Make sure D-Bus doesn't fiddle with the SIGPIPE handlers */ dbus_connection_set_change_sigpipe(FALSE); -- cgit v1.2.1 From 8aa75193662d0e18d7c21ee9d546b7f3c8b8bc14 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 11 Jul 2013 01:56:12 +0200 Subject: core: grant user@.service instances write access to their own cgroup --- src/core/execute.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/core/execute.c b/src/core/execute.c index cbeb0caf26..50d2d49ba8 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -1258,6 +1258,23 @@ int exec_spawn(ExecCommand *command, } } +#ifdef HAVE_PAM + if (cgroup_path && context->user && context->pam_name) { + err = cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER, cgroup_path, 0644, uid, gid); + if (err < 0) { + r = EXIT_CGROUP; + goto fail_child; + } + + + err = cg_set_group_access(SYSTEMD_CGROUP_CONTROLLER, cgroup_path, 0755, uid, gid); + if (err < 0) { + r = EXIT_CGROUP; + goto fail_child; + } + } +#endif + if (apply_permissions) { err = enforce_groups(context, username, gid); if (err < 0) { -- cgit v1.2.1 From 049b4474b35d0b854f87b0795a5113665413f6a4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 11 Jul 2013 01:56:45 +0200 Subject: update TODO --- TODO | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index 27d5df6ae1..864516101b 100644 --- a/TODO +++ b/TODO @@ -36,8 +36,6 @@ Fedora 19: CGroup Rework Completion: -* user@.service and session-*.scope should get posession of their own cgroups - * introduce "mainpid" for scopes * implement system-wide DefaultCPUAccounting=1 switch (and similar for blockio, memory?) @@ -56,12 +54,14 @@ CGroup Rework Completion: * split up BlockIOWeight= and BlockIODeviceWeight= -* introduce high-level settings for RT budget, swapiness +* introduce high-level settings for RT budget, swappiness * man: document new bus apis Features: +* do we really need both hasprefix() and startswith()? + * when a kernel driver logs in a tight loop we should ratelimit that too. * journald: when we drop syslog messages because the syslog socket is -- cgit v1.2.1 From 4c5420a0c1429de866c4dfbe2f973cfa241bdbe4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 11 Jul 2013 01:57:09 +0200 Subject: units: since we auto-spawn user@.service instances now we don need an [Install] section in it --- units/user@.service.in | 3 --- 1 file changed, 3 deletions(-) diff --git a/units/user@.service.in b/units/user@.service.in index d2d24f10bc..8f9a3b3347 100644 --- a/units/user@.service.in +++ b/units/user@.service.in @@ -16,6 +16,3 @@ Type=notify ExecStart=-@rootlibexecdir@/systemd --user Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%I/dbus/user_bus_socket Slice=user-%i.slice - -[Install] -Alias=user@%i.service -- cgit v1.2.1 From f7db7a691c3f532cf60886312459f2baea755283 Mon Sep 17 00:00:00 2001 From: Shawn Landden Date: Mon, 8 Jul 2013 18:28:14 +0000 Subject: basic SO_REUSEPORT support --- man/systemd.socket.xml | 11 +++++++++++ src/core/dbus-socket.c | 2 ++ src/core/socket.c | 11 +++++++++++ src/core/socket.h | 1 + src/shared/missing.h | 4 ++++ 5 files changed, 29 insertions(+) diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml index 0a2d86996b..2e1fb7cea1 100644 --- a/man/systemd.socket.xml +++ b/man/systemd.socket.xml @@ -504,6 +504,17 @@ for details. + + ReusePort= + Takes a boolean + value. If true allows multiple bind()s + to this TCP or UDP port. This + controls the SO_REUSEPORT socket + option. See + socket7 + for details. + + SmackLabel= SmackLabelIPIn= diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c index da317edb86..30c4b6302c 100644 --- a/src/core/dbus-socket.c +++ b/src/core/dbus-socket.c @@ -67,6 +67,7 @@ " \n" \ " \n" \ " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ @@ -194,6 +195,7 @@ static const BusProperty bus_socket_properties[] = { { "MessageQueueMaxMessages", bus_property_append_long, "x", offsetof(Socket, mq_maxmsg) }, { "MessageQueueMessageSize", bus_property_append_long, "x", offsetof(Socket, mq_msgsize) }, { "Result", bus_socket_append_socket_result, "s", offsetof(Socket, result) }, + { "ReusePort", bus_property_append_bool, "b", offsetof(Socket, reuseport) }, { "SmackLabel", bus_property_append_string, "s", offsetof(Socket, smack), true }, { "SmackLabelIPIn", bus_property_append_string, "s", offsetof(Socket, smack_ip_in), true }, { "SmackLabelIPOut",bus_property_append_string, "s", offsetof(Socket, smack_ip_out), true }, diff --git a/src/core/socket.c b/src/core/socket.c index 2def0c9ead..cf88bae9da 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -536,6 +536,11 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) { "%sMessageQueueMessageSize: %li\n", prefix, s->mq_msgsize); + if (s->reuseport) + fprintf(f, + "%sReusePort: %s\n", + prefix, yes_no(s->reuseport)); + if (s->smack) fprintf(f, "%sSmackLabel: %s\n", @@ -792,6 +797,12 @@ static void socket_apply_socket_options(Socket *s, int fd) { if (setsockopt(fd, SOL_TCP, TCP_CONGESTION, s->tcp_congestion, strlen(s->tcp_congestion)+1) < 0) log_warning_unit(UNIT(s)->id, "TCP_CONGESTION failed: %m"); + if (s->reuseport) { + int b = s->reuseport; + if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &b, sizeof(b))) + log_warning_unit(UNIT(s)->id, "SO_REUSEPORT failed: %m"); + } + #ifdef HAVE_SMACK if (s->smack_ip_in) if (fsetxattr(fd, "security.SMACK64IPIN", s->smack_ip_in, strlen(s->smack_ip_in), 0) < 0) diff --git a/src/core/socket.h b/src/core/socket.h index 15942c1c90..8f9dfdbfb0 100644 --- a/src/core/socket.h +++ b/src/core/socket.h @@ -144,6 +144,7 @@ struct Socket { size_t pipe_size; char *bind_to_device; char *tcp_congestion; + bool reuseport; long mq_maxmsg; long mq_msgsize; diff --git a/src/shared/missing.h b/src/shared/missing.h index 24a8392b22..534b3ccd4e 100644 --- a/src/shared/missing.h +++ b/src/shared/missing.h @@ -266,3 +266,7 @@ static inline int name_to_handle_at(int fd, const char *name, struct file_handle #ifndef TFD_TIMER_CANCEL_ON_SET #define TFD_TIMER_CANCEL_ON_SET (1 << 1) #endif + +#ifndef SO_REUSEPORT +#define SO_REUSEPORT 15 +#endif -- cgit v1.2.1 From 852752fca2f73323e3c25b33348b3c92458665ae Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Thu, 11 Jul 2013 13:42:14 +0200 Subject: kernel-install/90-loaderentry.install: do not fail for missing initrd --- src/kernel-install/90-loaderentry.install | 1 + 1 file changed, 1 insertion(+) diff --git a/src/kernel-install/90-loaderentry.install b/src/kernel-install/90-loaderentry.install index 6fbb14908a..6b91d1cccb 100644 --- a/src/kernel-install/90-loaderentry.install +++ b/src/kernel-install/90-loaderentry.install @@ -77,6 +77,7 @@ mkdir -p "${LOADER_ENTRY%/*}" || { echo "linux $BOOT_DIR/linux" [[ -f $BOOT_DIR_ABS/initrd ]] && \ echo "initrd $BOOT_DIR/initrd" + : } > "$LOADER_ENTRY" || { echo "Could not create loader entry '$LOADER_ENTRY'." >&2 exit 1 -- cgit v1.2.1 From e2ca86cf78f911a8be51f0224796e24883019139 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Thu, 11 Jul 2013 10:33:48 -0400 Subject: configure: split checks for libkmod >= 14 PKG_CHECK_EXISTS won't created a cached variable that later messes with our PKG_CHECK_MODULES check for an explicit version. Unfortunately, nesting these checks as the code existed lead to an odd error. Rather, split the checks apart. This also improves to the error message when the requisite version isn't found, and supplies the literal version systemd needs. --- configure.ac | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 7451ea4fd0..1e196f7307 100644 --- a/configure.ac +++ b/configure.ac @@ -218,12 +218,12 @@ PKG_CHECK_MODULES(DBUS, [dbus-1 >= 1.3.2]) have_kmod=no AC_ARG_ENABLE(kmod, AS_HELP_STRING([--disable-kmod], [disable loadable modules support])) if test "x$enable_kmod" != "xno"; then - PKG_CHECK_MODULES(KMOD, [ libkmod ], - [PKG_CHECK_MODULES(KMOD, [ libkmod >= 14 ], - [AC_DEFINE(HAVE_KMOD, 1, [Define if kmod is available]) have_kmod=yes], - AC_MSG_ERROR([*** kmod out-of-date, try --disable-kmod])) - ], - have_kmod=no) + PKG_CHECK_EXISTS([ libkmod ], have_kmod=yes, have_kmod=no) + if test "x$have_kmod" = "xyes"; then + PKG_CHECK_MODULES(KMOD, [ libkmod >= 14 ], + [AC_DEFINE(HAVE_KMOD, 1, [Define if kmod is available])], + AC_MSG_ERROR([*** kmod version >= 14 not found])) + fi if test "x$have_kmod" = xno -a "x$enable_kmod" = xyes; then AC_MSG_ERROR([*** kmod support requested, but libraries not found]) fi -- cgit v1.2.1 From a8833944647bfd10e43569646be954db5cbac54e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 11 Jul 2013 03:52:43 +0200 Subject: core: implicitly create a per-template slice for all instantiated units by default If no explicit slice is configured for an instantiated unit, create an implicit one for all instances of the same template. --- src/core/unit.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/core/unit.c b/src/core/unit.c index 5bc57e25c6..bfde08d68c 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -2030,6 +2030,8 @@ char *unit_default_cgroup_path(Unit *u) { } int unit_add_default_slice(Unit *u) { + _cleanup_free_ char *b = NULL; + const char *slice_name; Unit *slice; int r; @@ -2041,7 +2043,38 @@ int unit_add_default_slice(Unit *u) { if (!unit_get_cgroup_context(u)) return 0; - r = manager_load_unit(u->manager, u->manager->running_as == SYSTEMD_SYSTEM ? SPECIAL_SYSTEM_SLICE : SPECIAL_ROOT_SLICE, NULL, NULL, &slice); + if (u->instance) { + _cleanup_free_ char *prefix = NULL, *escaped = NULL; + ; + /* Implicitly place all instantiated units in their + * own per-template slice */ + + prefix = unit_name_to_prefix(u->id); + if (!prefix) + return -ENOMEM; + + /* The prefix is already escaped, but it might include + * "-" which has a special meaning for slice units, + * hence escape it here extra. */ + escaped = strreplace(prefix, "-", "\\x2d"); + if (!escaped) + return -ENOMEM; + + if (u->manager->running_as == SYSTEMD_SYSTEM) + b = strjoin("system-", escaped, ".slice", NULL); + else + b = strappend(escaped, ".slice"); + if (!b) + return -ENOMEM; + + slice_name = b; + } else + slice_name = + u->manager->running_as == SYSTEMD_SYSTEM + ? SPECIAL_SYSTEM_SLICE + : SPECIAL_ROOT_SLICE; + + r = manager_load_unit(u->manager, slice_name, NULL, NULL, &slice); if (r < 0) return r; -- cgit v1.2.1 From be2c1bd2a843aa61901086fccbae15b3aa085fb1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 11 Jul 2013 18:37:14 +0200 Subject: cgroup: don't move systemd into systems.slice when running as --user instance --- src/core/cgroup.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/core/cgroup.c b/src/core/cgroup.c index b5d1347856..b9ef00c617 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -638,8 +638,11 @@ int manager_setup_cgroup(Manager *m) { } /* 4. Realize the system slice and put us in there */ - a = strappenda(m->cgroup_root, "/" SPECIAL_SYSTEM_SLICE); - r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, a, 0); + if (m->running_as == SYSTEMD_SYSTEM) { + a = strappenda(m->cgroup_root, "/" SPECIAL_SYSTEM_SLICE); + r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, a, 0); + } else + r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_root, 0); if (r < 0) { log_error("Failed to create root cgroup hierarchy: %s", strerror(-r)); return r; -- cgit v1.2.1 From 8a84192905a9845fda31b65cc433127f9c2f95ae Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 11 Jul 2013 18:42:12 +0200 Subject: cgroup: don't ever try to destroy the cgroup of the root slice The root slice is after all the root cgroup, so don't attempt to delete it. --- src/core/cgroup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/cgroup.c b/src/core/cgroup.c index b9ef00c617..d0f36cb18e 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -531,7 +531,7 @@ void unit_destroy_cgroup(Unit *u) { if (!u->cgroup_path) return; - r = cg_trim_with_mask(u->cgroup_mask, u->cgroup_path, true); + r = cg_trim_with_mask(u->cgroup_mask, u->cgroup_path, !unit_has_name(u, SPECIAL_ROOT_SLICE)); if (r < 0) log_debug("Failed to destroy cgroup %s: %s", u->cgroup_path, strerror(-r)); -- cgit v1.2.1 From d7bd3de0654669e65b9642c248c5fa6d1d9a9f61 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 11 Jul 2013 18:47:20 +0200 Subject: cgroup: simplify how instantiated units are mapped to cgroups Previously for an instantiated unit foo@bar.service we created a cgroup foo@.service/foo@bar.service, in order to place all instances of the same template inside the same subtree. As we now implicitly add all instantiated units into one per-template slice we don't need this complexity anymore, and instance units can map directly to the cgroups of their full name. --- src/core/unit.c | 28 +++++++--------------------- src/shared/cgroup-util.c | 24 +++--------------------- src/test/test-cgroup-util.c | 23 ++++++++++++++--------- 3 files changed, 24 insertions(+), 51 deletions(-) diff --git a/src/core/unit.c b/src/core/unit.c index bfde08d68c..86452859bc 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -1991,7 +1991,7 @@ char *unit_dbus_path(Unit *u) { } char *unit_default_cgroup_path(Unit *u) { - _cleanup_free_ char *escaped_instance = NULL, *slice = NULL; + _cleanup_free_ char *escaped = NULL, *slice = NULL; int r; assert(u); @@ -2005,28 +2005,14 @@ char *unit_default_cgroup_path(Unit *u) { return NULL; } - escaped_instance = cg_escape(u->id); - if (!escaped_instance) + escaped = cg_escape(u->id); + if (!escaped) return NULL; - if (u->instance) { - _cleanup_free_ char *t = NULL, *escaped_template = NULL; - - t = unit_name_template(u->id); - if (!t) - return NULL; - - escaped_template = cg_escape(t); - if (!escaped_template) - return NULL; - - return strjoin(u->manager->cgroup_root, "/", - slice ? slice : "", slice ? "/" : "", - escaped_template, "/", escaped_instance, NULL); - } else - return strjoin(u->manager->cgroup_root, "/", - slice ? slice : "", slice ? "/" : "", - escaped_instance, NULL); + if (slice) + return strjoin(u->manager->cgroup_root, "/", slice, "/", escaped, NULL); + else + return strjoin(u->manager->cgroup_root, "/", escaped, NULL); } int unit_add_default_slice(Unit *u) { diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index 8f3c64fdc5..1d545e0466 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -1126,7 +1126,7 @@ int cg_pid_get_path_shifted(pid_t pid, char **root, char **cgroup) { } int cg_path_decode_unit(const char *cgroup, char **unit){ - char *p, *e, *c, *s, *k; + char *e, *c, *s; assert(cgroup); assert(unit); @@ -1135,28 +1135,10 @@ int cg_path_decode_unit(const char *cgroup, char **unit){ c = strndupa(cgroup, e - cgroup); c = cg_unescape(c); - /* Could this be a valid unit name? */ - if (!unit_name_is_valid(c, true)) + if (!unit_name_is_valid(c, false)) return -EINVAL; - if (!unit_name_is_template(c)) - s = strdup(c); - else { - if (*e != '/') - return -EINVAL; - - e += strspn(e, "/"); - - p = strchrnul(e, '/'); - k = strndupa(e, p - e); - k = cg_unescape(k); - - if (!unit_name_is_valid(k, false)) - return -EINVAL; - - s = strdup(k); - } - + s = strdup(c); if (!s) return -ENOMEM; diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c index ed2c6aeeae..295bb02e3b 100644 --- a/src/test/test-cgroup-util.c +++ b/src/test/test-cgroup-util.c @@ -32,12 +32,15 @@ static void check_p_d_u(const char *path, int code, const char *result) { } static void test_path_decode_unit(void) { - check_p_d_u("getty@.service/getty@tty2.service", 0, "getty@tty2.service"); - check_p_d_u("getty@.service/getty@tty2.service/xxx", 0, "getty@tty2.service"); + check_p_d_u("getty@tty2.service", 0, "getty@tty2.service"); + check_p_d_u("getty@tty2.service/", 0, "getty@tty2.service"); + check_p_d_u("getty@tty2.service/xxx", 0, "getty@tty2.service"); check_p_d_u("getty@.service/", -EINVAL, NULL); check_p_d_u("getty@.service", -EINVAL, NULL); check_p_d_u("getty.service", 0, "getty.service"); check_p_d_u("getty", -EINVAL, NULL); + check_p_d_u("getty/waldo", -EINVAL, NULL); + check_p_d_u("_cpu.service", 0, "cpu.service"); } static void check_p_g_u(const char *path, int code, const char *result) { @@ -49,13 +52,14 @@ static void check_p_g_u(const char *path, int code, const char *result) { static void test_path_get_unit(void) { check_p_g_u("/system.slice/foobar.service/sdfdsaf", 0, "foobar.service"); - check_p_g_u("/system.slice/getty@.service/getty@tty5.service", 0, "getty@tty5.service"); - check_p_g_u("/system.slice/getty@.service/getty@tty5.service/aaa/bbb", 0, "getty@tty5.service"); - check_p_g_u("/system.slice/getty@.service/getty@tty5.service/", 0, "getty@tty5.service"); + check_p_g_u("/system.slice/getty@tty5.service", 0, "getty@tty5.service"); + check_p_g_u("/system.slice/getty@tty5.service/aaa/bbb", 0, "getty@tty5.service"); + check_p_g_u("/system.slice/getty@tty5.service/", 0, "getty@tty5.service"); check_p_g_u("/system.slice/getty@tty6.service/tty5", 0, "getty@tty6.service"); check_p_g_u("sadfdsafsda", -EINVAL, NULL); - check_p_g_u("/system.slice/getty####@tty6.service/tty5", -EINVAL, NULL); + check_p_g_u("/system.slice/getty####@tty6.service/xxx", -EINVAL, NULL); check_p_g_u("/system.slice/system-waldo.slice/foobar.service/sdfdsaf", 0, "foobar.service"); + check_p_g_u("/system.slice/system-waldo.slice/_cpu.service/sdfdsaf", 0, "cpu.service"); } static void check_p_g_u_u(const char *path, int code, const char *result) { @@ -71,10 +75,11 @@ static void test_path_get_user_unit(void) { check_p_g_u_u("/user.slice/user-1002.slice/session-2.scope/foobar.service/waldo", 0, "foobar.service"); check_p_g_u_u("/user.slice/user-1000.slice/session-2.scope/foobar.service/waldo/uuuux", 0, "foobar.service"); check_p_g_u_u("/user.slice/user-1000.slice/session-2.scope/waldo/waldo/uuuux", -EINVAL, NULL); - check_p_g_u_u("/user.slice/user-1000.slice/session-2.scope/foobar@.service/foobar@pie.service/pa/po", 0, "foobar@pie.service"); - check_p_g_u_u("/session-2.scope/foobar@.service/foobar@pie.service/pa/po", 0, "foobar@pie.service"); - check_p_g_u_u("/xyz.slice/xyz-waldo.slice/session-77.scope/foobar@.service/foobar@pie.service/pa/po", 0, "foobar@pie.service"); + check_p_g_u_u("/user.slice/user-1000.slice/session-2.scope/foobar@pie.service/pa/po", 0, "foobar@pie.service"); + check_p_g_u_u("/session-2.scope/foobar@pie.service/pa/po", 0, "foobar@pie.service"); + check_p_g_u_u("/xyz.slice/xyz-waldo.slice/session-77.scope/foobar@pie.service/pa/po", 0, "foobar@pie.service"); check_p_g_u_u("/meh.service", -ENOENT, NULL); + check_p_g_u_u("/session-3.scope/_cpu.service", 0, "cpu.service"); } static void check_p_g_s(const char *path, int code, const char *result) { -- cgit v1.2.1 From 05b23cae8ebf6fbafd23ab8a0b0cfed747745d15 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 11 Jul 2013 18:49:44 +0200 Subject: update TODO --- TODO | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index 864516101b..34634fbbfb 100644 --- a/TODO +++ b/TODO @@ -36,6 +36,8 @@ Fedora 19: CGroup Rework Completion: +* systemctl user.slice doesn't show the full tree? + * introduce "mainpid" for scopes * implement system-wide DefaultCPUAccounting=1 switch (and similar for blockio, memory?) @@ -48,8 +50,6 @@ CGroup Rework Completion: * fix machine regstration to forward property array -* add implicit slice for instantiated services - * make BlockIODeviceWeight=, BlockIODeviceBandwidth= runtime settable * split up BlockIOWeight= and BlockIODeviceWeight= -- cgit v1.2.1 From 9d12709626bccc0cae677a7035f62efe6aabb4ab Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 11 Jul 2013 19:14:38 +0200 Subject: loginctl: suppress cgroup tree output if cgroup is empty same for machinectl --- src/login/loginctl.c | 17 ++++++++++++----- src/machine/machinectl.c | 13 ++++++++++--- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/login/loginctl.c b/src/login/loginctl.c index 93f4beed37..736db6a11b 100644 --- a/src/login/loginctl.c +++ b/src/login/loginctl.c @@ -35,8 +35,9 @@ #include "build.h" #include "strv.h" #include "unit-name.h" -#include "cgroup-show.h" #include "sysfs-show.h" +#include "cgroup-show.h" +#include "cgroup-util.h" #include "spawn-polkit-agent.h" static char **arg_property = NULL; @@ -262,7 +263,7 @@ static int list_seats(DBusConnection *bus, char **args, unsigned n) { return 0; } -static int show_unit_cgroup(DBusConnection *bus, const char *interface, const char *unit) { +static int show_unit_cgroup(DBusConnection *bus, const char *interface, const char *unit, pid_t leader) { const char *property = "ControlGroup"; _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; _cleanup_free_ char *path = NULL; @@ -313,6 +314,12 @@ static int show_unit_cgroup(DBusConnection *bus, const char *interface, const ch dbus_message_iter_get_basic(&sub, &cgroup); + if (isempty(cgroup)) + return 0; + + if (cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, cgroup, false) != 0 && leader <= 0) + return 0; + output_flags = arg_all * OUTPUT_SHOW_ALL | arg_full * OUTPUT_FULL_WIDTH; @@ -323,7 +330,7 @@ static int show_unit_cgroup(DBusConnection *bus, const char *interface, const ch else c = 0; - show_cgroup_by_path(cgroup, "\t\t ", c, false, output_flags); + show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, cgroup, "\t\t ", c, false, &leader, leader > 0, output_flags); return 0; } @@ -441,7 +448,7 @@ static void print_session_status_info(DBusConnection *bus, SessionStatusInfo *i) if (i->scope) { printf("\t Unit: %s\n", i->scope); - show_unit_cgroup(bus, "org.freedesktop.systemd1.Scope", i->scope); + show_unit_cgroup(bus, "org.freedesktop.systemd1.Scope", i->scope, i->leader); } } @@ -483,7 +490,7 @@ static void print_user_status_info(DBusConnection *bus, UserStatusInfo *i) { if (i->slice) { printf("\t Unit: %s\n", i->slice); - show_unit_cgroup(bus, "org.freedesktop.systemd1.Slice", i->slice); + show_unit_cgroup(bus, "org.freedesktop.systemd1.Slice", i->slice, 0); } } diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c index cd640e76ae..97c2193551 100644 --- a/src/machine/machinectl.c +++ b/src/machine/machinectl.c @@ -36,6 +36,7 @@ #include "strv.h" #include "unit-name.h" #include "cgroup-show.h" +#include "cgroup-util.h" #include "spawn-polkit-agent.h" static char **arg_property = NULL; @@ -125,7 +126,7 @@ static int list_machines(DBusConnection *bus, char **args, unsigned n) { return 0; } -static int show_scope_cgroup(DBusConnection *bus, const char *unit) { +static int show_scope_cgroup(DBusConnection *bus, const char *unit, pid_t leader) { const char *interface = "org.freedesktop.systemd1.Scope"; const char *property = "ControlGroup"; _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; @@ -177,6 +178,12 @@ static int show_scope_cgroup(DBusConnection *bus, const char *unit) { dbus_message_iter_get_basic(&sub, &cgroup); + if (isempty(cgroup)) + return 0; + + if (cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, cgroup, false) != 0 && leader <= 0) + return 0; + output_flags = arg_all * OUTPUT_SHOW_ALL | arg_full * OUTPUT_FULL_WIDTH; @@ -187,7 +194,7 @@ static int show_scope_cgroup(DBusConnection *bus, const char *unit) { else c = 0; - show_cgroup_by_path(cgroup, "\t\t ", c, false, output_flags); + show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, cgroup, "\t\t ", c, false, &leader, leader > 0, output_flags); return 0; } @@ -249,7 +256,7 @@ static void print_machine_status_info(DBusConnection *bus, MachineStatusInfo *i) if (i->scope) { printf("\t Unit: %s\n", i->scope); - show_scope_cgroup(bus, i->scope); + show_scope_cgroup(bus, i->scope, i->leader); } } -- cgit v1.2.1 From 042f9f5e5e76cf0e3cbfd009abd2add0366cdeca Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 11 Jul 2013 19:15:01 +0200 Subject: systemctl: show cgroup tree if cgroup is empty but has non-empty children This makes sure "systemctl status user.slice" shows a nice cgroup tree of all logged in users. --- src/systemctl/systemctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index d25b7d6fae..2ea5a3b0d8 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -2788,7 +2788,7 @@ static void print_status_info(UnitStatusInfo *i) { printf(" Status: \"%s\"\n", i->status_text); if (i->control_group && - (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) { + (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) { unsigned c; printf(" CGroup: %s\n", i->control_group); -- cgit v1.2.1 From c14901bdebb311531fb85b02c7c6eebf6e8e4388 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 11 Jul 2013 19:16:11 +0200 Subject: update TODO --- TODO | 2 -- 1 file changed, 2 deletions(-) diff --git a/TODO b/TODO index 34634fbbfb..a6eed6f401 100644 --- a/TODO +++ b/TODO @@ -36,8 +36,6 @@ Fedora 19: CGroup Rework Completion: -* systemctl user.slice doesn't show the full tree? - * introduce "mainpid" for scopes * implement system-wide DefaultCPUAccounting=1 switch (and similar for blockio, memory?) -- cgit v1.2.1 From 554604b3073467af75dc94fac9e2343148603289 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 11 Jul 2013 19:53:46 +0200 Subject: machined: forward scope properties array from client to systemd This makes nspawn's --scope= switch work again. --- src/machine/machine.c | 8 +-- src/machine/machine.h | 2 +- src/machine/machined-dbus.c | 128 ++++++++++++++++++++++++++++++++++++++++++-- src/machine/machined.c | 2 +- src/machine/machined.h | 2 +- 5 files changed, 132 insertions(+), 10 deletions(-) diff --git a/src/machine/machine.c b/src/machine/machine.c index 591a656f1e..602aa18be6 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -217,7 +217,7 @@ int machine_load(Machine *m) { return r; } -static int machine_start_scope(Machine *m) { +static int machine_start_scope(Machine *m, DBusMessageIter *iter) { _cleanup_free_ char *description = NULL; DBusError error; char *job; @@ -241,7 +241,7 @@ static int machine_start_scope(Machine *m) { description = strappend(m->class == MACHINE_VM ? "Virtual Machine " : "Container ", m->name); - r = manager_start_scope(m->manager, scope, m->leader, SPECIAL_MACHINE_SLICE, description, &error, &job); + r = manager_start_scope(m->manager, scope, m->leader, SPECIAL_MACHINE_SLICE, description, iter, &error, &job); if (r < 0) { log_error("Failed to start machine scope: %s", bus_error(&error, r)); dbus_error_free(&error); @@ -262,7 +262,7 @@ static int machine_start_scope(Machine *m) { return r; } -int machine_start(Machine *m) { +int machine_start(Machine *m, DBusMessageIter *iter) { int r; assert(m); @@ -271,7 +271,7 @@ int machine_start(Machine *m) { return 0; /* Create cgroup */ - r = machine_start_scope(m); + r = machine_start_scope(m, iter); if (r < 0) return r; diff --git a/src/machine/machine.h b/src/machine/machine.h index 7501fa372e..c5d52a968b 100644 --- a/src/machine/machine.h +++ b/src/machine/machine.h @@ -82,7 +82,7 @@ Machine* machine_new(Manager *manager, const char *name); void machine_free(Machine *m); int machine_check_gc(Machine *m, bool drop_not_started); void machine_add_to_gc_queue(Machine *m); -int machine_start(Machine *m); +int machine_start(Machine *m, DBusMessageIter *iter); int machine_stop(Machine *m); int machine_save(Machine *m); int machine_load(Machine *m); diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c index 4664c73a9c..1e8bc609a3 100644 --- a/src/machine/machined-dbus.c +++ b/src/machine/machined-dbus.c @@ -185,6 +185,13 @@ static int bus_manager_create_machine(Manager *manager, DBusMessage *message) { if (!(isempty(root_directory) || path_is_absolute(root_directory))) return -EINVAL; + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT) + return -EINVAL; + + dbus_message_iter_recurse(&iter, &sub); + if (hashmap_get(manager->machines, name)) return -EEXIST; @@ -218,7 +225,7 @@ static int bus_manager_create_machine(Manager *manager, DBusMessage *message) { } } - r = machine_start(m); + r = machine_start(m, &sub); if (r < 0) goto fail; @@ -614,12 +621,118 @@ finish: return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } +static int copy_many_fields(DBusMessageIter *dest, DBusMessageIter *src); + +static int copy_one_field(DBusMessageIter *dest, DBusMessageIter *src) { + int type, r; + + type = dbus_message_iter_get_arg_type(src); + + switch (type) { + + case DBUS_TYPE_STRUCT: { + DBusMessageIter dest_sub, src_sub; + + dbus_message_iter_recurse(src, &src_sub); + + if (!dbus_message_iter_open_container(dest, DBUS_TYPE_STRUCT, NULL, &dest_sub)) + return log_oom(); + + r = copy_many_fields(&dest_sub, &src_sub); + if (r < 0) + return r; + + if (!dbus_message_iter_close_container(dest, &dest_sub)) + return log_oom(); + + return 0; + } + + case DBUS_TYPE_ARRAY: { + DBusMessageIter dest_sub, src_sub; + + dbus_message_iter_recurse(src, &src_sub); + + if (!dbus_message_iter_open_container(dest, DBUS_TYPE_ARRAY, dbus_message_iter_get_signature(&src_sub), &dest_sub)) + return log_oom(); + + r = copy_many_fields(&dest_sub, &src_sub); + if (r < 0) + return r; + + if (!dbus_message_iter_close_container(dest, &dest_sub)) + return log_oom(); + + return 0; + } + + case DBUS_TYPE_VARIANT: { + DBusMessageIter dest_sub, src_sub; + + dbus_message_iter_recurse(src, &src_sub); + + if (!dbus_message_iter_open_container(dest, DBUS_TYPE_VARIANT, dbus_message_iter_get_signature(&src_sub), &dest_sub)) + return log_oom(); + + r = copy_one_field(&dest_sub, &src_sub); + if (r < 0) + return r; + + if (!dbus_message_iter_close_container(dest, &dest_sub)) + return log_oom(); + + return 0; + } + + case DBUS_TYPE_STRING: + case DBUS_TYPE_OBJECT_PATH: + case DBUS_TYPE_BYTE: + case DBUS_TYPE_BOOLEAN: + case DBUS_TYPE_UINT16: + case DBUS_TYPE_INT16: + case DBUS_TYPE_UINT32: + case DBUS_TYPE_INT32: + case DBUS_TYPE_UINT64: + case DBUS_TYPE_INT64: + case DBUS_TYPE_DOUBLE: + case DBUS_TYPE_SIGNATURE: { + const void *p; + + dbus_message_iter_get_basic(src, &p); + dbus_message_iter_append_basic(dest, type, &p); + return 0; + } + + default: + return -EINVAL; + } +} + +static int copy_many_fields(DBusMessageIter *dest, DBusMessageIter *src) { + int r; + + assert(dest); + assert(src); + + while (dbus_message_iter_get_arg_type(src) != DBUS_TYPE_INVALID) { + + r = copy_one_field(dest, src); + if (r < 0) + return r; + + dbus_message_iter_next(src); + } + + return 0; +} + int manager_start_scope( Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, + DBusMessageIter *more_properties, DBusError *error, char **job) { @@ -630,6 +743,7 @@ int manager_start_scope( uint64_t timeout = 500 * USEC_PER_MSEC; const char *fail = "fail"; uint32_t u; + int r; assert(manager); assert(scope); @@ -698,8 +812,16 @@ int manager_start_scope( !dbus_message_iter_append_basic(&sub4, DBUS_TYPE_UINT32, &u) || !dbus_message_iter_close_container(&sub3, &sub4) || !dbus_message_iter_close_container(&sub2, &sub3) || - !dbus_message_iter_close_container(&sub, &sub2) || - !dbus_message_iter_close_container(&iter, &sub)) + !dbus_message_iter_close_container(&sub, &sub2)) + return log_oom(); + + if (more_properties) { + r = copy_many_fields(&sub, more_properties); + if (r < 0) + return r; + } + + if (!dbus_message_iter_close_container(&iter, &sub)) return log_oom(); reply = dbus_connection_send_with_reply_and_block(manager->bus, m, -1, error); diff --git a/src/machine/machined.c b/src/machine/machined.c index c7c4ecc375..3ce51da90d 100644 --- a/src/machine/machined.c +++ b/src/machine/machined.c @@ -330,7 +330,7 @@ int manager_startup(Manager *m) { /* And start everything */ HASHMAP_FOREACH(machine, m->machines, i) - machine_start(machine); + machine_start(machine, NULL); return 0; } diff --git a/src/machine/machined.h b/src/machine/machined.h index 32a15fe1ab..780f51678c 100644 --- a/src/machine/machined.h +++ b/src/machine/machined.h @@ -67,7 +67,7 @@ extern const DBusObjectPathVTable bus_manager_vtable; DBusHandlerResult bus_message_filter(DBusConnection *c, DBusMessage *message, void *userdata); -int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, DBusError *error, char **job); +int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, DBusMessageIter *more_properties, DBusError *error, char **job); int manager_stop_unit(Manager *manager, const char *unit, DBusError *error, char **job); int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, DBusError *error); int manager_unit_is_active(Manager *manager, const char *unit); -- cgit v1.2.1 From 8e7076caae32a560a11c1643b53fc4f12db4a6b1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 11 Jul 2013 20:40:18 +0200 Subject: cgroup: split out per-device BlockIOWeight= setting into BlockIODeviceWeight= This way we can nicely map the configuration directive to properties and back, without requiring two different signatures for the same property. --- src/core/cgroup.c | 2 +- src/core/load-fragment-gperf.gperf.m4 | 1 + src/core/load-fragment.c | 87 +++++++++++++++++++++++------------ src/core/load-fragment.h | 1 + 4 files changed, 61 insertions(+), 30 deletions(-) diff --git a/src/core/cgroup.c b/src/core/cgroup.c index d0f36cb18e..5a1c3adacd 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -114,7 +114,7 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) { LIST_FOREACH(device_weights, w, c->blockio_device_weights) fprintf(f, - "%sBlockIOWeight=%s %lu", + "%sBlockIODeviceWeight=%s %lu", prefix, w->path, w->weight); diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index 76fc9c48ac..0c337bca9c 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -93,6 +93,7 @@ $1.DeviceAllow, config_parse_device_allow, 0, $1.DevicePolicy, config_parse_device_policy, 0, offsetof($1, cgroup_context.device_policy) $1.BlockIOAccounting, config_parse_bool, 0, offsetof($1, cgroup_context.blockio_accounting) $1.BlockIOWeight, config_parse_blockio_weight, 0, offsetof($1, cgroup_context) +$1.BlockIODeviceWeight, config_parse_blockio_device_weight, 0, offsetof($1, cgroup_context) $1.BlockIOReadBandwidth, config_parse_blockio_bandwidth, 0, offsetof($1, cgroup_context) $1.BlockIOWriteBandwidth, config_parse_blockio_bandwidth, 0, offsetof($1, cgroup_context)' )m4_dnl diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 2b10d72ab3..cf92f0df73 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -2094,7 +2094,44 @@ int config_parse_blockio_weight( void *data, void *userdata) { + CGroupContext *c = data; + unsigned long lu; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + + if (isempty(rvalue)) { + c->blockio_weight = 1000; + return 0; + } + + r = safe_atolu(rvalue, &lu); + if (r < 0 || lu < 10 || lu > 1000) { + log_syntax(unit, LOG_ERR, filename, line, EINVAL, + "Block IO weight '%s' invalid. Ignoring.", rvalue); + return 0; + } + + c->blockio_weight = lu; + + return 0; +} + +int config_parse_blockio_device_weight( + const char *unit, + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + _cleanup_free_ char *path = NULL; + CGroupBlockIODeviceWeight *w; CGroupContext *c = data; unsigned long lu; const char *weight; @@ -2106,8 +2143,6 @@ int config_parse_blockio_weight( assert(rvalue); if (isempty(rvalue)) { - c->blockio_weight = 1000; - while (c->blockio_device_weights) cgroup_context_free_blockio_device_weight(c, c->blockio_device_weights); @@ -2116,23 +2151,23 @@ int config_parse_blockio_weight( n = strcspn(rvalue, WHITESPACE); weight = rvalue + n; - if (*weight) { - /* Two params, first device name, then weight */ - path = strndup(rvalue, n); - if (!path) - return log_oom(); + if (!*weight) { + log_syntax(unit, LOG_ERR, filename, line, EINVAL, + "Expected block device and device weight. Ignoring."); + return 0; + } - if (!path_startswith(path, "/dev")) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Invalid device node path '%s'. Ignoring.", path); - return 0; - } + path = strndup(rvalue, n); + if (!path) + return log_oom(); - weight += strspn(weight, WHITESPACE); - } else - /* One param, only weight */ - weight = rvalue; + if (!path_startswith(path, "/dev")) { + log_syntax(unit, LOG_ERR, filename, line, EINVAL, + "Invalid device node path '%s'. Ignoring.", path); + return 0; + } + weight += strspn(weight, WHITESPACE); r = safe_atolu(weight, &lu); if (r < 0 || lu < 10 || lu > 1000) { log_syntax(unit, LOG_ERR, filename, line, EINVAL, @@ -2140,23 +2175,17 @@ int config_parse_blockio_weight( return 0; } - if (!path) - c->blockio_weight = lu; - else { - CGroupBlockIODeviceWeight *w; - - w = new0(CGroupBlockIODeviceWeight, 1); - if (!w) - return log_oom(); - w->path = path; - path = NULL; + w = new0(CGroupBlockIODeviceWeight, 1); + if (!w) + return log_oom(); - w->weight = lu; + w->path = path; + path = NULL; - LIST_PREPEND(CGroupBlockIODeviceWeight, device_weights, c->blockio_device_weights, w); - } + w->weight = lu; + LIST_PREPEND(CGroupBlockIODeviceWeight, device_weights, c->blockio_device_weights, w); return 0; } diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h index 5e36f3538a..90e5e3a5c9 100644 --- a/src/core/load-fragment.h +++ b/src/core/load-fragment.h @@ -81,6 +81,7 @@ int config_parse_memory_limit(const char *unit, const char *filename, unsigned l int config_parse_device_policy(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_device_allow(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_blockio_weight(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_blockio_device_weight(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_blockio_bandwidth(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); /* gperf prototypes */ -- cgit v1.2.1 From 665f8316f435772ed539be5e164a85cd188f84b4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 11 Jul 2013 21:03:06 +0200 Subject: core: when writing drop-in files, name them directly after the property we set Mapping from "FooBar" to "foo-bar" is unnecessary and makes it hard to handle many different properties with the same code, hence, let's just not do it. --- src/core/dbus-cgroup.c | 18 +++++++++--------- src/core/dbus-service.c | 2 +- src/core/dbus-unit.c | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c index d1d35633c1..27b54f95c6 100644 --- a/src/core/dbus-cgroup.c +++ b/src/core/dbus-cgroup.c @@ -162,7 +162,7 @@ int bus_cgroup_set_property( dbus_message_iter_get_basic(i, &b); c->cpu_accounting = b; - unit_write_drop_in_private_section(u, mode, "cpu-accounting", b ? "CPUAccounting=yes" : "CPUAccounting=no"); + unit_write_drop_in_private_section(u, mode, name, b ? "CPUAccounting=yes" : "CPUAccounting=no"); } return 1; @@ -185,7 +185,7 @@ int bus_cgroup_set_property( c->cpu_shares = ul; sprintf(buf, "CPUShares=%lu", ul); - unit_write_drop_in_private_section(u, mode, "cpu-shares", buf); + unit_write_drop_in_private_section(u, mode, name, buf); } return 1; @@ -200,7 +200,7 @@ int bus_cgroup_set_property( dbus_message_iter_get_basic(i, &b); c->blockio_accounting = b; - unit_write_drop_in_private_section(u, mode, "block-io-accounting", b ? "BlockIOAccounting=yes" : "BlockIOAccounting=no"); + unit_write_drop_in_private_section(u, mode, name, b ? "BlockIOAccounting=yes" : "BlockIOAccounting=no"); } return 1; @@ -223,7 +223,7 @@ int bus_cgroup_set_property( c->cpu_shares = ul; sprintf(buf, "BlockIOWeight=%lu", ul); - unit_write_drop_in_private_section(u, mode, "blockio-weight", buf); + unit_write_drop_in_private_section(u, mode, name, buf); } return 1; @@ -238,7 +238,7 @@ int bus_cgroup_set_property( dbus_message_iter_get_basic(i, &b); c->memory_accounting = b; - unit_write_drop_in_private_section(u, mode, "memory-accounting", b ? "MemoryAccounting=yes" : "MemoryAccounting=no"); + unit_write_drop_in_private_section(u, mode, name, b ? "MemoryAccounting=yes" : "MemoryAccounting=no"); } return 1; @@ -257,11 +257,11 @@ int bus_cgroup_set_property( if (streq(name, "MemoryLimit")) { c->memory_limit = limit; sprintf(buf, "MemoryLimit=%" PRIu64, limit); - unit_write_drop_in_private_section(u, mode, "memory-limit", buf); + unit_write_drop_in_private_section(u, mode, name, buf); } else { c->memory_soft_limit = limit; sprintf(buf, "MemorySoftLimit=%" PRIu64, limit); - unit_write_drop_in_private_section(u, mode, "memory-soft-limit", buf); + unit_write_drop_in_private_section(u, mode, name, buf); } } @@ -285,7 +285,7 @@ int bus_cgroup_set_property( c->device_policy = p; buf = strappenda("DevicePolicy=", policy); - unit_write_drop_in_private_section(u, mode, "device-policy", buf); + unit_write_drop_in_private_section(u, mode, name, buf); } return 1; @@ -365,7 +365,7 @@ int bus_cgroup_set_property( fprintf(f, "DeviceAllow=%s %s%s%s\n", a->path, a->r ? "r" : "", a->w ? "w" : "", a->m ? "m" : ""); fflush(f); - unit_write_drop_in_private_section(u, mode, "device-allow", buf); + unit_write_drop_in_private_section(u, mode, name, buf); } return 1; diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c index c2e02209be..d63ca01c4f 100644 --- a/src/core/dbus-service.c +++ b/src/core/dbus-service.c @@ -276,7 +276,7 @@ static int bus_service_set_transient_property( } fflush(f); - unit_write_drop_in_private_section(UNIT(s), mode, "exec-start", buf); + unit_write_drop_in_private_section(UNIT(s), mode, name, buf); } return 1; diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index 57fac00d19..5814971b8c 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -807,7 +807,7 @@ static int bus_unit_set_transient_property( if (!contents) return -ENOMEM; - unit_write_drop_in(u, mode, "Description", contents); + unit_write_drop_in(u, mode, name, contents); } return 1; @@ -841,7 +841,7 @@ static int bus_unit_set_transient_property( if (!contents) return -ENOMEM; - unit_write_drop_in(u, mode, "Slice", contents); + unit_write_drop_in(u, mode, name, contents); } return 1; -- cgit v1.2.1 From b9ec9359369f224bfb13db616f97401a6a177bd8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 11 Jul 2013 21:29:33 +0200 Subject: core: simplify drop-in writing logic a bit let's make use of some format string magic! --- src/core/dbus-cgroup.c | 32 ++++++++++----------------- src/core/dbus-service.c | 2 +- src/core/dbus-unit.c | 36 +++++++++++------------------- src/core/unit.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++--- src/core/unit.h | 6 ++++- 5 files changed, 85 insertions(+), 49 deletions(-) diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c index 27b54f95c6..8ad3d118c5 100644 --- a/src/core/dbus-cgroup.c +++ b/src/core/dbus-cgroup.c @@ -162,7 +162,7 @@ int bus_cgroup_set_property( dbus_message_iter_get_basic(i, &b); c->cpu_accounting = b; - unit_write_drop_in_private_section(u, mode, name, b ? "CPUAccounting=yes" : "CPUAccounting=no"); + unit_write_drop_in_private(u, mode, name, b ? "CPUAccounting=yes" : "CPUAccounting=no"); } return 1; @@ -181,11 +181,8 @@ int bus_cgroup_set_property( return -EINVAL; if (mode != UNIT_CHECK) { - char buf[sizeof("CPUShares=") + DECIMAL_STR_MAX(ul)]; c->cpu_shares = ul; - - sprintf(buf, "CPUShares=%lu", ul); - unit_write_drop_in_private_section(u, mode, name, buf); + unit_write_drop_in_private_format(u, mode, name, "CPUShares=%lu", ul); } return 1; @@ -200,7 +197,7 @@ int bus_cgroup_set_property( dbus_message_iter_get_basic(i, &b); c->blockio_accounting = b; - unit_write_drop_in_private_section(u, mode, name, b ? "BlockIOAccounting=yes" : "BlockIOAccounting=no"); + unit_write_drop_in_private(u, mode, name, b ? "BlockIOAccounting=yes" : "BlockIOAccounting=no"); } return 1; @@ -219,11 +216,8 @@ int bus_cgroup_set_property( return -EINVAL; if (mode != UNIT_CHECK) { - char buf[sizeof("BlockIOWeight=") + DECIMAL_STR_MAX(ul)]; c->cpu_shares = ul; - - sprintf(buf, "BlockIOWeight=%lu", ul); - unit_write_drop_in_private_section(u, mode, name, buf); + unit_write_drop_in_private_format(u, mode, name, "BlockIOWeight=%lu", ul); } return 1; @@ -238,7 +232,7 @@ int bus_cgroup_set_property( dbus_message_iter_get_basic(i, &b); c->memory_accounting = b; - unit_write_drop_in_private_section(u, mode, name, b ? "MemoryAccounting=yes" : "MemoryAccounting=no"); + unit_write_drop_in_private(u, mode, name, b ? "MemoryAccounting=yes" : "MemoryAccounting=no"); } return 1; @@ -250,19 +244,15 @@ int bus_cgroup_set_property( if (mode != UNIT_CHECK) { uint64_t limit; - char buf[sizeof("MemorySoftLimit=") + DECIMAL_STR_MAX(limit)]; dbus_message_iter_get_basic(i, &limit); - if (streq(name, "MemoryLimit")) { + if (streq(name, "MemoryLimit")) c->memory_limit = limit; - sprintf(buf, "MemoryLimit=%" PRIu64, limit); - unit_write_drop_in_private_section(u, mode, name, buf); - } else { + else c->memory_soft_limit = limit; - sprintf(buf, "MemorySoftLimit=%" PRIu64, limit); - unit_write_drop_in_private_section(u, mode, name, buf); - } + + unit_write_drop_in_private_format(u, mode, name, "%s=%" PRIu64, name, limit); } return 1; @@ -285,7 +275,7 @@ int bus_cgroup_set_property( c->device_policy = p; buf = strappenda("DevicePolicy=", policy); - unit_write_drop_in_private_section(u, mode, name, buf); + unit_write_drop_in_private(u, mode, name, buf); } return 1; @@ -365,7 +355,7 @@ int bus_cgroup_set_property( fprintf(f, "DeviceAllow=%s %s%s%s\n", a->path, a->r ? "r" : "", a->w ? "w" : "", a->m ? "m" : ""); fflush(f); - unit_write_drop_in_private_section(u, mode, name, buf); + unit_write_drop_in_private(u, mode, name, buf); } return 1; diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c index d63ca01c4f..8b157b5f3c 100644 --- a/src/core/dbus-service.c +++ b/src/core/dbus-service.c @@ -276,7 +276,7 @@ static int bus_service_set_transient_property( } fflush(f); - unit_write_drop_in_private_section(UNIT(s), mode, name, buf); + unit_write_drop_in_private(UNIT(s), mode, name, buf); } return 1; diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index 5814971b8c..ba4d42652e 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -794,7 +794,6 @@ static int bus_unit_set_transient_property( return -EINVAL; if (mode != UNIT_CHECK) { - _cleanup_free_ char *contents = NULL; const char *description; dbus_message_iter_get_basic(i, &description); @@ -803,18 +802,13 @@ static int bus_unit_set_transient_property( if (r < 0) return r; - contents = strjoin("[Unit]\nDescription=", description, "\n", NULL); - if (!contents) - return -ENOMEM; - - unit_write_drop_in(u, mode, name, contents); + unit_write_drop_in_format(u, mode, name, "[Unit]\nDescription=%s\n", description); } return 1; } else if (streq(name, "Slice") && unit_get_cgroup_context(u)) { const char *s; - Unit *slice; if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_STRING) return -EINVAL; @@ -822,10 +816,12 @@ static int bus_unit_set_transient_property( dbus_message_iter_get_basic(i, &s); if (isempty(s)) { - if (mode != UNIT_CHECK) + if (mode != UNIT_CHECK) { unit_ref_unset(&u->slice); + unit_remove_drop_in(u, mode, name); + } } else { - _cleanup_free_ char *contents = NULL; + Unit *slice; r = manager_load_unit(u->manager, s, NULL, error, &slice); if (r < 0) @@ -834,15 +830,12 @@ static int bus_unit_set_transient_property( if (slice->type != UNIT_SLICE) return -EINVAL; - if (mode != UNIT_CHECK) + if (mode != UNIT_CHECK) { unit_ref_set(&u->slice, slice); - - contents = strjoin("[", UNIT_VTABLE(u)->private_section, "]\nSlice=", s, NULL); - if (!contents) - return -ENOMEM; - - unit_write_drop_in(u, mode, name, contents); + unit_write_drop_in_private_format(u, mode, name, "Slice=%s\n", s); + } } + return 1; } else if (streq(name, "Requires") || @@ -880,7 +873,7 @@ static int bus_unit_set_transient_property( return -EINVAL; if (mode != UNIT_CHECK) { - _cleanup_free_ char *label = NULL, *contents = NULL; + _cleanup_free_ char *label = NULL; r = unit_add_dependency_by_name(u, d, other, NULL, true); if (r < 0) @@ -890,11 +883,7 @@ static int bus_unit_set_transient_property( if (!label) return -ENOMEM; - contents = strjoin("[Unit]\n", name, "=", other, "\n", NULL); - if (!contents) - return -ENOMEM; - - unit_write_drop_in(u, mode, label, contents); + unit_write_drop_in_format(u, mode, label, "[Unit]\n%s=%s\n", name, other); } dbus_message_iter_next(&sub); @@ -1048,10 +1037,11 @@ const BusProperty bus_unit_properties[] = { { "ConditionResult", bus_property_append_bool, "b", offsetof(Unit, condition_result) }, { "LoadError", bus_unit_append_load_error, "(ss)", 0 }, { "Transient", bus_property_append_bool, "b", offsetof(Unit, transient) }, - { NULL, } + {} }; const BusProperty bus_unit_cgroup_properties[] = { { "Slice", bus_unit_append_slice, "s", 0 }, { "ControlGroup", bus_property_append_string, "s", offsetof(Unit, cgroup_path), true }, + {} }; diff --git a/src/core/unit.c b/src/core/unit.c index 86452859bc..dd08011ff4 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -2733,6 +2733,7 @@ CGroupContext *unit_get_cgroup_context(Unit *u) { } static int drop_in_file(Unit *u, UnitSetPropertiesMode mode, const char *name, char **_p, char **_q) { + _cleanup_free_ char *b = NULL; char *p, *q; int r; @@ -2742,7 +2743,11 @@ static int drop_in_file(Unit *u, UnitSetPropertiesMode mode, const char *name, c assert(_q); assert(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)); - if (!filename_is_safe(name)) + b = xescape(name, "/."); + if (!b) + return -ENOMEM; + + if (!filename_is_safe(b)) return -EINVAL; if (u->manager->running_as == SYSTEMD_USER) { @@ -2762,7 +2767,7 @@ static int drop_in_file(Unit *u, UnitSetPropertiesMode mode, const char *name, c if (!p) return -ENOMEM; - q = strjoin(p, "/90-", name, ".conf", NULL); + q = strjoin(p, "/90-", b, ".conf", NULL); if (!q) { free(p); return -ENOMEM; @@ -2792,7 +2797,29 @@ int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, co return write_string_file_atomic_label(q, data); } -int unit_write_drop_in_private_section(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) { +int unit_write_drop_in_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) { + _cleanup_free_ char *p = NULL; + va_list ap; + int r; + + assert(u); + assert(name); + assert(format); + + if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME))) + return 0; + + va_start(ap, format); + r = vasprintf(&p, format, ap); + va_end(ap); + + if (r < 0) + return -ENOMEM; + + return unit_write_drop_in(u, mode, name, p); +} + +int unit_write_drop_in_private(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) { _cleanup_free_ char *ndata = NULL; assert(u); @@ -2802,6 +2829,9 @@ int unit_write_drop_in_private_section(Unit *u, UnitSetPropertiesMode mode, cons if (!UNIT_VTABLE(u)->private_section) return -EINVAL; + if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME))) + return 0; + ndata = strjoin("[", UNIT_VTABLE(u)->private_section, "]\n", data, NULL); if (!ndata) return -ENOMEM; @@ -2809,6 +2839,28 @@ int unit_write_drop_in_private_section(Unit *u, UnitSetPropertiesMode mode, cons return unit_write_drop_in(u, mode, name, ndata); } +int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) { + _cleanup_free_ char *p = NULL; + va_list ap; + int r; + + assert(u); + assert(name); + assert(format); + + if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME))) + return 0; + + va_start(ap, format); + r = vasprintf(&p, format, ap); + va_end(ap); + + if (r < 0) + return -ENOMEM; + + return unit_write_drop_in_private(u, mode, name, p); +} + int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name) { _cleanup_free_ char *p = NULL, *q = NULL; int r; diff --git a/src/core/unit.h b/src/core/unit.h index ed4df18246..0caea183c4 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -598,7 +598,11 @@ ExecContext *unit_get_exec_context(Unit *u) _pure_; CGroupContext *unit_get_cgroup_context(Unit *u) _pure_; int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data); -int unit_write_drop_in_private_section(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data); +int unit_write_drop_in_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) _printf_attr_(4,5); + +int unit_write_drop_in_private(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data); +int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) _printf_attr_(4,5); + int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name); int unit_kill_context(Unit *u, KillContext *c, bool sigkill, pid_t main_pid, pid_t control_pid, bool main_pid_alien); -- cgit v1.2.1 From 1e1ddecf405fdeb5a073c0696fafb50946af60d2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 11 Jul 2013 21:30:19 +0200 Subject: update TODO --- TODO | 4 ---- 1 file changed, 4 deletions(-) diff --git a/TODO b/TODO index a6eed6f401..b8d0151d57 100644 --- a/TODO +++ b/TODO @@ -46,12 +46,8 @@ CGroup Rework Completion: * logind: implement session kill exceptions -* fix machine regstration to forward property array - * make BlockIODeviceWeight=, BlockIODeviceBandwidth= runtime settable -* split up BlockIOWeight= and BlockIODeviceWeight= - * introduce high-level settings for RT budget, swappiness * man: document new bus apis -- cgit v1.2.1 From f440e1bb8a0b1262c7649da502d0e9358019b968 Mon Sep 17 00:00:00 2001 From: Lukas Nykryn Date: Tue, 9 Jul 2013 15:45:36 +0200 Subject: unit: check correct variable after strdup --- src/core/unit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/unit.c b/src/core/unit.c index dd08011ff4..b245356887 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -2326,7 +2326,7 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) { char *s; s = strdup(v); - if (!v) + if (!s) return -ENOMEM; free(u->cgroup_path); -- cgit v1.2.1 From 66a69314941b5020f57cda943095413c40d677d8 Mon Sep 17 00:00:00 2001 From: Lukas Nykryn Date: Tue, 9 Jul 2013 15:45:38 +0200 Subject: systemctl: remove unused variable --- src/systemctl/systemctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 2ea5a3b0d8..9574ff20bd 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -1186,7 +1186,7 @@ static int list_dependencies(DBusConnection *bus, char **args) { static int get_default(DBusConnection *bus, char **args) { char *path = NULL; - _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL; + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; int r; _cleanup_dbus_error_free_ DBusError error; -- cgit v1.2.1 From cd3069559a09b4e4f85a6f02aa8f0521f48359ca Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 12 Jul 2013 01:15:52 +0200 Subject: build-sys: don't enable color gcc on dumb terminals Guys, we know that emacs is the best editor on earth, but unfortunately its "M-x compile" terminal cannot do colors (well, it does its own highlighting of the output anyway), and it will inform the programs it calls about this with TERM=dumb, and gcc should check for that. But you guys turned that off. Not cool. Let's turn it on again. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 1e196f7307..802009efcd 100644 --- a/configure.ac +++ b/configure.ac @@ -133,7 +133,7 @@ CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [\ -ffast-math \ -fno-common \ -fdiagnostics-show-option \ - -fdiagnostics-color \ + -fdiagnostics-color=auto \ -fno-strict-aliasing \ -fvisibility=hidden \ -ffunction-sections \ -- cgit v1.2.1 From 47a1454f707dff2e5d1db2f8bfcc406805d4d450 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 12 Jul 2013 01:18:09 +0200 Subject: update TODO --- TODO | 3 +++ 1 file changed, 3 insertions(+) diff --git a/TODO b/TODO index b8d0151d57..5d4ba8f65e 100644 --- a/TODO +++ b/TODO @@ -54,6 +54,9 @@ CGroup Rework Completion: Features: +* Get rid of systemd-sysv: + https://fedoraproject.org/wiki/User:Toshio/Systemd_Convert_draft + * do we really need both hasprefix() and startswith()? * when a kernel driver logs in a tight loop we should ratelimit that too. -- cgit v1.2.1 From 433dd100442e8197868def975c6fd38b48dc6439 Mon Sep 17 00:00:00 2001 From: Lukas Nykryn Date: Tue, 9 Jul 2013 15:45:37 +0200 Subject: journald-server: r should be checked after journal_file_open_reliably --- src/journal/journald-server.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 44ba916f10..6beaa8a729 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -910,11 +910,12 @@ static int system_journal_open(Server *s) { if (r >= 0) server_fix_perms(s, s->system_journal, 0); - } else if (r < 0) { - if (r != -ENOENT && r != -EROFS) - log_warning("Failed to open system journal: %s", strerror(-r)); + else if (r < 0) { + if (r != -ENOENT && r != -EROFS) + log_warning("Failed to open system journal: %s", strerror(-r)); - r = 0; + r = 0; + } } if (!s->runtime_journal && -- cgit v1.2.1 From b54022fb92580022c5e830fbe4280992f5b3a770 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 10 Jul 2013 21:43:34 -0400 Subject: man: remove note about shutdown being legacy This can only confuse people, because there's no need to discourage people from using shutdown. It is fully functional and supported. --- man/shutdown.xml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/man/shutdown.xml b/man/shutdown.xml index 570383319b..af799c6649 100644 --- a/man/shutdown.xml +++ b/man/shutdown.xml @@ -168,13 +168,6 @@ code otherwise. - - Notes - - This is a legacy command available for - compatibility only. - - See Also -- cgit v1.2.1 From 479fe882ae92e4c2eac3c995cd0d23d4c604889f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 11 Jul 2013 23:39:27 -0400 Subject: man: use not for suffixes Especially sentences like "filename ends in .suffix" are easier to parse if the suffix is surrounded by quotes. In sentences like "requires a .service unit", where the suffix is used as a class designation, there is no need to use quotes. --- man/systemd.automount.xml | 2 +- man/systemd.device.xml | 2 +- man/systemd.mount.xml | 2 +- man/systemd.path.xml | 4 ++-- man/systemd.snapshot.xml | 2 +- man/systemd.socket.xml | 2 +- man/systemd.swap.xml | 2 +- man/systemd.target.xml | 2 +- man/systemd.timer.xml | 4 ++-- man/systemd.unit.xml | 2 +- 10 files changed, 12 insertions(+), 12 deletions(-) diff --git a/man/systemd.automount.xml b/man/systemd.automount.xml index 2a310d3ecf..adba75a71a 100644 --- a/man/systemd.automount.xml +++ b/man/systemd.automount.xml @@ -55,7 +55,7 @@ Description A unit configuration file whose name ends in - .automount encodes information + .automount encodes information about a file system automount point controlled and supervised by systemd. diff --git a/man/systemd.device.xml b/man/systemd.device.xml index 1c29aa4e79..e3cf071bcb 100644 --- a/man/systemd.device.xml +++ b/man/systemd.device.xml @@ -55,7 +55,7 @@ Description A unit configuration file whose name ends in - .device encodes information about + .device encodes information about a device unit as exposed in the sysfs/udev7 device tree. diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml index 07f21025b8..c57f613290 100644 --- a/man/systemd.mount.xml +++ b/man/systemd.mount.xml @@ -55,7 +55,7 @@ Description A unit configuration file whose name ends in - .mount encodes information about + .mount encodes information about a file system mount point controlled and supervised by systemd. diff --git a/man/systemd.path.xml b/man/systemd.path.xml index 1975142d2c..8c782b8531 100644 --- a/man/systemd.path.xml +++ b/man/systemd.path.xml @@ -55,7 +55,7 @@ Description A unit configuration file whose name ends in - .path encodes information about + .path encodes information about a path monitored by systemd, for path-based activation. @@ -185,7 +185,7 @@ when any of the configured paths changes. The argument is a unit name, whose suffix is not - .path. If not + .path. If not specified, this value defaults to a service that has the same name as the path unit, except for the suffix. (See diff --git a/man/systemd.snapshot.xml b/man/systemd.snapshot.xml index 08d14c4e01..4e8d5a901f 100644 --- a/man/systemd.snapshot.xml +++ b/man/systemd.snapshot.xml @@ -57,7 +57,7 @@ Snapshot units are not configured via unit configuration files. Nonetheless they are named similar to filenames. A unit name whose name ends in - .snapshot refers to a dynamic + .snapshot refers to a dynamic snapshot of the systemd runtime state. Snapshots are not configured on disk but created diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml index 2e1fb7cea1..1b899c46a1 100644 --- a/man/systemd.socket.xml +++ b/man/systemd.socket.xml @@ -55,7 +55,7 @@ Description A unit configuration file whose name ends in - .socket encodes information about + .socket encodes information about an IPC or network socket or a file system FIFO controlled and supervised by systemd, for socket-based activation. diff --git a/man/systemd.swap.xml b/man/systemd.swap.xml index 9a3905a927..d931c46e80 100644 --- a/man/systemd.swap.xml +++ b/man/systemd.swap.xml @@ -55,7 +55,7 @@ Description A unit configuration file whose name ends in - .swap encodes information about a + .swap encodes information about a swap device or file for memory paging controlled and supervised by systemd. diff --git a/man/systemd.target.xml b/man/systemd.target.xml index fd51cfde3a..15662a548d 100644 --- a/man/systemd.target.xml +++ b/man/systemd.target.xml @@ -55,7 +55,7 @@ Description A unit configuration file whose name ends in - .target encodes information about + .target encodes information about a target unit of systemd, which is used for grouping units and as well-known synchronization points during start-up. diff --git a/man/systemd.timer.xml b/man/systemd.timer.xml index 1f0aac2eed..fa67d59a22 100644 --- a/man/systemd.timer.xml +++ b/man/systemd.timer.xml @@ -55,7 +55,7 @@ Description A unit configuration file whose name ends in - .timer encodes information about + .timer encodes information about a timer controlled and supervised by systemd, for timer-based activation. @@ -187,7 +187,7 @@ The unit to activate when this timer elapses. The argument is a unit name, whose suffix is not - .timer. If not + .timer. If not specified, this value defaults to a service that has the same name as the timer unit, except for the diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index 4f0bd64b12..a870f6b17a 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -173,7 +173,7 @@ Along with a unit file foo.service a directory foo.service.d/ may exist. All - files with the suffix .conf from + files with the suffix .conf from this directory will be parsed after the file itself is parsed. This is useful to alter or add configuration settings to a unit, without having to modify their -- cgit v1.2.1 From d868475ad62547f0a034dfaf038aff31b3d05372 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 10 Jul 2013 01:25:02 -0400 Subject: man: document the slice and scope units, add systemd.cgroup(5) --- Makefile-man.am | 3 + man/systemd.cgroup.xml | 308 ++++++++++++++++++++++++++++++++++++++++++++++++ man/systemd.exec.xml | 122 +------------------ man/systemd.mount.xml | 17 ++- man/systemd.scope.xml | 100 ++++++++++++++++ man/systemd.service.xml | 8 +- man/systemd.slice.xml | 99 ++++++++++++++++ man/systemd.socket.xml | 8 +- man/systemd.swap.xml | 8 +- 9 files changed, 541 insertions(+), 132 deletions(-) create mode 100644 man/systemd.cgroup.xml create mode 100644 man/systemd.scope.xml create mode 100644 man/systemd.slice.xml diff --git a/Makefile-man.am b/Makefile-man.am index bef749af86..e74cceaada 100644 --- a/Makefile-man.am +++ b/Makefile-man.am @@ -76,6 +76,7 @@ MANPAGES += \ man/systemd-update-utmp.service.8 \ man/systemd.1 \ man/systemd.automount.5 \ + man/systemd.cgroup.5 \ man/systemd.device.5 \ man/systemd.exec.5 \ man/systemd.journal-fields.7 \ @@ -83,7 +84,9 @@ MANPAGES += \ man/systemd.mount.5 \ man/systemd.path.5 \ man/systemd.preset.5 \ + man/systemd.scope.5 \ man/systemd.service.5 \ + man/systemd.slice.5 \ man/systemd.snapshot.5 \ man/systemd.socket.5 \ man/systemd.special.7 \ diff --git a/man/systemd.cgroup.xml b/man/systemd.cgroup.xml new file mode 100644 index 0000000000..504c9685a5 --- /dev/null +++ b/man/systemd.cgroup.xml @@ -0,0 +1,308 @@ + + + + + + + + + systemd.cgroup + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.cgroup + 5 + + + + systemd.cgroup + Cgroup configuration unit settings + + + + + slice.slice, + scope.scope, + service.service, + socket.socket, + mount.mount, + swap.swap + + + + + Description + + Unit configuration files for services, slices, scopes, + sockets, mount points, and swap devices share a subset of + configuration options which configure the control group settings + for spawned processes. + + This man page lists the configuration options shared by + those six unit types. See + systemd.unit5 + for the common options of all unit configuration files, and + systemd.slice5, + systemd.scope5, + systemd.service5, + systemd.socket5, + systemd.mount5, + and + systemd.swap5 + for more information on the specific unit configuration files. The + execution specific configuration options are configured in the + [Slice], [Scope], [Service], [Socket], [Mount], or [Swap] + sections, depending on the unit type. + + + + Options + + Units of the types listed above can have settings + for cgroup configuration: + + + + CPUAccounting= + + + Turn on the CPU usage accounting for this + unit. + + + + + BlockIOAccounting= + + + Turn on the Block IO bandwidth accounting + for this unit. + + + + + MemoryAccounting= + + + Turn on the process and kernel memory + accounting for this unit. + + + + + + CPUShares=weight + + + Assign the specified overall CPU time share weight to + the processes executed. Takes an integer value. This + controls the cpu.shares control group + attribute, which defaults to 1024. For details about this + control group attribute see sched-design-CFS.txt. + + Implies CPUAccounting=true. + + + + + MemoryLimit=bytes + MemorySoftLimit=bytes + + + Specify the hard and soft limits on maximum memory + usage of the executed processes. The "hard" limit specifies + how much process and kernel memory can be used by tasks in + this unit, when there is no memory contention. If the kernel + detects memory contention, memory reclaim will be performed + until the memory usage is within the "soft" limit. Takes a + memory size in bytes. If the value is suffixed with K, M, G + or T the specified memory size is parsed as Kilobytes, + Megabytes, Gigabytes, or Terabytes (with the base 1024), + respectively. This controls the + memory.limit_in_bytes and + memory.soft_limit_in_bytes control group + attributes. For details about these control group attributes + see memory.txt. + + Implies MemoryAccounting=true. + + + + + BlockIOWeight=weight + + Set the default + overall block IO weight for the + executed processes. Takes a single + weight value (between 10 and 1000) to + set the default block IO weight. This + controls the + blkio.weight + control group attribute, which + defaults to 1000. For details about + this control group attribute see + blkio-controller.txt. + + + + BlockIODeviceWeight=device weight + + + Set the per-device overall block IO weight for the + executed processes. Takes a space-separated pair of a file + path and a weight value to specify the device specific + weight value, between 10 and 1000. (Example: "/dev/sda + 500"). The file path may be specified as path to a block + device node or as any other file in which case the backing + block device of the file system of the file is + determined. This controls the + blkio.weight_device control group + attribute, which defaults to 1000. Use this option multiple + times to set weights for multiple devices. For details about + this control group attribute see blkio-controller.txt. + + + + + BlockIOReadBandwidth=device bytes + BlockIOWriteBandwidth=device bytes + + + Set the per-device overall block IO bandwidth limit + for the executed processes. Takes a space-separated pair of + a file path and a bandwidth value (in bytes per second) to + specify the device specific bandwidth. The file path may be + a path to a block device node, or as any other file in which + case the backing block device of the file system of the file + is used. If the bandwidth is suffixed with K, M, G, or T + the specified bandwidth is parsed as Kilobytes, Megabytes, + Gigabytes, or Terabytes, respectively (Example: + "/dev/disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0 5M"). This + controls the blkio.read_bps_device and + blkio.write_bps_device control group + attributes. Use this option multiple times to set bandwidth + limits for multiple devices. For details about these control + group attributes see + blkio-controller.txt. + + + + + + DeviceAllow= + + + Control access to specific device nodes by the + executed processes. Takes two space-separated strings: a + device node path (such as /dev/null) + followed by a combination of r, + w, m to control + reading, writing, + or creating of the specific device node by the unit + (mknod), respectively. This controls + the devices.allow and + devices.deny control group + attributes. For details about these control group attributes + see devices.txt. + + + + + DevicePolicy=auto|closed|strict + + + + Control the policy for allowing device access: + + + + + + means to only allow types of access that are + explicitly specified. + + + + + + + in addition allows access to standard pseudo + devices including + /dev/null, + /dev/zero, + /dev/full, + /dev/random, and + /dev/urandom. + + + + + + + + + in addition allows access to all devices if no + explicit DeviceAllow= is present. + This is the default. + + + + + + + + + + + See Also + + systemd1, + systemd.unit5, + systemd.service5, + systemd.slice5, + systemd.scope5, + systemd.socket5, + systemd.mount5, + systemd.swap5, + systemd.directives7, + The documentation for control groups and specific controllers in the Linux kernel: + cgroups.txt, + cpuacct.txt, + memory.txt, + blkio-controller.txt. + + + diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 4294e54a55..d299fc0382 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -58,7 +58,7 @@ Description Unit configuration files for services, sockets, - mount points and swap devices share a subset of + mount points, and swap devices share a subset of configuration options which define the execution environment of spawned processes. @@ -69,7 +69,7 @@ files, and systemd.service5, systemd.socket5, - systemd.swap5 + systemd.swap5, and systemd.mount5 for more information on the specific unit @@ -945,124 +945,6 @@ - - CPUShares= - - Assign the specified - overall CPU time shares to the - processes executed. Takes an integer - value. This controls the - cpu.shares control - group attribute, which defaults to - 1024. For details about this control - group attribute see sched-design-CFS.txt. - - - - MemoryLimit= - MemorySoftLimit= - - Limit the overall memory usage - of the executed processes to a certain - size. Takes a memory size in bytes. If - the value is suffixed with K, M, G or - T the specified memory size is parsed - as Kilobytes, Megabytes, Gigabytes, - or Terabytes (to the base - 1024), respectively. This controls the - memory.limit_in_bytes - and - memory.soft_limit_in_bytes - control group attributes. For details - about these control group attributes - see memory.txt. - - - - DeviceAllow= - DeviceDeny= - - Control access to - specific device nodes by the executed processes. Takes two - space-separated strings: a device node - path (such as - /dev/null) - followed by a combination of r, w, m - to control reading, writing, or - creating of the specific device node - by the unit, respectively. This controls the - devices.allow - and - devices.deny - control group attributes. For details - about these control group attributes - see devices.txt. - - - - BlockIOWeight= - - Set the default or - per-device overall block IO weight - value for the executed - processes. Takes either a single - weight value (between 10 and 1000) to - set the default block IO weight, or a - space-separated pair of a file path - and a weight value to specify the - device specific weight value (Example: - "/dev/sda 500"). The file path may be - specified as path to a block device - node or as any other file in which - case the backing block device of the - file system of the file is - determined. This controls the - blkio.weight and - blkio.weight_device - control group attributes, which - default to 1000. Use this option - multiple times to set weights for - multiple devices. For details about - these control group attributes see - blkio-controller.txt. - - - - BlockIOReadBandwidth= - BlockIOWriteBandwidth= - - Set the per-device - overall block IO bandwidth limit for - the executed processes. Takes a - space-separated pair of a file path and a - bandwidth value (in bytes per second) - to specify the device specific - bandwidth. The file path may be - specified as path to a block device - node or as any other file in which - case the backing block device of the - file system of the file is determined. - If the bandwidth is suffixed with K, M, - G, or T the specified bandwidth is - parsed as Kilobytes, Megabytes, - Gigabytes, or Terabytes, respectively (Example: - "/dev/disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0 - 5M"). This controls the - blkio.read_bps_device - and - blkio.write_bps_device - control group attributes. Use this - option multiple times to set bandwidth - limits for multiple devices. For - details about these control group - attributes see blkio-controller.txt. - - ReadWriteDirectories= ReadOnlyDirectories= diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml index c57f613290..214f40c742 100644 --- a/man/systemd.mount.xml +++ b/man/systemd.mount.xml @@ -73,12 +73,16 @@ which define the execution environment the mount8 binary is executed in, and in - systemd.kill5 - which define the way the processes are - terminated. Note that the User= and Group= options are - not particularly useful for mount units specifying a - Type= option or using configuration - not specified in /etc/fstab; + systemd.kill5, + which define the way the processes are terminated, and + in + systemd.cgroup5, + which configure control group settings for the + processes of the service. Note that the User= and + Group= options are not particularly useful for mount + units specifying a Type= option or + using configuration not specified in + /etc/fstab; mount8 will refuse options that aren't listed in /etc/fstab if it is not run as @@ -298,6 +302,7 @@ systemd.unit5, systemd.exec5, systemd.kill5, + systemd.cgroup5, systemd.service5, systemd.device5, proc5, diff --git a/man/systemd.scope.xml b/man/systemd.scope.xml new file mode 100644 index 0000000000..31f2d6f5a5 --- /dev/null +++ b/man/systemd.scope.xml @@ -0,0 +1,100 @@ + + + + + + + + + systemd.scope + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.scope + 5 + + + + systemd.scope + Scope unit configuration + + + + scope.scope + + + + Description + + A unit configuration file whose name ends in + .scope encodes information about a unit created + by systemd to encapsulate processes launched not by systemd + itself. This management is performed by creating a node in the + control group tree. Processes are moved into the scope by means + of the DBus API. + systemd-run can be + used to easily launch a command in a new scope unit. + + See + systemd.unit5 + for the common options of all unit configuration + files. The common configuration items are configured + in the generic [Unit] and [Install] sections. The + scope specific configuration options are configured in + the [Scope] section. Currently, only generic cgroup settings + as described in + systemd.cgroup7 are allowed. + + + Unless DefaultDependencies=false + is used, scope units will implicitly have dependencies of + type Conflicts= and + Before= on + shutdown.target. These ensure + that scope units are removed prior to system + shutdown. Only scope units involved with early boot or + late system shutdown should disable this option. + + + + + See Also + + systemd1, + systemd-run1, + systemd.unit5, + systemd.cgroup5, + systemd.service5, + systemd.directives7. + + + + diff --git a/man/systemd.service.xml b/man/systemd.service.xml index abe3a8d673..238a49a251 100644 --- a/man/systemd.service.xml +++ b/man/systemd.service.xml @@ -73,9 +73,12 @@ systemd.exec5, which define the execution environment the commands are executed in, and in - systemd.kill5 + systemd.kill5, which define the way the processes of the service are - terminated. + terminated, and in + systemd.cgroup5, + which configure control group settings for the + processes of the service. Unless DefaultDependencies= is set to , service units will @@ -994,6 +997,7 @@ systemctl8, systemd.unit5, systemd.exec5, + systemd.cgroup5, systemd.kill5, systemd.directives7 diff --git a/man/systemd.slice.xml b/man/systemd.slice.xml new file mode 100644 index 0000000000..5376921689 --- /dev/null +++ b/man/systemd.slice.xml @@ -0,0 +1,99 @@ + + + + + + + + + systemd.slice + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.slice + 5 + + + + systemd.slice + Slice unit configuration + + + + slice.slice + + + + Description + + A unit configuration file whose name ends in + .slice encodes information about a slice + created by systemd to manage resources used by a certain group of + processes. This management is performed by creating a node in the + control group tree. Those processes are part of different units, + usually .service units (see + systemd.unit5). + + + See + systemd.unit5 + for the common options of all unit configuration + files. The common configuration items are configured + in the generic [Unit] and [Install] sections. The + slice specific configuration options are configured in + the [Slice] section. Currently, only generic cgroup settings + as described in + systemd.cgroup7 are allowed. + + + Unless DefaultDependencies=false + is used, slice units will implicitly have dependencies of + type Conflicts= and + Before= on + shutdown.target. These ensure + that slice units are removed prior to system + shutdown. Only slice units involved with early boot or + late system shutdown should disable this option. + + + + + See Also + + systemd1, + systemd.unit5, + systemd.cgroup5, + systemd.service5, + systemd.directives7. + + + + diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml index 1b899c46a1..fad5c2b8c5 100644 --- a/man/systemd.socket.xml +++ b/man/systemd.socket.xml @@ -77,9 +77,12 @@ and commands are executed in, and in - systemd.kill5 + systemd.kill5, which define the way the processes are - terminated. + terminated, and in + systemd.cgroup5, + which configure control group settings for the + processes of the service. For each socket file a matching service file (see @@ -709,6 +712,7 @@ systemd.unit5, systemd.exec5, systemd.kill5, + systemd.cgroup5, systemd.service5, systemd.directives7 diff --git a/man/systemd.swap.xml b/man/systemd.swap.xml index d931c46e80..5e339ea18c 100644 --- a/man/systemd.swap.xml +++ b/man/systemd.swap.xml @@ -73,9 +73,12 @@ which define the execution environment the swapon8 binary is executed in, and in - systemd.kill5 + systemd.kill5, which define the way the processes are - terminated. + terminated, and in + systemd.cgroup5, + which configure control group settings for the + processes of the service. Swap units must be named after the devices or files they control. Example: the swap device @@ -203,6 +206,7 @@ systemd.unit5, systemd.exec5, systemd.kill5, + systemd.cgroup5, systemd.device5, systemd.mount5, swapon8, -- cgit v1.2.1 From 0c959b39175b126fdb70ae00de37ca6d9c8ca3a1 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 12 Jul 2013 12:20:18 +0200 Subject: hwdb: keyboard -- add file Do not enable/install it now, until we switch over from the current keymap tool. --- hwdb/60-keyboard.hwdb | 912 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 912 insertions(+) create mode 100644 hwdb/60-keyboard.hwdb diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb new file mode 100644 index 0000000000..e957e13a5e --- /dev/null +++ b/hwdb/60-keyboard.hwdb @@ -0,0 +1,912 @@ +# This file is part of systemd. +# +# Keyboard mapping of scan codes to key codes, and +# scan codes to add to the AT keyboard's 'force-release' list. +# +# The lookup keys are composed in: +# 60-keyboard.rules +# +# Note: The format of the "keyboard:" prefix match key is a +# contract between the rules file and the hardware data, it might +# change in later revisions to support more or better matches, it +# is not necessarily expected to be a stable ABI. +# +# Supported hardware matches are: +# - USB keyboards identified by the usb kernel modalias: +# keyboard:usb:vXXXXpYYYY* +# XXXX is the 4-digit hex uppercase vendor, and YYYY +# the 4-digit hex uppercase product. +# +# - AT keyboard DMI data matches: +# keyboard:dmi:bvn*:bvr*:bd*:svn:pn:pvr* +# and are the firmware-provided strings +# exported by the kernel DMI modalias. +# +# - Platform driver device name and DMI data match: +# keyboard:name::dmi:bvn*:bvr*:bd*:svn:pn* +# is the name device specified by the +# driver, is the firmware-provided string exported +# by the kernel DMI modalias. +# +# Scan codes are specified as: +# KEYBOARD_KEY_= +# The scan code should be expressed in hex lowercase and in +# full bytes, a multiple of 2 digits. The key codes are retrieved +# and normalized from the kernel input API header. +# +# A '!' as the first charcter of the key identifier string +# will add the scan code to the AT keyboard's list of scan codes +# where the driver will synthesize a release event and not expect +# it to be generated by the hardware. +# +# To debug key presses and access scan code mapping data of +# an input device use the commonly available tool: evtest(1). + +########################################################### +# Logitech +########################################################### + +# Logitech Cordless Wave Pro +keyboard:usb:v046DpC52[9b]* + KEYBOARD_KEY_0c01b6=camera + KEYBOARD_KEY_0c0183=media + KEYBOARD_KEY_0c0184=wordprocessor + KEYBOARD_KEY_0c0186=spreadsheet + KEYBOARD_KEY_0c018e=calendar + KEYBOARD_KEY_0c0223=homepage + KEYBOARD_KEY_0c01bc=messenger + KEYBOARD_KEY_0c018a=mail + KEYBOARD_KEY_0c0221=search + KEYBOARD_KEY_0c00b8=ejectcd + KEYBOARD_KEY_0c022d=zoomin + KEYBOARD_KEY_0c022e=zoomout + +########################################################### +# Lenovo +########################################################### + +# thinkpad_acpi driver +keyboard:name:ThinkPad Extra Buttons:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn* + KEYBOARD_KEY_01=screenlock + KEYBOARD_KEY_02=battery + KEYBOARD_KEY_03=sleep + KEYBOARD_KEY_04=wlan + KEYBOARD_KEY_06=switchvideomode + KEYBOARD_KEY_07=f21 + KEYBOARD_KEY_08=f24 + KEYBOARD_KEY_0b=suspend + KEYBOARD_KEY_0f=brightnessup + KEYBOARD_KEY_10=brightnessdown + KEYBOARD_KEY_11=kbdillumtoggle + KEYBOARD_KEY_13=zoom + KEYBOARD_KEY_14=volumeup + KEYBOARD_KEY_15=volumedown + KEYBOARD_KEY_16=mute + KEYBOARD_KEY_17=prog1 + KEYBOARD_KEY_1a=f20 + +# +keyboard:name:Ideapad extra buttons:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn* + KEYBOARD_KEY_42=f23 + KEYBOARD_KEY_43=f22 + +# ThinkPad Keyboard with TrackPoint +keyboard:usb:v17EFp6009* + KEYBOARD_KEY_090012=screenlock # Fn+F2 + KEYBOARD_KEY_090013=battery # Fn+F3 + KEYBOARD_KEY_090014=wlan # Fn+F5 + KEYBOARD_KEY_090016=switchvideomode # Fn+F7 + KEYBOARD_KEY_090017=f21 # Fn+F8 touchpad toggle + KEYBOARD_KEY_090019=suspend # Fn+F12 + KEYBOARD_KEY_09001a=brightnessup # Fn+Home + KEYBOARD_KEY_09001b=brightnessdown # Fn+End + KEYBOARD_KEY_09001d=zoom # Fn+Space + KEYBOARD_KEY_090011=prog1 # ThinkVantage button + KEYBOARD_KEY_090015=camera # Fn+F6 headset/camera VoIP key ?? + KEYBOARD_KEY_090010=f20 # Microphone mute button; should be micmute + +# Lenovo 3000 +keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*3000*:pvr* + KEYBOARD_KEY_8b=switchvideomode # Fn+F7 video + KEYBOARD_KEY_96=wlan # Fn+F5 wireless + KEYBOARD_KEY_97=sleep # Fn+F4 suspend + KEYBOARD_KEY_98=suspend # Fn+F12 hibernate + KEYBOARD_KEY_b4=prog1 # Lenovo Care + +# lenovo-ideapad +keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pnS10-*:pvr* + KEYBOARD_KEY_81=rfkill # does nothing in BIOS + KEYBOARD_KEY_83=display_off # BIOS toggles screen state + KEYBOARD_KEY_b9=brightnessup # does nothing in BIOS + KEYBOARD_KEY_ba=brightnessdown # does nothing in BIOS + KEYBOARD_KEY_f1=camera # BIOS toggles camera power + KEYBOARD_KEY_f2=f21 # touchpad toggle (key alternately emits F2 and F3) + KEYBOARD_KEY_f3=f21 + +# Thinkpad X200_Tablet +keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pnThinkPad X2* Tablet*:pvr* + KEYBOARD_KEY_5d=menu + KEYBOARD_KEY_63=fn + KEYBOARD_KEY_66=screenlock + KEYBOARD_KEY_67=cyclewindows # bezel circular arrow + KEYBOARD_KEY_68=setup # bezel setup / menu + KEYBOARD_KEY_6c=direction # rotate screen + +# ThinkPad X6 Tablet +keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pnThinkPad X6*:pvr* + KEYBOARD_KEY_6c=f21 # rotate + KEYBOARD_KEY_68=screenlock # screenlock + KEYBOARD_KEY_6b=esc # escape + KEYBOARD_KEY_6d=right # right on d-pad + KEYBOARD_KEY_6e=left # left on d-pad + KEYBOARD_KEY_71=up # up on d-pad + KEYBOARD_KEY_6f=down # down on d-pad + KEYBOARD_KEY_69=enter # enter on d-pad + +# IdeaPad +keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad Y550*:pvr* + KEYBOARD_KEY_95=media + KEYBOARD_KEY_a3=play + +# V480 +keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*Lenovo V480*:pvr* + KEYBOARD_KEY_f1=f21 + +# IdeaPad +keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad U300s*:pvr* + KEYBOARD_KEY_f1=f21 + KEYBOARD_KEY_ce=f20 + +########################################################### +# IBM +########################################################### + +# thinkpad_acpi driver +keyboard:name:ThinkPad Extra Buttons:dmi:bvn*:bvr*:bd*:svnIBM*:pn*:pvr* + KEYBOARD_KEY_01=battery # Fn+F2 + KEYBOARD_KEY_02=screenlock # Fn+F3 + KEYBOARD_KEY_03=sleep # Fn+F4 + KEYBOARD_KEY_04=wlan # Fn+F5 + KEYBOARD_KEY_06=switchvideomode # Fn+F7 + KEYBOARD_KEY_07=zoom # Fn+F8 screen expand + KEYBOARD_KEY_08=f24 # Fn+F9 undock + KEYBOARD_KEY_0b=suspend # Fn+F12 + KEYBOARD_KEY_0f=brightnessup # Fn+Home + KEYBOARD_KEY_10=brightnessdown # Fn+End + KEYBOARD_KEY_11=kbdillumtoggle # Fn+PgUp - ThinkLight + KEYBOARD_KEY_13=zoom # Fn+Space + KEYBOARD_KEY_14=volumeup + KEYBOARD_KEY_15=volumedown + KEYBOARD_KEY_16=mute + KEYBOARD_KEY_17=prog1 # ThinkPad/ThinkVantage button (high keycode: "vendor") + +# IBM Thinkpad USB Keyboard Trackpoint +usb:v04B3p301[89]* + KEYBOARD_KEY_900f0=screenlock + KEYBOARD_KEY_900f1=wlan + KEYBOARD_KEY_900f2=switchvideomode + KEYBOARD_KEY_900f3=suspend + KEYBOARD_KEY_900f4=brightnessup + KEYBOARD_KEY_900f5=brightnessdown + KEYBOARD_KEY_900f8=zoom + +########################################################### +# SONY +########################################################### + +# sony-laptop driver +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn* + KEYBOARD_KEY_06=mute # Fn+F2 + KEYBOARD_KEY_07=volumedown # Fn+F3 + KEYBOARD_KEY_08=volumeup # Fn+F4 + KEYBOARD_KEY_09=brightnessdown # Fn+F5 + KEYBOARD_KEY_0a=brightnessup # Fn+F6 + KEYBOARD_KEY_0b=switchvideomode # Fn+F7 + KEYBOARD_KEY_0e=zoom # Fn+F10 + KEYBOARD_KEY_10=suspend # Fn+F12 + +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-C1*:pvr* +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-K25*:pvr* +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-F[1-6]*:pvr* +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-FX*:pvr* +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-FRV*:pvr* +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-GR*:pvr* +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-TR*:pvr* +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-NV*:pvr* +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-Z*:pvr* +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*VGN-S360*:pvr* + KEYBOARD_KEY_06=battery + KEYBOARD_KEY_07=mute + +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVGN-AR71*:pvr* +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVGN-FW*:pvr* +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVGN-Z21*:pvr* + KEYBOARD_KEY_00=brightnessdown # Fn+F5 + KEYBOARD_KEY_10=brightnessup # Fn+F6 + KEYBOARD_KEY_11=switchvideomode # Fn+F7 + KEYBOARD_KEY_12=zoomout + KEYBOARD_KEY_14=zoomin + KEYBOARD_KEY_15=suspend # Fn+F12 + KEYBOARD_KEY_17=prog1 + KEYBOARD_KEY_20=media + +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVPC*:pvr* + KEYBOARD_KEY_05=f21 # Fn+F1 -> KEY_F21 (The actual touchpad toggle) + KEYBOARD_KEY_0d=zoomout # Fn+F9 + KEYBOARD_KEY_0e=zoomin # Fn+F10 + +########################################################### +# Hewlett Packard +########################################################### + +keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*:pvr* + KEYBOARD_KEY_81=fn_esc + KEYBOARD_KEY_89=battery # Fn+F8 + KEYBOARD_KEY_8a=screenlock # Fn+F6 + KEYBOARD_KEY_8b=camera + KEYBOARD_KEY_8c=media # music + KEYBOARD_KEY_8e=dvd + KEYBOARD_KEY_b1=help + KEYBOARD_KEY_b3=f23 # FIXME: Auto brightness + KEYBOARD_KEY_d7=wlan + KEYBOARD_KEY_92=brightnessdown # Fn+F7 (Fn+F9 on 6730b) + KEYBOARD_KEY_97=brightnessup # Fn+F8 (Fn+F10 on 6730b) + KEYBOARD_KEY_ee=switchvideomode # Fn+F4 + +# Tablet +keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[tT][aA][bB][lL][eE][tT]*:pvr* + KEYBOARD_KEY_82=prog2 # Funny Key + KEYBOARD_KEY_83=prog1 # Q + KEYBOARD_KEY_84=tab + KEYBOARD_KEY_85=esc + KEYBOARD_KEY_86=pageup + KEYBOARD_KEY_87=pagedown + +# Pavillion +keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[pP][aA][vV][iI][lL][iI][oO][nN]*:pvr* + KEYBOARD_KEY_88=media # FIXME: quick play + KEYBOARD_KEY_d8=!f23 # touchpad off + KEYBOARD_KEY_d9=!f22 # touchpad on + +# Elitebook +keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*Compaq*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*EliteBook*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*2230s*:pvr* + KEYBOARD_KEY_88=presentation + KEYBOARD_KEY_d9=help # I key (high keycode: "info") + +# Presario +keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*Presario*CQ*:pvr* + KEYBOARD_KEY_d8=f21 + KEYBOARD_KEY_d9=f21 + +# 2510p 2530p +keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*2510p*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*2530p*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP G60 Notebook PC:pvr* + KEYBOARD_KEY_d8=!f23 # touchpad off + KEYBOARD_KEY_d9=!f22 # touchpad on + +# TX2 +keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[tT][xX]2*:pvr* + KEYBOARD_KEY_c2=media + KEYBOARD_KEY_d8=!f23 # Toggle touchpad button on tx2 (OFF) + KEYBOARD_KEY_d9=!f22 # Toggle touchpad button on tx2 (ON) + +# Presario 2100 +keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnPresario 2100*:pvr* + KEYBOARD_KEY_f0=help + KEYBOARD_KEY_f1=screenlock + KEYBOARD_KEY_f3=search + +# Elitebook 8440p +keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP EliteBook 8440p:pvr* + KEYBOARD_KEY_88=www + KEYBOARD_KEY_a0=mute + KEYBOARD_KEY_ae=volumedown + KEYBOARD_KEY_b0=volumeup + KEYBOARD_KEY_ec=mail + +# Elitebook 8460p +keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP EliteBook 8460p:pvr* + KEYBOARD_KEY_f8=wlan # Wireless HW switch button + KEYBOARD_KEY_b3=prog1 # Fn+F11 - Ambient Light Sensor button + KEYBOARD_KEY_b1=prog2 # Fn+ESC - System information button + +# HDX9494nr +keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHDX9494NR:pvr* + KEYBOARD_KEY_b2=www # Fn+F3 + KEYBOARD_KEY_d8=!f23 # touchpad off + KEYBOARD_KEY_d9=!f22 # touchpad on + +########################################################### +# COMPAQ +########################################################### + +keyboard:dmi:bvn*:bvr*:bd*:svnCompaq*:pn*E500*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnCompaq*:pn*Evo N*:pvr* + KEYBOARD_KEY_a3=www # I key + KEYBOARD_KEY_9a=search + KEYBOARD_KEY_9e=email + KEYBOARD_KEY_9f=homepage + +########################################################### +# Samsung +########################################################### + +keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pvr* + KEYBOARD_KEY_74=prog1 # User key + KEYBOARD_KEY_75=www + KEYBOARD_KEY_78=mail + KEYBOARD_KEY_82=!switchvideomode # Fn+F4 CRT/LCD (high keycode: "displaytoggle") + KEYBOARD_KEY_83=!battery # Fn+F2 + KEYBOARD_KEY_84=!prog1 # Fn+F5 backlight on/off + KEYBOARD_KEY_86=!wlan # Fn+F9 + KEYBOARD_KEY_88=!brightnessup # Fn+Up + KEYBOARD_KEY_89=!brightnessdown # Fn+Down + KEYBOARD_KEY_b1=!prog2 # Fn+F7 run Samsung Magic Doctor (keypressed event is generated twice) + KEYBOARD_KEY_b3=!prog3 # Fn+F8 switch power mode (battery/dynamic/performance) + KEYBOARD_KEY_b4=!wlan # Fn+F9 (X60P) + KEYBOARD_KEY_f7=!f22 # Fn+F10 Touchpad on + KEYBOARD_KEY_f9=!f23 # Fn+F10 Touchpad off + +# Series 3 +keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*300E[457]*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*200E[45]*:pvr* + KEYBOARD_KEY_ce=! # Fn+F1 launch control setting + KEYBOARD_KEY_d5=! # Fn+F12 Wi-Fi toggle + +# Series 9 +keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*90X3A*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*900X[34]*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*900XC3*:pvr* + KEYBOARD_KEY_ce=! # Fn+F8 keyboard backlight up + KEYBOARD_KEY_8d=! # Fn+F7 keyboard backlight down + KEYBOARD_KEY_96=! # Fn+F1 performance mode (?) + KEYBOARD_KEY_97=! # Fn+F12 Wi-Fi toggle + KEYBOARD_KEY_d5=! # Fn+F6 battery life extender + +# SQ1US +keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pnSQ1US:pvr* + KEYBOARD_KEY_d4=menu + KEYBOARD_KEY_d8=f1 + KEYBOARD_KEY_d9=f10 + KEYBOARD_KEY_d6=f3 + KEYBOARD_KEY_d7=f9 + KEYBOARD_KEY_e4=f5 + KEYBOARD_KEY_ee=f11 + +# SX20S +keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*SX20S*:pvr* + KEYBOARD_KEY_74=mute + KEYBOARD_KEY_75=mute + KEYBOARD_KEY_77=f22 # Touchpad on + KEYBOARD_KEY_79=f23 # Touchpad off + +keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700Z*:pvr* + KEYBOARD_KEY_ba=ejectcd + KEYBOARD_KEY_96=keyboardbrightnessup + KEYBOARD_KEY_97=keyboardbrightnessdown + +keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700T*:pvr* + KEYBOARD_KEY_ad=leftmeta + +########################################################### +# Dell +########################################################### + +keyboard:dmi:bvn*:bvr*:bd*:svnDell:pvr* + KEYBOARD_KEY_81=playpause # Play/Pause + KEYBOARD_KEY_82=stopcd # Stop + KEYBOARD_KEY_83=previoussong # Previous song + KEYBOARD_KEY_84=nextsong # Next song + KEYBOARD_KEY_85=brightnessdown # Fn+Down Brightness Down + KEYBOARD_KEY_86=brightnessup # Fn+Up Brightness Up + KEYBOARD_KEY_87=battery # Fn+F3 battery icon + KEYBOARD_KEY_88=unknown # Fn+F2 Turn On/Off Wireless - handled in hardware + KEYBOARD_KEY_89=ejectclosecd # Fn+F10 Eject CD + KEYBOARD_KEY_8a=suspend # Fn+F1 hibernate + KEYBOARD_KEY_8b=switchvideomode # Fn+F8 CRT/LCD (high keycode: "displaytoggle") + KEYBOARD_KEY_8c=f23 # Fn+Right Auto Brightness + KEYBOARD_KEY_8F=switchvideomode # Fn+F7 aspect ratio + KEYBOARD_KEY_90=previoussong # Front panel previous song + KEYBOARD_KEY_91=prog1 # Wi-Fi Catcher (Dell-specific) + KEYBOARD_KEY_92=media # MediaDirect button (house icon) + KEYBOARD_KEY_93=f23 # FIXME Fn+Left Auto Brightness + KEYBOARD_KEY_95=camera # Shutter button - Takes a picture if optional camera available + KEYBOARD_KEY_97=email # Tablet email button + KEYBOARD_KEY_98=f21 # FIXME: Tablet screen rotation + KEYBOARD_KEY_99=nextsong # Front panel next song + KEYBOARD_KEY_9a=setup # Tablet tools button + KEYBOARD_KEY_9b=switchvideomode # Display toggle button + KEYBOARD_KEY_9e=f21 # Touchpad toggle + KEYBOARD_KEY_a2=playpause # Front panel play/pause + KEYBOARD_KEY_a4=stopcd # Front panel stop + KEYBOARD_KEY_ed=media # MediaDirect button + KEYBOARD_KEY_d8=screenlock # FIXME: Tablet lock button + KEYBOARD_KEY_d9=f21 # Touchpad toggle + +# +keyboard:dmi:bvn*:bvr*:bd*:svnDell:pnInspiron 910:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDell:pnInspiron 101[012]:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDell:pnInspiron 1110:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDell:pnInspiron 1210:pvr* + KEYBOARD_KEY_84=wlan + +# Latitude XT2 +keyboard:dmi:bvn*:bvr*:bd*:svnDell:pnLatitude XT2:pvr* + KEYBOARD_KEY_9b=up # tablet rocker up + KEYBOARD_KEY_9e=enter # tablet rocker press + KEYBOARD_KEY_9f=back # tablet back + KEYBOARD_KEY_a3=down # tablet rocker down + +keyboard:dmi:bvn*:bvr*:bd*:svnDell Inc.:pnStudio 155[78]:pvr* + KEYBOARD_KEY_a0=! # mute + KEYBOARD_KEY_ae=! # volume down + KEYBOARD_KEY_b0=! # volume up + +# Dell Touchpad +keyboard:dmi:bvn*:bvr*:bd*:svnDell Inc.:pn:*Latitude*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDell Inc.:pn:*Precision*:pvr* + KEYBOARD_KEY_9e=! + +# Dell XPS +keyboard:dmi:bvn*:bvr*:bd*:svnDell Inc.:pnXPS*:pvr* + KEYBOARD_KEY_8c=! + +########################################################### +# Microsoft +########################################################### + +# Microsoft Natural Ergonomic Keyboard 4000 +keyboard:usb:v045Ep00DB* + KEYBOARD_KEY_c022d=zoomin + KEYBOARD_KEY_c022e=zoomout + +########################################################### +# Acer +########################################################### + +keyboard:name:Acer WMI hotkeys:dmi:bvn*:bvr*:bd*:svn*:pnAcer*:pvr* + KEYBOARD_KEY_82=f21 + +########################################################### +# MSI +########################################################### + +keyboard:name:MSI Laptop hotkeys:dmi:bvn*:bvr*:bd*:svn*:pnM[iI][cC][rR][oO]-S[tT][aA][rR]*:pvr* + KEYBOARD_KEY_0213=f22 + KEYBOARD_KEY_0214=f23 + +########################################## +# Acer +########################################## + +# Aspire 5720 +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire 5720*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnZG8*:pvr* + KEYBOARD_KEY_84=bluetooth # sent when bluetooth module missing, and key pressed + KEYBOARD_KEY_92=media # Acer arcade + KEYBOARD_KEY_d4=bluetooth # Bluetooth on + KEYBOARD_KEY_d9=bluetooth # Bluetooth off + KEYBOARD_KEY_f4=prog3 # e-key + +# Aspire 5920g +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire 5920G:* + KEYBOARD_KEY_8a=media + KEYBOARD_KEY_92=media + KEYBOARD_KEY_a6=setup + KEYBOARD_KEY_b2=www + KEYBOARD_KEY_d9=bluetooth # (toggle) on-to-off + +# Aspire 6920 +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire 6920:* + KEYBOARD_KEY_d9=bluetooth # (toggle) on-to-off + KEYBOARD_KEY_92=media + KEYBOARD_KEY_9e=back + KEYBOARD_KEY_83=rewind + KEYBOARD_KEY_89=fastforward + +# Aspire 8930 +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire 8930:* + KEYBOARD_KEY_ca=prog3 # key 'HOLD' on CineDash Media Console + KEYBOARD_KEY_83=rewind + KEYBOARD_KEY_89=fastforward + KEYBOARD_KEY_92=media # key 'ARCADE' on CineDash Media Console + KEYBOARD_KEY_9e=back + +# Travelmate C300 +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*C3[01]0*:pvr* + KEYBOARD_KEY_67=f24 # FIXME: rotate screen + KEYBOARD_KEY_68=up + KEYBOARD_KEY_69=down + KEYBOARD_KEY_6b=fn + KEYBOARD_KEY_6c=screenlock # FIXME: lock tablet device/buttons + +# +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pn* +keyboard:dmi:bvn*:bvr*:bd*:svnGateway*:pnA0A1*:pvr* + KEYBOARD_KEY_a5=help # Fn+F1 + KEYBOARD_KEY_a6=setup # Fn+F2 Acer eSettings + KEYBOARD_KEY_a7=battery # Fn+F3 Power Management + KEYBOARD_KEY_a9=switchvideomode # Fn+F5 + KEYBOARD_KEY_b3=euro + KEYBOARD_KEY_b4=dollar + KEYBOARD_KEY_ce=brightnessup # Fn+Right + KEYBOARD_KEY_d4=bluetooth # (toggle) off-to-on + KEYBOARD_KEY_d5=wlan # (toggle) on-to-off + KEYBOARD_KEY_d6=wlan # (toggle) off-to-on + KEYBOARD_KEY_d7=bluetooth # (toggle) on-to-off + KEYBOARD_KEY_d8=bluetooth # (toggle) off-to-on + KEYBOARD_KEY_d9=brightnessup # Fn+Right + KEYBOARD_KEY_ee=brightnessup # Fn+Right + KEYBOARD_KEY_ef=brightnessdown # Fn+Left + KEYBOARD_KEY_f1=f22 # Fn+F7 Touchpad toggle (off-to-on) + KEYBOARD_KEY_f2=f23 # Fn+F7 Touchpad toggle (on-to-off) + KEYBOARD_KEY_f3=prog2 # "P2" programmable button + KEYBOARD_KEY_f4=prog1 # "P1" programmable button + KEYBOARD_KEY_f5=presentation + KEYBOARD_KEY_f8=fn + KEYBOARD_KEY_f9=f23 # Launch NTI shadow + +# +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5210*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5220*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5610*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5620*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5720*:pvr* + KEYBOARD_KEY_ee=screenlock + +# +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*6292*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*8471*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*4720*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*7720*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire 1810T*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAO751h:* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAO531h:* + KEYBOARD_KEY_d9=bluetooth + +# +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*4720*:pvr* + KEYBOARD_KEY_b2=www + KEYBOARD_KEY_ee=screenlock + +# +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate 6593:* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire 1640:* + KEYBOARD_KEY_b2=www + KEYBOARD_KEY_ee=screenlock" + +########################################## +# Fujitsu +########################################## + +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pnAMILO*M*:pvr* + KEYBOARD_KEY_97=prog2 + KEYBOARD_KEY_9f=prog1 + +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pnAmilo Li 1718:* + KEYBOARD_KEY_d6=wlan + +# Amilo Li 2732 +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pnAMILO Li 2732:* + KEYBOARD_KEY_d9=brightnessdown # Fn+F8 brightness down + KEYBOARD_KEY_ef=brightnessup # Fn+F9 brightness up + KEYBOARD_KEY_a9=switchvideomode # Fn+F10 Cycle between available video outputs + +# Amilo Pa 2548 +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*AMILO Pa 2548*:pvr* + KEYBOARD_KEY_e0=volumedown + KEYBOARD_KEY_e1=volumeup + KEYBOARD_KEY_e5=prog1 + +# Amilo Pro Edition V3505 +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*AMILO Pro Edition V3505*:pvr* + KEYBOARD_KEY_a5=help # Fn+F1 + KEYBOARD_KEY_a9=switchvideomode # Fn+F3 + KEYBOARD_KEY_d9=brightnessdown # Fn+F8 + KEYBOARD_KEY_e0=brightnessup # Fn+F9 + +# Amilo Pro v3205 +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*AMILO Pro V3205*:pvr* + KEYBOARD_KEY_f4=f21 # FIXME: silent-mode decrease CPU/GPU clock + KEYBOARD_KEY_f7=switchvideomode # Fn+F3 + +# Amilo Si 1520 +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*Amilo Si 1520*:pvr* + KEYBOARD_KEY_e1=wlan + KEYBOARD_KEY_f3=wlan + KEYBOARD_KEY_ee=brightnessdown + KEYBOARD_KEY_e0=brightnessup + KEYBOARD_KEY_e2=bluetooth + KEYBOARD_KEY_f7=video + +# Esprimo Mobile V5 +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*ESPRIMO Mobile V5*:pvr* + KEYBOARD_KEY_a9=switchvideomode + KEYBOARD_KEY_d9=brightnessdown + KEYBOARD_KEY_df=sleep + KEYBOARD_KEY_ef=brightnessup + +# Esprimo Mobile V6 +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*ESPRIMO Mobile V6*:pvr* + KEYBOARD_KEY_ce=brightnessup + KEYBOARD_KEY_ef=brightnessdown + +########################################################### +# Toshiba +########################################################### + +# Satellite A100 +keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSATELLITE A100:pvr* + KEYBOARD_KEY_a4=stopcd + KEYBOARD_KEY_b2=www + +# Satellite A110 +keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite A110:pvr* + KEYBOARD_KEY_92=stop + KEYBOARD_KEY_93=www + KEYBOARD_KEY_94=media + KEYBOARD_KEY_9e=f22 # Touchpad on + KEYBOARD_KEY_9f=f23 # Touchpad off + KEYBOARD_KEY_b9=nextsong + KEYBOARD_KEY_d9=brightnessup + KEYBOARD_KEY_ee=screenlock + KEYBOARD_KEY_f4=previoussong + KEYBOARD_KEY_f7=playpause + +# Satellite M30X +keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite M30X:pvr* + KEYBOARD_KEY_ef=brightnessdown + KEYBOARD_KEY_d9=brightnessup + KEYBOARD_KEY_ee=screenlock + KEYBOARD_KEY_93=media + KEYBOARD_KEY_9e=f22 # touchpad enable + KEYBOARD_KEY_9f=f23 # touchpad disable + +########################################################### +# Micro Star +########################################################### + +keyboard:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pn* +keyboard:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn* + KEYBOARD_KEY_a0=mute # Fn+F9 + KEYBOARD_KEY_ae=volumedown # Fn+F7 + KEYBOARD_KEY_b0=volumeup # Fn+F8 + KEYBOARD_KEY_b2=www # e button + KEYBOARD_KEY_df=sleep # Fn+F12 + KEYBOARD_KEY_e2=bluetooth # satellite dish2 + KEYBOARD_KEY_e4=f21 # Fn+F3 Touchpad disable + KEYBOARD_KEY_ec=email # envelope button + KEYBOARD_KEY_ee=camera # Fn+F6 camera disable + KEYBOARD_KEY_f6=wlan # satellite dish1 + KEYBOARD_KEY_f7=brightnessdown # Fn+F4 + KEYBOARD_KEY_f8=brightnessup # Fn+F5 + KEYBOARD_KEY_f9=search + +# +keyboard:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pnGE60*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pnGE70*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn*:pvr* + KEYBOARD_KEY_c2=ejectcd + +# +keyboard:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pn*U-100*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pn*U100*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pn*N033:* + KEYBOARD_KEY_f7=reserved + KEYBOARD_KEY_f8=reserved + +# +keyboard:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pnU90/U100:* + KEYBOARD_KEY_e4=reserved +########################################################### +# Other +########################################################### + +# Genius Slimstar 320 +keyboard:usb:v0458p0708d*dc*dsc*dp*ic*isc*ip*in01* + KEYBOARD_KEY_0900f0=scrollup + KEYBOARD_KEY_0900f1=scrolldown + KEYBOARD_KEY_0900f3=back + KEYBOARD_KEY_0900f2=forward + KEYBOARD_KEY_0900f5=wordprocessor + KEYBOARD_KEY_0900f6=spreadsheet + KEYBOARD_KEY_0900f4=presentation + KEYBOARD_KEY_0c0223=www + KEYBOARD_KEY_0900f7=chat + KEYBOARD_KEY_0900fb=prog1 + KEYBOARD_KEY_0900f8=close + KEYBOARD_KEY_0900f9=graphicseditor + KEYBOARD_KEY_0900fd=scale + KEYBOARD_KEY_0900fc=screenlock + +# Asus +keyboard:dmi:bvn*:bvr*:bd*:svnASUS:* + KEYBOARD_KEY_ed=volumeup + KEYBOARD_KEY_ee=volumedown + KEYBOARD_KEY_ef=mute + +# VIA +keyboard:dmi:bvn*:bvr*:bd*:svnVIA:pnK8N800:pvr* + KEYBOARD_KEY_81=prog1 + +# Everex +keyboard:dmi:bvn*:bvr*:bd*:svnEverex:pnXT5000*:pvr* + KEYBOARD_KEY_5c=media + KEYBOARD_KEY_65=f21 # Fn+F5 Touchpad toggle + KEYBOARD_KEY_67=prog3 # Fan speed control button + KEYBOARD_KEY_6f=brightnessup + KEYBOARD_KEY_7f=brightnessdown + KEYBOARD_KEY_b2=www + KEYBOARD_KEY_ec=mail + +# Compal +keyboard:dmi:bvn*:bvr*:bd*:svnCOMPAL:pnHEL80I:* + KEYBOARD_KEY_84=wlan + +# OLPC XO +keyboard:dmi:bvn*:bvr*:bd*:svnOLPC:pnXO:* + KEYBOARD_KEY_59=fn + KEYBOARD_KEY_81=fn_esc + KEYBOARD_KEY_f9=camera + KEYBOARD_KEY_f8=sound # Fn+CAMERA = Mic + KEYBOARD_KEY_43=brightnessdown + KEYBOARD_KEY_44=brightnessup + KEYBOARD_KEY_57=volumedown + KEYBOARD_KEY_58=volumeup + KEYBOARD_KEY_bb=f1 + KEYBOARD_KEY_bc=f2 + KEYBOARD_KEY_bd=f3 + KEYBOARD_KEY_be=f4 + KEYBOARD_KEY_bf=f5 + KEYBOARD_KEY_c0=f6 + KEYBOARD_KEY_c1=f7 + KEYBOARD_KEY_c2=f8 + KEYBOARD_KEY_c3=f9 + KEYBOARD_KEY_c4=f10 + KEYBOARD_KEY_c7=f11 + KEYBOARD_KEY_d8=f12 + KEYBOARD_KEY_f7=f13 + KEYBOARD_KEY_f6=f14 + KEYBOARD_KEY_f5=f15 + KEYBOARD_KEY_f4=f16 + KEYBOARD_KEY_f3=f17 + KEYBOARD_KEY_f2=f18 + KEYBOARD_KEY_f1=f19 + KEYBOARD_KEY_f0=f20 + KEYBOARD_KEY_ef=f21 + KEYBOARD_KEY_ee=chat + KEYBOARD_KEY_e4=chat + KEYBOARD_KEY_dd=menu # Frame + KEYBOARD_KEY_da=prog1 # Fn+Frame + KEYBOARD_KEY_d3=delete + KEYBOARD_KEY_d2=insert + KEYBOARD_KEY_c9=pageup + KEYBOARD_KEY_d1=pagedown + KEYBOARD_KEY_c7=home + KEYBOARD_KEY_cF=end + KEYBOARD_KEY_73=hp + KEYBOARD_KEY_7e=hp + KEYBOARD_KEY_db=leftmeta # left grab + KEYBOARD_KEY_dc=rightmeta # right grab + KEYBOARD_KEY_85=rightmeta # Right grab releases on a different scancode + KEYBOARD_KEY_d6=kbdillumtoggle # Fn+Space + KEYBOARD_KEY_69=switchvideomode # Brightness key + KEYBOARD_KEY_65=kp8 # up + KEYBOARD_KEY_66=kp2 # down + KEYBOARD_KEY_67=kp4 # left + KEYBOARD_KEY_68=kp6 # right + KEYBOARD_KEY_e5=kp9 # pgup + KEYBOARD_KEY_e6=kp3 # pgdn + KEYBOARD_KEY_e7=kp7 # home + KEYBOARD_KEY_e8=kp1 # end + +# Alienware +keyboard:dmi:bvn*:bvr*:bd*:svnAlienware*:pn* + KEYBOARD_KEY_8a=ejectcd + +# Zepto Znote +keyboard:dmi:bvn*:bvr*:bd*:svnZepto:pnZnote:* + KEYBOARD_KEY_93=switchvideomode # Fn+F3 Toggle Video Output + KEYBOARD_KEY_95=brightnessdown # Fn+F4 Brightness Down + KEYBOARD_KEY_91=brightnessup # Fn+F5 Brightness Up + KEYBOARD_KEY_a5=f23 # Fn+F6 Disable Touchpad + KEYBOARD_KEY_a6=f22 # Fn+F6 Enable Touchpad + KEYBOARD_KEY_a7=bluetooth # Fn+F10 Enable Bluetooth + KEYBOARD_KEY_a9=bluetooth # Fn+F10 Disable Bluetooth + KEYBOARD_KEY_f1=wlan # RF Switch Off + KEYBOARD_KEY_f2=wlan # RF Switch On + KEYBOARD_KEY_f4=prog1 # P1 Button + KEYBOARD_KEY_f3=prog2 # P2 Button + KEYBOARD_KEY_a0=! # mute + KEYBOARD_KEY_ae=! # volume down + KEYBOARD_KEY_b0=! # volume up + +keyboard:dmi:bvn*:bvr*:bd*:svnZepto:pnZnote 6615WD:* + KEYBOARD_KEY_a0=! # mute + KEYBOARD_KEY_ae=! # volume down + KEYBOARD_KEY_b0=! # volume up + +# Onkyo +keyboard:dmi:bvn*:bvr*:bd*:svnONKYO CORPORATION:pnONKYOPC:* + KEYBOARD_KEY_a0=mute # Fn+D + KEYBOARD_KEY_ae=volumedown # Fn+F + KEYBOARD_KEY_b0=volumeup # Fn+G + KEYBOARD_KEY_df=sleep # Fn+W + KEYBOARD_KEY_e0=bluetooth # Fn+H + KEYBOARD_KEY_e2=cyclewindows # Fn+Esc + KEYBOARD_KEY_ee=battery # Fn+Q + KEYBOARD_KEY_f0=media # Fn+R + KEYBOARD_KEY_f5=switchvideomode # Fn+E + KEYBOARD_KEY_f6=camera # Fn+T + KEYBOARD_KEY_f7=f21 # Fn+Y (touchpad toggle) + KEYBOARD_KEY_f8=brightnessup # Fn+S + KEYBOARD_KEY_f9=brightnessdown # Fn+A + KEYBOARD_KEY_fb=wlan # Fn+J + +# Quanta +keyboard:dmi:bvn*:bvr*:bd*:svn*:pn*:pvr*:rvnQuanta:rn30B7:rvr65.2B:* + KEYBOARD_KEY_88=media # "quick play + +# BenQ +keyboard:dmi:bvn*:bvr*:bd*:svn*BenQ*:pn*Joybook R22*:pvr* + KEYBOARD_KEY_6e=wlan + +# Common Volume Keys +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU SIEMENS:pnAMILO*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnFOXCONN:pnQBOOK:* +keyboard:dmi:bvn*:bvr*:bd*:svnMTC:pn*:pvrA0:* +keyboard:dmi:bvn*:bvr*:bd*:svnMio Technology:pnN890:* +keyboard:dmi:bvn*:bvr*:bd*:svnPEGATRON CORP.:pnSpring Peak:* +keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA:pnSatellite [uU]30[05]*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA:pnSatellite Pro [uU]300*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA:pnSATELLITE [uU]500*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnViooo Corporation:pnPT17:* +keyboard:dmi:bvn*:bvr*:bd*:svnHANNspree:pnSN10E100:* +keyboard:dmi:bvn*:bvr*:bd*:svnGIGABYTE:pni1520M:* +keyboard:dmi:bvn*:bvr*:bd*:svnBenQ:pn*nScreen*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnBenQ:pnJoybook Lite*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDIXONSP:pnDIXON*:pvr* + KEYBOARD_KEY_a0=! # mute + KEYBOARD_KEY_ae=! # volume down + KEYBOARD_KEY_b0=! # volume up + +# Maxdata Pro 7000 +keyboard:dmi:bvn*:bvr*:bd*:svnMAXDATA:pnPro 7000*:pvr* + KEYBOARD_KEY_97=prog2 + KEYBOARD_KEY_9f=prog1 + KEYBOARD_KEY_a0=mute # Fn+F5 + KEYBOARD_KEY_82=www + KEYBOARD_KEY_ec=email + KEYBOARD_KEY_ae=volumedown # Fn+Down + KEYBOARD_KEY_b0=volumeup # Fn+Up + KEYBOARD_KEY_df=suspend # Fn+F2 + KEYBOARD_KEY_f5=help + +# Oqo Model 2 +keyboard:dmi:bvn*:bvr*:bd*:svnOQO Inc.*:pnOQO Model 2*:pvr* + KEYBOARD_KEY_8e=wlan + KEYBOARD_KEY_f0=switchvideomode + KEYBOARD_KEY_f1=mute + KEYBOARD_KEY_f2=volumedown + KEYBOARD_KEY_f3=volumeup + +# Inventec Symphony +keyboard:dmi:bvn*:bvr*:bd*:svnINVENTEC:pnSYMPHONY 6.0/7.0:pvr* + KEYBOARD_KEY_f3=prog2 + KEYBOARD_KEY_f4=prog1 + +# Medion FID2060 +keyboard:dmi:bvn*:bvr*:bd*:svnMEDION*:pn*FID2060*:pvr* + KEYBOARD_KEY_6b=channeldown # Thottle Down + KEYBOARD_KEY_6d=channelup # Thottle Up + +# Medion NB-A555 +keyboard:dmi:bvn*:bvr*:bd*:svnMEDIONNB:pnA555*:pvr* + KEYBOARD_KEY_63=www # N button + KEYBOARD_KEY_66=prog1 # link 1 button + KEYBOARD_KEY_67=email # envelope button + KEYBOARD_KEY_69=prog2 # link 2 button -- cgit v1.2.1 From e8193554925a22b63bef0e77b8397b56d63a91ff Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 12 Jul 2013 13:44:08 +0200 Subject: hwdb: keyboard -- update comments --- hwdb/60-keyboard.hwdb | 135 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 93 insertions(+), 42 deletions(-) diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index e957e13a5e..94357e7748 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -464,13 +464,6 @@ keyboard:usb:v045Ep00DB* KEYBOARD_KEY_c022d=zoomin KEYBOARD_KEY_c022e=zoomout -########################################################### -# Acer -########################################################### - -keyboard:name:Acer WMI hotkeys:dmi:bvn*:bvr*:bd*:svn*:pnAcer*:pvr* - KEYBOARD_KEY_82=f21 - ########################################################### # MSI ########################################################### @@ -483,6 +476,10 @@ keyboard:name:MSI Laptop hotkeys:dmi:bvn*:bvr*:bd*:svn*:pnM[iI][cC][rR][oO]-S[tT # Acer ########################################## +# Acer platform kernel driver +keyboard:name:Acer WMI hotkeys:dmi:bvn*:bvr*:bd*:svn*:pnAcer*:pvr* + KEYBOARD_KEY_82=f21 + # Aspire 5720 keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire 5720*:pvr* keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnZG8*:pvr* @@ -702,11 +699,28 @@ keyboard:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pn*N033:* # keyboard:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pnU90/U100:* KEYBOARD_KEY_e4=reserved + ########################################################### -# Other +# Medion +########################################################### + +# FID2060 +keyboard:dmi:bvn*:bvr*:bd*:svnMEDION*:pn*FID2060*:pvr* + KEYBOARD_KEY_6b=channeldown # Thottle Down + KEYBOARD_KEY_6d=channelup # Thottle Up + +# NB-A555 +keyboard:dmi:bvn*:bvr*:bd*:svnMEDIONNB:pnA555*:pvr* + KEYBOARD_KEY_63=www # N button + KEYBOARD_KEY_66=prog1 # link 1 button + KEYBOARD_KEY_67=email # envelope button + KEYBOARD_KEY_69=prog2 # link 2 button + +########################################################### +# Genius ########################################################### -# Genius Slimstar 320 +# Slimstar 320 keyboard:usb:v0458p0708d*dc*dsc*dp*ic*isc*ip*in01* KEYBOARD_KEY_0900f0=scrollup KEYBOARD_KEY_0900f1=scrolldown @@ -723,17 +737,26 @@ keyboard:usb:v0458p0708d*dc*dsc*dp*ic*isc*ip*in01* KEYBOARD_KEY_0900fd=scale KEYBOARD_KEY_0900fc=screenlock +########################################################### # Asus +########################################################### + keyboard:dmi:bvn*:bvr*:bd*:svnASUS:* KEYBOARD_KEY_ed=volumeup KEYBOARD_KEY_ee=volumedown KEYBOARD_KEY_ef=mute +########################################################### # VIA +########################################################### + keyboard:dmi:bvn*:bvr*:bd*:svnVIA:pnK8N800:pvr* KEYBOARD_KEY_81=prog1 +########################################################### # Everex +########################################################### + keyboard:dmi:bvn*:bvr*:bd*:svnEverex:pnXT5000*:pvr* KEYBOARD_KEY_5c=media KEYBOARD_KEY_65=f21 # Fn+F5 Touchpad toggle @@ -743,11 +766,18 @@ keyboard:dmi:bvn*:bvr*:bd*:svnEverex:pnXT5000*:pvr* KEYBOARD_KEY_b2=www KEYBOARD_KEY_ec=mail +########################################################### # Compal +########################################################### + keyboard:dmi:bvn*:bvr*:bd*:svnCOMPAL:pnHEL80I:* KEYBOARD_KEY_84=wlan -# OLPC XO +########################################################### +# OLPC +########################################################### + +# XO keyboard:dmi:bvn*:bvr*:bd*:svnOLPC:pnXO:* KEYBOARD_KEY_59=fn KEYBOARD_KEY_81=fn_esc @@ -804,11 +834,18 @@ keyboard:dmi:bvn*:bvr*:bd*:svnOLPC:pnXO:* KEYBOARD_KEY_e7=kp7 # home KEYBOARD_KEY_e8=kp1 # end +########################################################### # Alienware +########################################################### + keyboard:dmi:bvn*:bvr*:bd*:svnAlienware*:pn* KEYBOARD_KEY_8a=ejectcd -# Zepto Znote +########################################################### +# Zepto +########################################################### + +# Znote keyboard:dmi:bvn*:bvr*:bd*:svnZepto:pnZnote:* KEYBOARD_KEY_93=switchvideomode # Fn+F3 Toggle Video Output KEYBOARD_KEY_95=brightnessdown # Fn+F4 Brightness Down @@ -825,12 +862,16 @@ keyboard:dmi:bvn*:bvr*:bd*:svnZepto:pnZnote:* KEYBOARD_KEY_ae=! # volume down KEYBOARD_KEY_b0=! # volume up +# Znote 6615WD keyboard:dmi:bvn*:bvr*:bd*:svnZepto:pnZnote 6615WD:* KEYBOARD_KEY_a0=! # mute KEYBOARD_KEY_ae=! # volume down KEYBOARD_KEY_b0=! # volume up +########################################################### # Onkyo +########################################################### + keyboard:dmi:bvn*:bvr*:bd*:svnONKYO CORPORATION:pnONKYOPC:* KEYBOARD_KEY_a0=mute # Fn+D KEYBOARD_KEY_ae=volumedown # Fn+F @@ -847,34 +888,25 @@ keyboard:dmi:bvn*:bvr*:bd*:svnONKYO CORPORATION:pnONKYOPC:* KEYBOARD_KEY_f9=brightnessdown # Fn+A KEYBOARD_KEY_fb=wlan # Fn+J +########################################################### # Quanta +########################################################### + keyboard:dmi:bvn*:bvr*:bd*:svn*:pn*:pvr*:rvnQuanta:rn30B7:rvr65.2B:* KEYBOARD_KEY_88=media # "quick play +########################################################### # BenQ +########################################################### + keyboard:dmi:bvn*:bvr*:bd*:svn*BenQ*:pn*Joybook R22*:pvr* KEYBOARD_KEY_6e=wlan -# Common Volume Keys -keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU SIEMENS:pnAMILO*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnFOXCONN:pnQBOOK:* -keyboard:dmi:bvn*:bvr*:bd*:svnMTC:pn*:pvrA0:* -keyboard:dmi:bvn*:bvr*:bd*:svnMio Technology:pnN890:* -keyboard:dmi:bvn*:bvr*:bd*:svnPEGATRON CORP.:pnSpring Peak:* -keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA:pnSatellite [uU]30[05]*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA:pnSatellite Pro [uU]300*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA:pnSATELLITE [uU]500*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnViooo Corporation:pnPT17:* -keyboard:dmi:bvn*:bvr*:bd*:svnHANNspree:pnSN10E100:* -keyboard:dmi:bvn*:bvr*:bd*:svnGIGABYTE:pni1520M:* -keyboard:dmi:bvn*:bvr*:bd*:svnBenQ:pn*nScreen*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnBenQ:pnJoybook Lite*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnDIXONSP:pnDIXON*:pvr* - KEYBOARD_KEY_a0=! # mute - KEYBOARD_KEY_ae=! # volume down - KEYBOARD_KEY_b0=! # volume up +########################################################### +# Maxdata +########################################################### -# Maxdata Pro 7000 +# Pro 7000 keyboard:dmi:bvn*:bvr*:bd*:svnMAXDATA:pnPro 7000*:pvr* KEYBOARD_KEY_97=prog2 KEYBOARD_KEY_9f=prog1 @@ -886,7 +918,11 @@ keyboard:dmi:bvn*:bvr*:bd*:svnMAXDATA:pnPro 7000*:pvr* KEYBOARD_KEY_df=suspend # Fn+F2 KEYBOARD_KEY_f5=help -# Oqo Model 2 +########################################################### +# OQO +########################################################### + +# Model 2 keyboard:dmi:bvn*:bvr*:bd*:svnOQO Inc.*:pnOQO Model 2*:pvr* KEYBOARD_KEY_8e=wlan KEYBOARD_KEY_f0=switchvideomode @@ -894,19 +930,34 @@ keyboard:dmi:bvn*:bvr*:bd*:svnOQO Inc.*:pnOQO Model 2*:pvr* KEYBOARD_KEY_f2=volumedown KEYBOARD_KEY_f3=volumeup -# Inventec Symphony +########################################################### +# Inventec +########################################################### + +# Symphony keyboard:dmi:bvn*:bvr*:bd*:svnINVENTEC:pnSYMPHONY 6.0/7.0:pvr* KEYBOARD_KEY_f3=prog2 KEYBOARD_KEY_f4=prog1 -# Medion FID2060 -keyboard:dmi:bvn*:bvr*:bd*:svnMEDION*:pn*FID2060*:pvr* - KEYBOARD_KEY_6b=channeldown # Thottle Down - KEYBOARD_KEY_6d=channelup # Thottle Up +########################################################### +# Other +########################################################### -# Medion NB-A555 -keyboard:dmi:bvn*:bvr*:bd*:svnMEDIONNB:pnA555*:pvr* - KEYBOARD_KEY_63=www # N button - KEYBOARD_KEY_66=prog1 # link 1 button - KEYBOARD_KEY_67=email # envelope button - KEYBOARD_KEY_69=prog2 # link 2 button +# Common Volume Keys +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU SIEMENS:pnAMILO*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnFOXCONN:pnQBOOK:* +keyboard:dmi:bvn*:bvr*:bd*:svnMTC:pn*:pvrA0:* +keyboard:dmi:bvn*:bvr*:bd*:svnMio Technology:pnN890:* +keyboard:dmi:bvn*:bvr*:bd*:svnPEGATRON CORP.:pnSpring Peak:* +keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA:pnSatellite [uU]30[05]*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA:pnSatellite Pro [uU]300*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA:pnSATELLITE [uU]500*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnViooo Corporation:pnPT17:* +keyboard:dmi:bvn*:bvr*:bd*:svnHANNspree:pnSN10E100:* +keyboard:dmi:bvn*:bvr*:bd*:svnGIGABYTE:pni1520M:* +keyboard:dmi:bvn*:bvr*:bd*:svnBenQ:pn*nScreen*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnBenQ:pnJoybook Lite*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDIXONSP:pnDIXON*:pvr* + KEYBOARD_KEY_a0=! # mute + KEYBOARD_KEY_ae=! # volume down + KEYBOARD_KEY_b0=! # volume up -- cgit v1.2.1 From b463b81399f0bc0d54107ef819cc0f843473c7d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 12 Jul 2013 08:04:39 -0400 Subject: test-path-util,test-sched-prio: uninitialize manager to appease valgrind --- src/test/test-path-util.c | 2 +- src/test/test-sched-prio.c | 2 ++ src/test/test-unit-name.c | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c index 127e17803f..f396b32ffe 100644 --- a/src/test/test-path-util.c +++ b/src/test/test-path-util.c @@ -56,7 +56,7 @@ static void test_path(void) { assert_se(streq(path_get_file_name("file.../"), "")); #define test_parent(x, y) { \ - char *z; \ + char _cleanup_free_ *z = NULL; \ int r = path_get_parent(x, &z); \ printf("expected: %s\n", y ? y : "error"); \ printf("actual: %s\n", r<0 ? "error" : z); \ diff --git a/src/test/test-sched-prio.c b/src/test/test-sched-prio.c index 7af740757a..509c75f42d 100644 --- a/src/test/test-sched-prio.c +++ b/src/test/test-sched-prio.c @@ -88,5 +88,7 @@ int main(int argc, char *argv[]) { assert_se(ser->exec_context.cpu_sched_policy == SCHED_RR); assert_se(ser->exec_context.cpu_sched_priority == 99); + manager_free(m); + return EXIT_SUCCESS; } diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c index 93bf28aace..2fa0294882 100644 --- a/src/test/test-unit-name.c +++ b/src/test/test-unit-name.c @@ -190,6 +190,8 @@ static int test_unit_printf(void) { expect(u2, "%H", host); expect(u2, "%t", "/run/user/*"); + manager_free(m); + return 0; } -- cgit v1.2.1 From d7b478b448d16b0f755e7e1c2eb4df83859034b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 12 Jul 2013 08:15:21 -0400 Subject: shared/install: fix trivial memleak We lost the reference when setting path second time. --- src/shared/install.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/shared/install.c b/src/shared/install.c index d2dd276803..eb9a5fc0b5 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -506,7 +506,7 @@ static int find_symlinks_in_scope( UnitFileState *state) { int r; - _cleanup_free_ char *path = NULL; + _cleanup_free_ char *path2 = NULL; bool same_name_link_runtime = false, same_name_link = false; assert(scope >= 0); @@ -514,6 +514,7 @@ static int find_symlinks_in_scope( assert(name); if (scope == UNIT_FILE_SYSTEM || scope == UNIT_FILE_GLOBAL) { + _cleanup_free_ char *path = NULL; /* First look in runtime config path */ r = get_config_path(scope, true, root_dir, &path); @@ -530,11 +531,11 @@ static int find_symlinks_in_scope( } /* Then look in the normal config path */ - r = get_config_path(scope, false, root_dir, &path); + r = get_config_path(scope, false, root_dir, &path2); if (r < 0) return r; - r = find_symlinks(name, path, &same_name_link); + r = find_symlinks(name, path2, &same_name_link); if (r < 0) return r; else if (r > 0) { -- cgit v1.2.1 From 9f64229f9ca69f5652b238a67531432e56108bd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 12 Jul 2013 13:19:19 -0400 Subject: Revert "build-sys: don't enable color gcc on dumb terminals" This reverts commit cd3069559a09b4e4f85a6f02aa8f0521f48359ca. Emacs compilation can be fixed by putting (custom-set-variables '(compilation-environment (quote ("GCC_COLORS=")))) in ~/.emacs. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 802009efcd..1e196f7307 100644 --- a/configure.ac +++ b/configure.ac @@ -133,7 +133,7 @@ CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [\ -ffast-math \ -fno-common \ -fdiagnostics-show-option \ - -fdiagnostics-color=auto \ + -fdiagnostics-color \ -fno-strict-aliasing \ -fvisibility=hidden \ -ffunction-sections \ -- cgit v1.2.1 From 3d56f7df4411684404470d36ddec0d90649a13a3 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Fri, 12 Jul 2013 11:14:54 +0200 Subject: static-nodes: don't hardcode path to mkdir --- Makefile.am | 1 + units/kmod-static-nodes.service.in | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index f1dfeedf58..2283d05789 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4173,6 +4173,7 @@ substitutions = \ '|DEBUGTTY=$(DEBUGTTY)|' \ '|KILL=$(KILL)|' \ '|KMOD=$(KMOD)|' \ + '|MKDIR_P=$(MKDIR_P)|' \ '|QUOTAON=$(QUOTAON)|' \ '|QUOTACHECK=$(QUOTACHECK)|' \ '|SYSTEM_SYSVINIT_PATH=$(sysvinitdir)|' \ diff --git a/units/kmod-static-nodes.service.in b/units/kmod-static-nodes.service.in index f8a2d474ef..624a650526 100644 --- a/units/kmod-static-nodes.service.in +++ b/units/kmod-static-nodes.service.in @@ -12,5 +12,5 @@ Before=sysinit.target systemd-tmpfiles-setup-dev.service [Service] Type=oneshot -ExecStartPre=/usr/bin/mkdir -p /run/tmpfiles.d +ExecStartPre=@MKDIR_P@ /run/tmpfiles.d ExecStart=@KMOD@ static-nodes --format=tmpfiles --output=/run/tmpfiles.d/kmod.conf -- cgit v1.2.1 From b98e3866fddf2edfa13fc1b4323aa84f89336ff2 Mon Sep 17 00:00:00 2001 From: Shawn Landden Date: Fri, 12 Jul 2013 20:57:15 -0700 Subject: journalctl: have a useful --setup-keys error message when using non-persistant logging Generating seed... Generating key pair... Generating sealing key... Failed to open /var/log/journal/33f46101703a10c5fc6fa4f451840101/fss.tmp.k2wDDU: No such file or directory --- src/journal/journalctl.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 7baea237cb..32665b7f78 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -725,6 +725,19 @@ static int setup_keys(void) { char *p = NULL, *k = NULL; struct FSSHeader h; uint64_t n; + struct stat st; + + r = stat("/var/log/journal", &st); + if (r < 0 && errno != ENOENT && errno != ENOTDIR) { + log_error("stat(\"%s\") failed: %m", "/var/log/journal"); + return -errno; + } + + if (r < 0 || !S_ISDIR(st.st_mode)) { + log_error("%s is not a directory, must be using persistent logging for FSS.", + "/var/log/journal"); + return r < 0 ? -errno : -ENOTDIR; + } r = sd_id128_get_machine(&machine); if (r < 0) { -- cgit v1.2.1 From 6a75304e41e4487d840057a0e5f9972e141e4540 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sat, 13 Jul 2013 10:51:35 +0200 Subject: man: wording and grammar update --- man/systemd.cgroup.xml | 30 +++++++++++++++--------------- man/systemd.exec.xml | 2 +- man/systemd.scope.xml | 2 +- man/systemd.socket.xml | 2 +- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/man/systemd.cgroup.xml b/man/systemd.cgroup.xml index 504c9685a5..e31faf522e 100644 --- a/man/systemd.cgroup.xml +++ b/man/systemd.cgroup.xml @@ -78,7 +78,7 @@ along with systemd; If not, see . and systemd.swap5 for more information on the specific unit configuration files. The - execution specific configuration options are configured in the + execution-specific configuration options are configured in the [Slice], [Scope], [Service], [Socket], [Mount], or [Swap] sections, depending on the unit type. @@ -94,7 +94,7 @@ along with systemd; If not, see . CPUAccounting= - Turn on the CPU usage accounting for this + Turn on CPU usage accounting for this unit. @@ -103,7 +103,7 @@ along with systemd; If not, see . BlockIOAccounting= - Turn on the Block IO bandwidth accounting + Turn on Block IO bandwidth accounting for this unit. @@ -112,7 +112,7 @@ along with systemd; If not, see . MemoryAccounting= - Turn on the process and kernel memory + Turn on process and kernel memory accounting for this unit. @@ -126,7 +126,7 @@ along with systemd; If not, see . the processes executed. Takes an integer value. This controls the cpu.shares control group attribute, which defaults to 1024. For details about this - control group attribute see sched-design-CFS.txt. Implies CPUAccounting=true. @@ -145,12 +145,12 @@ along with systemd; If not, see . detects memory contention, memory reclaim will be performed until the memory usage is within the "soft" limit. Takes a memory size in bytes. If the value is suffixed with K, M, G - or T the specified memory size is parsed as Kilobytes, + or T, the specified memory size is parsed as Kilobytes, Megabytes, Gigabytes, or Terabytes (with the base 1024), respectively. This controls the memory.limit_in_bytes and memory.soft_limit_in_bytes control group - attributes. For details about these control group attributes + attributes. For details about these control group attributes, see memory.txt. @@ -170,7 +170,7 @@ along with systemd; If not, see . blkio.weight control group attribute, which defaults to 1000. For details about - this control group attribute see + this control group attribute, see blkio-controller.txt. @@ -190,7 +190,7 @@ along with systemd; If not, see . blkio.weight_device control group attribute, which defaults to 1000. Use this option multiple times to set weights for multiple devices. For details about - this control group attribute see blkio-controller.txt. @@ -206,7 +206,7 @@ along with systemd; If not, see . specify the device specific bandwidth. The file path may be a path to a block device node, or as any other file in which case the backing block device of the file system of the file - is used. If the bandwidth is suffixed with K, M, G, or T + is used. If the bandwidth is suffixed with K, M, G, or T, the specified bandwidth is parsed as Kilobytes, Megabytes, Gigabytes, or Terabytes, respectively (Example: "/dev/disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0 5M"). This @@ -214,7 +214,7 @@ along with systemd; If not, see . blkio.write_bps_device control group attributes. Use this option multiple times to set bandwidth limits for multiple devices. For details about these control - group attributes see + group attributes, see blkio-controller.txt. @@ -230,11 +230,11 @@ along with systemd; If not, see . followed by a combination of r, w, m to control reading, writing, - or creating of the specific device node by the unit + or creation of the specific device node by the unit (mknod), respectively. This controls the devices.allow and devices.deny control group - attributes. For details about these control group attributes + attributes. For details about these control group attributes, see devices.txt. @@ -259,7 +259,7 @@ along with systemd; If not, see . - in addition allows access to standard pseudo + in addition, allows access to standard pseudo devices including /dev/null, /dev/zero, @@ -274,7 +274,7 @@ along with systemd; If not, see . - in addition allows access to all devices if no + in addition, allows access to all devices if no explicit DeviceAllow= is present. This is the default. diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index d299fc0382..c9958340af 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -58,7 +58,7 @@ Description Unit configuration files for services, sockets, - mount points, and swap devices share a subset of + mount points and swap devices share a subset of configuration options which define the execution environment of spawned processes. diff --git a/man/systemd.scope.xml b/man/systemd.scope.xml index 31f2d6f5a5..6cd8c8845a 100644 --- a/man/systemd.scope.xml +++ b/man/systemd.scope.xml @@ -56,7 +56,7 @@ along with systemd; If not, see . A unit configuration file whose name ends in .scope encodes information about a unit created - by systemd to encapsulate processes launched not by systemd + by systemd to encapsulate processes not launched by systemd itself. This management is performed by creating a node in the control group tree. Processes are moved into the scope by means of the DBus API. diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml index fad5c2b8c5..852010bfaa 100644 --- a/man/systemd.socket.xml +++ b/man/systemd.socket.xml @@ -510,7 +510,7 @@ ReusePort= Takes a boolean - value. If true allows multiple bind()s + value. If true, allows multiple bind()s to this TCP or UDP port. This controls the SO_REUSEPORT socket option. See -- cgit v1.2.1 From 92d430a9e03056c0f62ed49149d59aed0046d0dd Mon Sep 17 00:00:00 2001 From: Ross Lagerwall Date: Mon, 17 Jun 2013 19:11:50 +0100 Subject: install: make "reenable" work with templated units Before, "systemctl reenable getty@tty1.service" would fail with: Failed to issue method call: File exists To fix this, reimplement "reenable" explicitly as a disable followed by an enable. This is shorter and is how the man page documents its behavior. --- src/shared/install.c | 38 +++++--------------------------------- 1 file changed, 5 insertions(+), 33 deletions(-) diff --git a/src/shared/install.c b/src/shared/install.c index eb9a5fc0b5..116106824f 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -1534,43 +1534,15 @@ int unit_file_reenable( bool force, UnitFileChange **changes, unsigned *n_changes) { + int r; - _cleanup_lookup_paths_free_ LookupPaths paths = {}; - _cleanup_install_context_done_ InstallContext c = {}; - char **i; - _cleanup_free_ char *config_path = NULL; - _cleanup_set_free_free_ Set *remove_symlinks_to = NULL; - int r, q; - - assert(scope >= 0); - assert(scope < _UNIT_FILE_SCOPE_MAX); - - r = lookup_paths_init_from_scope(&paths, scope); - if (r < 0) - return r; - - r = get_config_path(scope, runtime, root_dir, &config_path); + r = unit_file_disable(scope, runtime, root_dir, files, + changes, n_changes); if (r < 0) return r; - STRV_FOREACH(i, files) { - r = mark_symlink_for_removal(&remove_symlinks_to, *i); - if (r < 0) - return r; - - r = install_info_add_auto(&c, *i); - if (r < 0) - return r; - } - - r = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files); - - /* Returns number of symlinks that where supposed to be installed. */ - q = install_context_apply(&c, &paths, config_path, root_dir, force, changes, n_changes); - if (r == 0) - r = q; - - return r; + return unit_file_enable(scope, runtime, root_dir, files, force, + changes, n_changes); } int unit_file_set_default( -- cgit v1.2.1 From 7aa4fa34f76b0d9b031f0a5ea941c7fa10cebbee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 13 Jul 2013 09:59:35 -0400 Subject: units: do not special-case getty@tty1.service installation Since a long while we can use "systemctl enable getty@tty1.service" which does the right thing, so there's no need to abuse Alias= for installation. --- units/getty@.service.m4 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/units/getty@.service.m4 b/units/getty@.service.m4 index f32ca99ea9..7853652009 100644 --- a/units/getty@.service.m4 +++ b/units/getty@.service.m4 @@ -20,9 +20,9 @@ After=rc-local.service Before=getty.target IgnoreOnIsolate=yes -# On systems without virtual consoles, don't start any getty. (Note +# On systems without virtual consoles, don't start any getty. Note # that serial gettys are covered by serial-getty@.service, not this -# unit +# unit. ConditionPathExists=/dev/tty0 [Service] @@ -48,4 +48,4 @@ Environment=LANG= LANGUAGE= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETA KillSignal=SIGHUP [Install] -Alias=getty.target.wants/getty@tty1.service +WantedBy=getty.target -- cgit v1.2.1 From 6aea6d10f460853111ca8744201ec8dade97de3c Mon Sep 17 00:00:00 2001 From: "Thomas H.P. Andersen" Date: Thu, 28 Mar 2013 14:54:06 +0100 Subject: Add test coverage and generate report with lcov Enable coverage with --enable-coverage. "make coverage" will create the report locally, "make coverage-sync" will upload the report to http://www.freedesktop.org/software/systemd/coverage/. Requires lcov version 1.10 to handle naming in systemd and to use the --no-external option. [zj: make the coverage at least generate something with separate build dir, simplify rules a bit: all errors are mine. ] --- .gitignore | 1 + Makefile.am | 38 ++++++++++++++++++++++++++++++++++++++ configure.ac | 24 ++++++++++++++++++++++++ src/.gitignore | 2 ++ 4 files changed, 65 insertions(+) diff --git a/.gitignore b/.gitignore index 5f9ba906a4..f4f1e45926 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ /busctl /cdrom_id /collect +/coverage/ /gtk-doc.make /hostnamectl /install-tree diff --git a/Makefile.am b/Makefile.am index 2283d05789..9105274c0d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1389,6 +1389,44 @@ test_sched_prio_LDADD = \ libsystemd-core.la \ libsystemd-daemon.la +# ------------------------------------------------------------------------------ +## .PHONY so it always rebuilds it +.PHONY: coverage lcov-run lcov-report + +# run lcov from scratch, always +coverage: + $(MAKE) lcov-run + $(MAKE) lcov-report + +coverage_dir = coverage +coverage_opts = --base-directory $(srcdir) --directory $(builddir) --rc 'geninfo_adjust_src_path=$(abspath $(srcdir))=>$(abspath $(builddir))' + +if ENABLE_COVERAGE +# reset run coverage tests +lcov-run: + @rm -rf $(coverage_dir) + lcov $(coverage_opts) --zerocounters + -$(MAKE) check + +# generate report based on current coverage data +lcov-report: + $(MKDIR_P) $(coverage_dir) + lcov $(coverage_opts) --compat-libtool --capture --no-external \ + | sed 's|$(abspath $(builddir))|$(abspath $(srcdir))|' > $(coverage_dir)/.lcov.info + genhtml -t "systemd test coverage" -o $(coverage_dir) $(coverage_dir)/.lcov.info + @echo "Coverage report generated in $(abs_builddir)/$(coverage_dir)/index.html" + +# lcov doesn't work properly with vpath builds, make sure that bad +# output is not uploaded by mistake. +coverage-sync: coverage + test "$(builddir)" = "$(srcdir)" + rsync -rlv --delete --omit-dir-times coverage/ $(www_target)/coverage + +else +lcov-run lcov-report: + echo "Need to reconfigure with --enable-coverage" +endif + # ------------------------------------------------------------------------------ systemd_initctl_SOURCES = \ src/initctl/initctl.c diff --git a/configure.ac b/configure.ac index 1e196f7307..afbe8e9048 100644 --- a/configure.ac +++ b/configure.ac @@ -214,6 +214,29 @@ m4_pattern_forbid([^_?PKG_[A-Z_]+$],[*** pkg.m4 missing, please install pkg-conf PKG_CHECK_MODULES(DBUS, [dbus-1 >= 1.3.2]) +# ------------------------------------------------------------------------------ +have_coverage=no +AC_ARG_ENABLE(coverage, AS_HELP_STRING([--enable-coverage], [enable test coverage])) +if test "x$enable_coverage" = "xyes" ; then + AC_CHECK_PROG(lcov_found, [lcov], [yes], [no]) + if test "x$lcov_found" = xno ; then + AC_MSG_ERROR([*** lcov support requested but the program was not found]) + else + lcov_version_major="`lcov --version | cut -d ' ' -f 4 | cut -d '.' -f 1`" + lcov_version_minor="`lcov --version | cut -d ' ' -f 4 | cut -d '.' -f 2`" + if test "$lcov_version_major" -eq 1 -a "$lcov_version_minor" -lt 10; then + AC_MSG_ERROR([*** lcov version is too old. 1.10 required]) + else + have_coverage=yes + CC_CHECK_FLAGS_APPEND([with_coverage_cflags], [CFLAGS], [\ + -fprofile-arcs \ + -ftest-coverage]) + AC_SUBST([OUR_CFLAGS], "$with_cflags $with_coverage_cflags") + fi + fi +fi +AM_CONDITIONAL(ENABLE_COVERAGE, [test "$have_coverage" = "yes"]) + # ------------------------------------------------------------------------------ have_kmod=no AC_ARG_ENABLE(kmod, AS_HELP_STRING([--disable-kmod], [disable loadable modules support])) @@ -1000,6 +1023,7 @@ AC_MSG_RESULT([ Python Headers: ${have_python_devel} man pages: ${have_manpages} gtk-doc: ${enable_gtk_doc} + test coverage: ${have_coverage} Split /usr: ${enable_split_usr} SysV compatibility: ${SYSTEM_SYSV_COMPAT} diff --git a/src/.gitignore b/src/.gitignore index afabb6a5d2..e6ac2d7b8a 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -4,3 +4,5 @@ load-fragment-gperf.gperf org.freedesktop.systemd1.policy.in org.freedesktop.systemd1.policy 99-systemd.rules +*.gcno +*.gcda -- cgit v1.2.1 From bf502e636be8f76e05b0334b4e78ea7a398ba241 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 13 Jul 2013 17:36:03 -0400 Subject: test: add trivial test for syscall table and extend table tests to error paths --- src/shared/test-tables.h | 8 +++++--- src/test/test-tables.c | 3 +++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/shared/test-tables.h b/src/shared/test-tables.h index ac7deda39b..deebec2ed2 100644 --- a/src/shared/test-tables.h +++ b/src/shared/test-tables.h @@ -29,15 +29,17 @@ static inline void _test_table(const char *name, int size) { int i; - for (i = 0; i < size; i++) { + for (i = 0; i < size + 1; i++) { const char* val = lookup(i); - int rev = -1; + int rev; if (val) rev = reverse(val); + else + rev = reverse("--no-such--value----"); printf("%s: %d → %s → %d\n", name, i, val, rev); - if (!val || rev != i) + if (i < size ? val == NULL || rev != i : val != NULL || rev != -1) exit(EXIT_FAILURE); } } diff --git a/src/test/test-tables.c b/src/test/test-tables.c index dff6431b6d..9a3d3e8e74 100644 --- a/src/test/test-tables.c +++ b/src/test/test-tables.c @@ -43,6 +43,7 @@ #include "unit-name.h" #include "unit.h" #include "util.h" +#include "syscall-list.h" #include "test-tables.h" @@ -98,5 +99,7 @@ int main(int argc, char **argv) { test_table(unit_load_state, UNIT_LOAD_STATE); test_table(unit_type, UNIT_TYPE); + _test_table("syscall", syscall_to_name, syscall_from_name, syscall_max()); + return EXIT_SUCCESS; } -- cgit v1.2.1 From 3eb1395706ca0a00ac15d59098a0250b0377e6b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 13 Jul 2013 23:36:39 -0400 Subject: man: tweak WantedBy=/RequiredBy= description a bit https://bugs.freedesktop.org/show_bug.cgi?id=55663 --- man/systemd.unit.xml | 45 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index a870f6b17a..a14e452fa3 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -1115,19 +1115,46 @@ WantedBy= RequiredBy= - Installs a symlink in - the .wants/ - or .requires/ - subdirectory for a unit, respectively. This has the - effect that when the listed unit name - is activated the unit listing it is - activated - too. WantedBy=foo.service + A symbolic link is + created in the + .wants/ or + .requires/ folder + of the listed unit when this unit is + activated by systemctl + enable. This has the effect + that a dependency of type + Wants= or + Requires= is added + from the listed unit to the current + unit. The primary result is that the + current unit will be started when the + listed unit is started. See the + description of + Wants= and + Requires= in the + [Unit] section for details. + + WantedBy=foo.service in a service bar.service is mostly equivalent to Alias=foo.service.wants/bar.service - in the same file. + in the same file. In case of template + units, systemctl enable + must be called with an instance name, and + this instance will be added to the + .wants/ or + .requires/ list + of the listed unit. + E.g. WantedBy=getty.target + in a service + getty@.service + will result in systemctl + enable getty@tty2.service + creating a + getty.target.wants/getty@tty2.service + link to getty@.service. + -- cgit v1.2.1 From c79d894d590fc9df4861738555cc43c477e33376 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 15 Jul 2013 00:55:37 +0200 Subject: hwdb: import data --- hwdb/20-OUI.hwdb | 108 ++++++++++++++++++++++++++++++++++++++++-- hwdb/20-pci-vendor-model.hwdb | 68 +++++++++++++++++++++++++- 2 files changed, 172 insertions(+), 4 deletions(-) diff --git a/hwdb/20-OUI.hwdb b/hwdb/20-OUI.hwdb index 8b402f9b4a..fe751ed447 100644 --- a/hwdb/20-OUI.hwdb +++ b/hwdb/20-OUI.hwdb @@ -7295,7 +7295,7 @@ OUI:0050C298C* ID_OUI_FROM_DATABASE=MGM-Devices Oy OUI:0050C298D* - ID_OUI_FROM_DATABASE=Mecos Traxler AG + ID_OUI_FROM_DATABASE=Mecos AG OUI:0050C298E* ID_OUI_FROM_DATABASE=Link Technologies, Inc @@ -13099,6 +13099,36 @@ OUI:40D85512D* OUI:40D85512E* ID_OUI_FROM_DATABASE=Canfield Scientific, Inc. +OUI:40D855130* + ID_OUI_FROM_DATABASE=GSP Sprachtechnologie GmbH + +OUI:40D855131* + ID_OUI_FROM_DATABASE=EMAC, INC. + +OUI:40D855132* + ID_OUI_FROM_DATABASE=AeroVision Avionics, Inc + +OUI:40D855133* + ID_OUI_FROM_DATABASE=Tattile srl + +OUI:40D855134* + ID_OUI_FROM_DATABASE=digitech GmbH & Co. KG + +OUI:40D855135* + ID_OUI_FROM_DATABASE=GLOBALCOM ENGINEERING SRL + +OUI:40D855136* + ID_OUI_FROM_DATABASE=Devriecom B.V. + +OUI:40D855137* + ID_OUI_FROM_DATABASE=GDE Polska + +OUI:40D855138* + ID_OUI_FROM_DATABASE=Calon Associates Limited + +OUI:40D855139* + ID_OUI_FROM_DATABASE=WOW System + OUI:000000* ID_OUI_FROM_DATABASE=XEROX CORPORATION @@ -14675,7 +14705,7 @@ OUI:00020D* ID_OUI_FROM_DATABASE=Micronpc.com OUI:00020E* - ID_OUI_FROM_DATABASE=ECI Telecom, Ltd., NSD-US + ID_OUI_FROM_DATABASE=ECI Telecom, Ltd OUI:00020F* ID_OUI_FROM_DATABASE=AATR @@ -51148,6 +51178,9 @@ OUI:044BFF* OUI:044CEF* ID_OUI_FROM_DATABASE=Fujian Sanao Technology Co.,Ltd +OUI:044F8B* + ID_OUI_FROM_DATABASE=Adapteva, Inc. + OUI:044FAA* ID_OUI_FROM_DATABASE=Ruckus Wireless @@ -52102,6 +52135,9 @@ OUI:0C57EB* OUI:0C5A19* ID_OUI_FROM_DATABASE=Axtion Sdn Bhd +OUI:0C5CD8* + ID_OUI_FROM_DATABASE=DOLI Elektronik GmbH + OUI:0C6076* ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. @@ -52171,6 +52207,9 @@ OUI:0C93FB* OUI:0C96BF* ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd +OUI:0C9B13* + ID_OUI_FROM_DATABASE=Shanghai Magic Mobile Telecommunication Co.Ltd. + OUI:0C9D56* ID_OUI_FROM_DATABASE=Consort Controls Ltd @@ -52924,6 +52963,9 @@ OUI:187A93* OUI:187C81* ID_OUI_FROM_DATABASE=Valeo Vision Systems +OUI:187ED5* + ID_OUI_FROM_DATABASE=shenzhen kaism technology Co. Ltd + OUI:1880CE* ID_OUI_FROM_DATABASE=Barberry Solutions Ltd @@ -53122,6 +53164,9 @@ OUI:1C48F9* OUI:1C4AF7* ID_OUI_FROM_DATABASE=AMON INC +OUI:1C4BB9* + ID_OUI_FROM_DATABASE=SMG ENTERPRISE, LLC + OUI:1C4BD6* ID_OUI_FROM_DATABASE=AzureWave @@ -53608,6 +53653,9 @@ OUI:245FDF* OUI:246278* ID_OUI_FROM_DATABASE=sysmocom - systems for mobile communications GmbH +OUI:2464EF* + ID_OUI_FROM_DATABASE=CYG SUNRI CO.,LTD. + OUI:246511* ID_OUI_FROM_DATABASE=AVM GmbH @@ -53626,6 +53674,9 @@ OUI:24767D* OUI:247703* ID_OUI_FROM_DATABASE=Intel Corporate +OUI:248000* + ID_OUI_FROM_DATABASE=Westcontrol AS + OUI:2481AA* ID_OUI_FROM_DATABASE=KSH International Co., Ltd. @@ -54109,12 +54160,18 @@ OUI:2C44FD* OUI:2C542D* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. +OUI:2C553C* + ID_OUI_FROM_DATABASE=Gainspeed, Inc. + OUI:2C59E5* ID_OUI_FROM_DATABASE=Hewlett Packard OUI:2C5AA3* ID_OUI_FROM_DATABASE=PROMATE ELECTRONIC CO.LTD +OUI:2C5FF3* + ID_OUI_FROM_DATABASE=Pertronic Industries + OUI:2C625A* ID_OUI_FROM_DATABASE=Finest Security Systems Co., Ltd @@ -54526,6 +54583,9 @@ OUI:3451C9* OUI:345B11* ID_OUI_FROM_DATABASE=EVI HEAT AB +OUI:346178* + ID_OUI_FROM_DATABASE=The Boeing Company + OUI:34684A* ID_OUI_FROM_DATABASE=Teraworks Co., Ltd. @@ -54958,6 +55018,9 @@ OUI:3C0FC1* OUI:3C106F* ID_OUI_FROM_DATABASE=ALBAHITH TECHNOLOGIES +OUI:3C15EA* + ID_OUI_FROM_DATABASE=TESCOM CO., LTD. + OUI:3C1915* ID_OUI_FROM_DATABASE=GFI Chrono Time @@ -56284,6 +56347,9 @@ OUI:50AF73* OUI:50B7C3* ID_OUI_FROM_DATABASE=Samsung Electronics CO., LTD +OUI:50B888* + ID_OUI_FROM_DATABASE=wi2be Tecnologia S/A + OUI:50B8A2* ID_OUI_FROM_DATABASE=ImTech Technologies LLC, @@ -56480,7 +56546,7 @@ OUI:54A51B* ID_OUI_FROM_DATABASE=Shenzhen Huawei Communication Technologies Co., Ltd OUI:54A54B* - ID_OUI_FROM_DATABASE=NSC Communiaction Siberia Ltd + ID_OUI_FROM_DATABASE=NSC Communications Siberia Ltd OUI:54A619* ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd @@ -56614,6 +56680,9 @@ OUI:5856E8* OUI:58570D* ID_OUI_FROM_DATABASE=Danfoss Solar Inverters +OUI:58639A* + ID_OUI_FROM_DATABASE=TPL SYSTEMES + OUI:5865E6* ID_OUI_FROM_DATABASE=INFOMARK CO., LTD. @@ -56686,6 +56755,9 @@ OUI:589835* OUI:58986F* ID_OUI_FROM_DATABASE=Revolution Display +OUI:58A2B5* + ID_OUI_FROM_DATABASE=LG Electronics + OUI:58A76F* ID_OUI_FROM_DATABASE=iD corporation @@ -58909,6 +58981,9 @@ OUI:7C0507* OUI:7C051E* ID_OUI_FROM_DATABASE=RAFAEL LTD. +OUI:7C0623* + ID_OUI_FROM_DATABASE=Ultra Electronics, CIS + OUI:7C08D9* ID_OUI_FROM_DATABASE=Shanghai Engineering Research Center for Broadband Technologies and Applications @@ -59422,6 +59497,9 @@ OUI:841715* OUI:841888* ID_OUI_FROM_DATABASE=Juniper Networks +OUI:841B38* + ID_OUI_FROM_DATABASE=Shenzhen Excelsecu Data Technology Co.,Ltd + OUI:841B5E* ID_OUI_FROM_DATABASE=NETGEAR @@ -59689,6 +59767,9 @@ OUI:8841C1* OUI:8843E1* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. +OUI:8844F6* + ID_OUI_FROM_DATABASE=Nokia Corporation + OUI:88462A* ID_OUI_FROM_DATABASE=Telechips Inc. @@ -62410,6 +62491,9 @@ OUI:B439D6* OUI:B43DB2* ID_OUI_FROM_DATABASE=Degreane Horizon +OUI:B43E3B* + ID_OUI_FROM_DATABASE=Viableware, Inc + OUI:B4417A* ID_OUI_FROM_DATABASE=ShenZhen Gongjin Electronics Co.,Ltd @@ -64714,6 +64798,9 @@ OUI:D824BD* OUI:D826B9* ID_OUI_FROM_DATABASE=Guangdong Coagent Electronics S &T Co., Ltd. +OUI:D8270C* + ID_OUI_FROM_DATABASE=MaxTronic International Co., Ltd. + OUI:D828C9* ID_OUI_FROM_DATABASE=General Electric Consumer and Industrial @@ -65134,6 +65221,9 @@ OUI:DCF858* OUI:DCFAD5* ID_OUI_FROM_DATABASE=STRONG Ges.m.b.H. +OUI:DCFB02* + ID_OUI_FROM_DATABASE=Buffalo Inc. + OUI:E005C5* ID_OUI_FROM_DATABASE=TP-LINK Technologies Co.,Ltd. @@ -65920,6 +66010,9 @@ OUI:EC233D* OUI:EC2368* ID_OUI_FROM_DATABASE=IntelliVoice Co.,Ltd. +OUI:EC2AF0* + ID_OUI_FROM_DATABASE=Ypsomed AG + OUI:EC2C49* ID_OUI_FROM_DATABASE=University of Tokyo @@ -66703,6 +66796,9 @@ OUI:F8472D* OUI:F84897* ID_OUI_FROM_DATABASE=Hitachi, Ltd. +OUI:F84A7F* + ID_OUI_FROM_DATABASE=Innometriks Inc + OUI:F84ABF* ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD @@ -66718,6 +66814,9 @@ OUI:F8516D* OUI:F852DF* ID_OUI_FROM_DATABASE=VNL Europe AB +OUI:F854AF* + ID_OUI_FROM_DATABASE=ECI Telecom Ltd. + OUI:F85BC9* ID_OUI_FROM_DATABASE=M-Cube Spa @@ -66787,6 +66886,9 @@ OUI:F89FB8* OUI:F8A03D* ID_OUI_FROM_DATABASE=Dinstar Technologies Co., Ltd. +OUI:F8A45F* + ID_OUI_FROM_DATABASE=Beijing Xiaomi communications co.,ltd + OUI:F8A9DE* ID_OUI_FROM_DATABASE=PUISSANCE PLUS diff --git a/hwdb/20-pci-vendor-model.hwdb b/hwdb/20-pci-vendor-model.hwdb index de0b27cb37..45b25cdd4f 100644 --- a/hwdb/20-pci-vendor-model.hwdb +++ b/hwdb/20-pci-vendor-model.hwdb @@ -1898,6 +1898,9 @@ pci:v00001002d00004242* pci:v00001002d00004242sv00001002sd000002AA* ID_MODEL_FROM_DATABASE=Radeon 8500 AIW DV Edition +pci:v00001002d00004243* + ID_MODEL_FROM_DATABASE=R200 PCI Bridge [All-in-Wonder Radeon 8500DV] + pci:v00001002d00004336* ID_MODEL_FROM_DATABASE=RS100 [Radeon IGP 320M] @@ -8372,6 +8375,45 @@ pci:v00001002d00009552sv0000174Bsd00003000* pci:v00001002d00009553* ID_MODEL_FROM_DATABASE=RV710/M92 [Mobility Radeon HD 4530/4570/545v] +pci:v00001002d00009553sv00001025sd0000015E* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 4570 + +pci:v00001002d00009553sv00001025sd0000017D* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 4570 + +pci:v00001002d00009553sv00001025sd00000205* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 4570 + +pci:v00001002d00009553sv00001025sd00000206* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 4570 + +pci:v00001002d00009553sv00001025sd00000237* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 4570 + +pci:v00001002d00009553sv00001028sd000002BE* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 4570 + +pci:v00001002d00009553sv00001028sd000002E8* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 4530 + +pci:v00001002d00009553sv0000103Csd00003624* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 4530 + +pci:v00001002d00009553sv0000103Csd00003628* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 4530 + +pci:v00001002d00009553sv0000103Csd00003636* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 4530 + +pci:v00001002d00009553sv00001043sd00001B32* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 4570 + +pci:v00001002d00009553sv00001043sd00001B42* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 4570 + +pci:v00001002d00009553sv0000104Dsd00009056* + ID_MODEL_FROM_DATABASE=Mobility Radeon HD 4570 + pci:v00001002d00009553sv00001179sd0000FF82* ID_MODEL_FROM_DATABASE=Satellite L505-13T GPU (Mobility Radeon HD 5145) @@ -10904,6 +10946,12 @@ pci:v00001022d00007813* pci:v00001022d00007814* ID_MODEL_FROM_DATABASE=FCH USB XHCI Controller +pci:v00001022d00007900* + ID_MODEL_FROM_DATABASE=CZ SATA Controller [IDE mode] + +pci:v00001022d0000790B* + ID_MODEL_FROM_DATABASE=CZ SMBus Controller + pci:v00001022d00009600* ID_MODEL_FROM_DATABASE=RS780 Host Bridge @@ -43791,7 +43839,7 @@ pci:v000014E4d00004720* ID_MODEL_FROM_DATABASE=BCM4712 MIPS CPU pci:v000014E4d00004727* - ID_MODEL_FROM_DATABASE=BCM4313 802.11b/g/n Wireless LAN Controller + ID_MODEL_FROM_DATABASE=BCM4313 802.11bgn Wireless Network Adapter pci:v000014E4d00004727sv00001028sd00000010* ID_MODEL_FROM_DATABASE=Inspiron M5010 / XPS 8300 @@ -50384,6 +50432,21 @@ pci:v00001AE8d00000A44* pci:v00001AE8d00000E44* ID_MODEL_FROM_DATABASE=microEnable IV-GigE x4 +pci:v00001AE9* + ID_VENDOR_FROM_DATABASE=Wilocity Ltd. + +pci:v00001AE9d00000101* + ID_MODEL_FROM_DATABASE=Wil6200 PCI Express Root Port + +pci:v00001AE9d00000200* + ID_MODEL_FROM_DATABASE=Wil6200 PCI Express Port + +pci:v00001AE9d00000201* + ID_MODEL_FROM_DATABASE=Wil6200 Wireless PCI Express Port + +pci:v00001AE9d00000301* + ID_MODEL_FROM_DATABASE=Wil6200 802.11ad Wireless Network Adapter + pci:v00001AEC* ID_VENDOR_FROM_DATABASE=Wolfson Microelectronics @@ -50663,6 +50726,9 @@ pci:v00001BB0* pci:v00001BB0d00000002* ID_MODEL_FROM_DATABASE=OmniCube Accelerator OA-3000 +pci:v00001BB0d00000010* + ID_MODEL_FROM_DATABASE=OmniCube Accelerator OA-3000-2 + pci:v00001BB3* ID_VENDOR_FROM_DATABASE=Bluecherry -- cgit v1.2.1 From aedc2eddd16e48d468e6ad0aea2caf00c7d37365 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 15 Jul 2013 00:56:18 +0200 Subject: hwdb: keyboard update --- hwdb/60-keyboard.hwdb | 1242 ++++++++++++++++++++++++------------------------- 1 file changed, 621 insertions(+), 621 deletions(-) diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index 94357e7748..dae8c85310 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -42,199 +42,303 @@ # To debug key presses and access scan code mapping data of # an input device use the commonly available tool: evtest(1). -########################################################### -# Logitech -########################################################### +########################################## +# Acer +########################################## -# Logitech Cordless Wave Pro -keyboard:usb:v046DpC52[9b]* - KEYBOARD_KEY_0c01b6=camera - KEYBOARD_KEY_0c0183=media - KEYBOARD_KEY_0c0184=wordprocessor - KEYBOARD_KEY_0c0186=spreadsheet - KEYBOARD_KEY_0c018e=calendar - KEYBOARD_KEY_0c0223=homepage - KEYBOARD_KEY_0c01bc=messenger - KEYBOARD_KEY_0c018a=mail - KEYBOARD_KEY_0c0221=search - KEYBOARD_KEY_0c00b8=ejectcd - KEYBOARD_KEY_0c022d=zoomin - KEYBOARD_KEY_0c022e=zoomout +# Acer platform kernel driver +keyboard:name:Acer WMI hotkeys:dmi:bvn*:bvr*:bd*:svn*:pnAcer*:pvr* + KEYBOARD_KEY_82=f21 -########################################################### -# Lenovo -########################################################### +# Aspire 5720 +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire 5720*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnZG8*:pvr* + KEYBOARD_KEY_84=bluetooth # sent when bluetooth module missing, and key pressed + KEYBOARD_KEY_92=media # Acer arcade + KEYBOARD_KEY_d4=bluetooth # Bluetooth on + KEYBOARD_KEY_d9=bluetooth # Bluetooth off + KEYBOARD_KEY_f4=prog3 # e-key -# thinkpad_acpi driver -keyboard:name:ThinkPad Extra Buttons:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn* - KEYBOARD_KEY_01=screenlock - KEYBOARD_KEY_02=battery - KEYBOARD_KEY_03=sleep - KEYBOARD_KEY_04=wlan - KEYBOARD_KEY_06=switchvideomode - KEYBOARD_KEY_07=f21 - KEYBOARD_KEY_08=f24 - KEYBOARD_KEY_0b=suspend - KEYBOARD_KEY_0f=brightnessup - KEYBOARD_KEY_10=brightnessdown - KEYBOARD_KEY_11=kbdillumtoggle - KEYBOARD_KEY_13=zoom - KEYBOARD_KEY_14=volumeup - KEYBOARD_KEY_15=volumedown - KEYBOARD_KEY_16=mute - KEYBOARD_KEY_17=prog1 - KEYBOARD_KEY_1a=f20 +# Aspire 5920g +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire 5920G:* + KEYBOARD_KEY_8a=media + KEYBOARD_KEY_92=media + KEYBOARD_KEY_a6=setup + KEYBOARD_KEY_b2=www + KEYBOARD_KEY_d9=bluetooth # (toggle) on-to-off -# -keyboard:name:Ideapad extra buttons:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn* - KEYBOARD_KEY_42=f23 - KEYBOARD_KEY_43=f22 +# Aspire 6920 +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire 6920:* + KEYBOARD_KEY_d9=bluetooth # (toggle) on-to-off + KEYBOARD_KEY_92=media + KEYBOARD_KEY_9e=back + KEYBOARD_KEY_83=rewind + KEYBOARD_KEY_89=fastforward -# ThinkPad Keyboard with TrackPoint -keyboard:usb:v17EFp6009* - KEYBOARD_KEY_090012=screenlock # Fn+F2 - KEYBOARD_KEY_090013=battery # Fn+F3 - KEYBOARD_KEY_090014=wlan # Fn+F5 - KEYBOARD_KEY_090016=switchvideomode # Fn+F7 - KEYBOARD_KEY_090017=f21 # Fn+F8 touchpad toggle - KEYBOARD_KEY_090019=suspend # Fn+F12 - KEYBOARD_KEY_09001a=brightnessup # Fn+Home - KEYBOARD_KEY_09001b=brightnessdown # Fn+End - KEYBOARD_KEY_09001d=zoom # Fn+Space - KEYBOARD_KEY_090011=prog1 # ThinkVantage button - KEYBOARD_KEY_090015=camera # Fn+F6 headset/camera VoIP key ?? - KEYBOARD_KEY_090010=f20 # Microphone mute button; should be micmute +# Aspire 8930 +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire 8930:* + KEYBOARD_KEY_ca=prog3 # key 'HOLD' on CineDash Media Console + KEYBOARD_KEY_83=rewind + KEYBOARD_KEY_89=fastforward + KEYBOARD_KEY_92=media # key 'ARCADE' on CineDash Media Console + KEYBOARD_KEY_9e=back -# Lenovo 3000 -keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*3000*:pvr* - KEYBOARD_KEY_8b=switchvideomode # Fn+F7 video - KEYBOARD_KEY_96=wlan # Fn+F5 wireless - KEYBOARD_KEY_97=sleep # Fn+F4 suspend - KEYBOARD_KEY_98=suspend # Fn+F12 hibernate - KEYBOARD_KEY_b4=prog1 # Lenovo Care +# Travelmate C300 +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*C3[01]0*:pvr* + KEYBOARD_KEY_67=f24 # FIXME: rotate screen + KEYBOARD_KEY_68=up + KEYBOARD_KEY_69=down + KEYBOARD_KEY_6b=fn + KEYBOARD_KEY_6c=screenlock # FIXME: lock tablet device/buttons -# lenovo-ideapad -keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pnS10-*:pvr* - KEYBOARD_KEY_81=rfkill # does nothing in BIOS - KEYBOARD_KEY_83=display_off # BIOS toggles screen state - KEYBOARD_KEY_b9=brightnessup # does nothing in BIOS - KEYBOARD_KEY_ba=brightnessdown # does nothing in BIOS - KEYBOARD_KEY_f1=camera # BIOS toggles camera power - KEYBOARD_KEY_f2=f21 # touchpad toggle (key alternately emits F2 and F3) - KEYBOARD_KEY_f3=f21 +# +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pn* +keyboard:dmi:bvn*:bvr*:bd*:svnGateway*:pnA0A1*:pvr* + KEYBOARD_KEY_a5=help # Fn+F1 + KEYBOARD_KEY_a6=setup # Fn+F2 Acer eSettings + KEYBOARD_KEY_a7=battery # Fn+F3 Power Management + KEYBOARD_KEY_a9=switchvideomode # Fn+F5 + KEYBOARD_KEY_b3=euro + KEYBOARD_KEY_b4=dollar + KEYBOARD_KEY_ce=brightnessup # Fn+Right + KEYBOARD_KEY_d4=bluetooth # (toggle) off-to-on + KEYBOARD_KEY_d5=wlan # (toggle) on-to-off + KEYBOARD_KEY_d6=wlan # (toggle) off-to-on + KEYBOARD_KEY_d7=bluetooth # (toggle) on-to-off + KEYBOARD_KEY_d8=bluetooth # (toggle) off-to-on + KEYBOARD_KEY_d9=brightnessup # Fn+Right + KEYBOARD_KEY_ee=brightnessup # Fn+Right + KEYBOARD_KEY_ef=brightnessdown # Fn+Left + KEYBOARD_KEY_f1=f22 # Fn+F7 Touchpad toggle (off-to-on) + KEYBOARD_KEY_f2=f23 # Fn+F7 Touchpad toggle (on-to-off) + KEYBOARD_KEY_f3=prog2 # "P2" programmable button + KEYBOARD_KEY_f4=prog1 # "P1" programmable button + KEYBOARD_KEY_f5=presentation + KEYBOARD_KEY_f8=fn + KEYBOARD_KEY_f9=f23 # Launch NTI shadow -# Thinkpad X200_Tablet -keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pnThinkPad X2* Tablet*:pvr* - KEYBOARD_KEY_5d=menu - KEYBOARD_KEY_63=fn - KEYBOARD_KEY_66=screenlock - KEYBOARD_KEY_67=cyclewindows # bezel circular arrow - KEYBOARD_KEY_68=setup # bezel setup / menu - KEYBOARD_KEY_6c=direction # rotate screen +# +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5210*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5220*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5610*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5620*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5720*:pvr* + KEYBOARD_KEY_ee=screenlock -# ThinkPad X6 Tablet -keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pnThinkPad X6*:pvr* - KEYBOARD_KEY_6c=f21 # rotate - KEYBOARD_KEY_68=screenlock # screenlock - KEYBOARD_KEY_6b=esc # escape - KEYBOARD_KEY_6d=right # right on d-pad - KEYBOARD_KEY_6e=left # left on d-pad - KEYBOARD_KEY_71=up # up on d-pad - KEYBOARD_KEY_6f=down # down on d-pad - KEYBOARD_KEY_69=enter # enter on d-pad +# +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*6292*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*8471*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*4720*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*7720*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire 1810T*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAO751h:* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAO531h:* + KEYBOARD_KEY_d9=bluetooth -# IdeaPad -keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad Y550*:pvr* - KEYBOARD_KEY_95=media - KEYBOARD_KEY_a3=play +# +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*4720*:pvr* + KEYBOARD_KEY_b2=www + KEYBOARD_KEY_ee=screenlock -# V480 -keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*Lenovo V480*:pvr* - KEYBOARD_KEY_f1=f21 +# +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate 6593:* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire 1640:* + KEYBOARD_KEY_b2=www + KEYBOARD_KEY_ee=screenlock" -# IdeaPad -keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad U300s*:pvr* - KEYBOARD_KEY_f1=f21 - KEYBOARD_KEY_ce=f20 +########################################################### +# Alienware +########################################################### + +keyboard:dmi:bvn*:bvr*:bd*:svnAlienware*:pn* + KEYBOARD_KEY_8a=ejectcd ########################################################### -# IBM +# Asus ########################################################### -# thinkpad_acpi driver -keyboard:name:ThinkPad Extra Buttons:dmi:bvn*:bvr*:bd*:svnIBM*:pn*:pvr* - KEYBOARD_KEY_01=battery # Fn+F2 - KEYBOARD_KEY_02=screenlock # Fn+F3 - KEYBOARD_KEY_03=sleep # Fn+F4 - KEYBOARD_KEY_04=wlan # Fn+F5 - KEYBOARD_KEY_06=switchvideomode # Fn+F7 - KEYBOARD_KEY_07=zoom # Fn+F8 screen expand - KEYBOARD_KEY_08=f24 # Fn+F9 undock - KEYBOARD_KEY_0b=suspend # Fn+F12 - KEYBOARD_KEY_0f=brightnessup # Fn+Home - KEYBOARD_KEY_10=brightnessdown # Fn+End - KEYBOARD_KEY_11=kbdillumtoggle # Fn+PgUp - ThinkLight - KEYBOARD_KEY_13=zoom # Fn+Space - KEYBOARD_KEY_14=volumeup - KEYBOARD_KEY_15=volumedown - KEYBOARD_KEY_16=mute - KEYBOARD_KEY_17=prog1 # ThinkPad/ThinkVantage button (high keycode: "vendor") +keyboard:dmi:bvn*:bvr*:bd*:svnASUS:* + KEYBOARD_KEY_ed=volumeup + KEYBOARD_KEY_ee=volumedown + KEYBOARD_KEY_ef=mute -# IBM Thinkpad USB Keyboard Trackpoint -usb:v04B3p301[89]* - KEYBOARD_KEY_900f0=screenlock - KEYBOARD_KEY_900f1=wlan - KEYBOARD_KEY_900f2=switchvideomode - KEYBOARD_KEY_900f3=suspend - KEYBOARD_KEY_900f4=brightnessup - KEYBOARD_KEY_900f5=brightnessdown - KEYBOARD_KEY_900f8=zoom +########################################################### +# BenQ +########################################################### + +keyboard:dmi:bvn*:bvr*:bd*:svn*BenQ*:pn*Joybook R22*:pvr* + KEYBOARD_KEY_6e=wlan ########################################################### -# SONY +# Compal ########################################################### -# sony-laptop driver -keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn* - KEYBOARD_KEY_06=mute # Fn+F2 - KEYBOARD_KEY_07=volumedown # Fn+F3 - KEYBOARD_KEY_08=volumeup # Fn+F4 - KEYBOARD_KEY_09=brightnessdown # Fn+F5 - KEYBOARD_KEY_0a=brightnessup # Fn+F6 - KEYBOARD_KEY_0b=switchvideomode # Fn+F7 - KEYBOARD_KEY_0e=zoom # Fn+F10 - KEYBOARD_KEY_10=suspend # Fn+F12 +keyboard:dmi:bvn*:bvr*:bd*:svnCOMPAL:pnHEL80I:* + KEYBOARD_KEY_84=wlan -keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-C1*:pvr* -keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-K25*:pvr* -keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-F[1-6]*:pvr* -keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-FX*:pvr* -keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-FRV*:pvr* -keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-GR*:pvr* -keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-TR*:pvr* -keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-NV*:pvr* -keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-Z*:pvr* -keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*VGN-S360*:pvr* - KEYBOARD_KEY_06=battery - KEYBOARD_KEY_07=mute +########################################################### +# COMPAQ +########################################################### -keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVGN-AR71*:pvr* -keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVGN-FW*:pvr* -keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVGN-Z21*:pvr* - KEYBOARD_KEY_00=brightnessdown # Fn+F5 - KEYBOARD_KEY_10=brightnessup # Fn+F6 - KEYBOARD_KEY_11=switchvideomode # Fn+F7 - KEYBOARD_KEY_12=zoomout - KEYBOARD_KEY_14=zoomin - KEYBOARD_KEY_15=suspend # Fn+F12 - KEYBOARD_KEY_17=prog1 - KEYBOARD_KEY_20=media +keyboard:dmi:bvn*:bvr*:bd*:svnCompaq*:pn*E500*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnCompaq*:pn*Evo N*:pvr* + KEYBOARD_KEY_a3=www # I key + KEYBOARD_KEY_9a=search + KEYBOARD_KEY_9e=email + KEYBOARD_KEY_9f=homepage -keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVPC*:pvr* - KEYBOARD_KEY_05=f21 # Fn+F1 -> KEY_F21 (The actual touchpad toggle) - KEYBOARD_KEY_0d=zoomout # Fn+F9 - KEYBOARD_KEY_0e=zoomin # Fn+F10 +########################################################### +# Dell +########################################################### + +keyboard:dmi:bvn*:bvr*:bd*:svnDell:pvr* + KEYBOARD_KEY_81=playpause # Play/Pause + KEYBOARD_KEY_82=stopcd # Stop + KEYBOARD_KEY_83=previoussong # Previous song + KEYBOARD_KEY_84=nextsong # Next song + KEYBOARD_KEY_85=brightnessdown # Fn+Down Brightness Down + KEYBOARD_KEY_86=brightnessup # Fn+Up Brightness Up + KEYBOARD_KEY_87=battery # Fn+F3 battery icon + KEYBOARD_KEY_88=unknown # Fn+F2 Turn On/Off Wireless - handled in hardware + KEYBOARD_KEY_89=ejectclosecd # Fn+F10 Eject CD + KEYBOARD_KEY_8a=suspend # Fn+F1 hibernate + KEYBOARD_KEY_8b=switchvideomode # Fn+F8 CRT/LCD (high keycode: "displaytoggle") + KEYBOARD_KEY_8c=f23 # Fn+Right Auto Brightness + KEYBOARD_KEY_8F=switchvideomode # Fn+F7 aspect ratio + KEYBOARD_KEY_90=previoussong # Front panel previous song + KEYBOARD_KEY_91=prog1 # Wi-Fi Catcher (Dell-specific) + KEYBOARD_KEY_92=media # MediaDirect button (house icon) + KEYBOARD_KEY_93=f23 # FIXME Fn+Left Auto Brightness + KEYBOARD_KEY_95=camera # Shutter button - Takes a picture if optional camera available + KEYBOARD_KEY_97=email # Tablet email button + KEYBOARD_KEY_98=f21 # FIXME: Tablet screen rotation + KEYBOARD_KEY_99=nextsong # Front panel next song + KEYBOARD_KEY_9a=setup # Tablet tools button + KEYBOARD_KEY_9b=switchvideomode # Display toggle button + KEYBOARD_KEY_9e=f21 # Touchpad toggle + KEYBOARD_KEY_a2=playpause # Front panel play/pause + KEYBOARD_KEY_a4=stopcd # Front panel stop + KEYBOARD_KEY_ed=media # MediaDirect button + KEYBOARD_KEY_d8=screenlock # FIXME: Tablet lock button + KEYBOARD_KEY_d9=f21 # Touchpad toggle + +# +keyboard:dmi:bvn*:bvr*:bd*:svnDell:pnInspiron 910:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDell:pnInspiron 101[012]:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDell:pnInspiron 1110:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDell:pnInspiron 1210:pvr* + KEYBOARD_KEY_84=wlan + +# Latitude XT2 +keyboard:dmi:bvn*:bvr*:bd*:svnDell:pnLatitude XT2:pvr* + KEYBOARD_KEY_9b=up # tablet rocker up + KEYBOARD_KEY_9e=enter # tablet rocker press + KEYBOARD_KEY_9f=back # tablet back + KEYBOARD_KEY_a3=down # tablet rocker down + +keyboard:dmi:bvn*:bvr*:bd*:svnDell Inc.:pnStudio 155[78]:pvr* + KEYBOARD_KEY_a0=! # mute + KEYBOARD_KEY_ae=! # volume down + KEYBOARD_KEY_b0=! # volume up + +# Dell Touchpad +keyboard:dmi:bvn*:bvr*:bd*:svnDell Inc.:pn:*Latitude*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDell Inc.:pn:*Precision*:pvr* + KEYBOARD_KEY_9e=! + +# Dell XPS +keyboard:dmi:bvn*:bvr*:bd*:svnDell Inc.:pnXPS*:pvr* + KEYBOARD_KEY_8c=! + +########################################################### +# Everex +########################################################### + +keyboard:dmi:bvn*:bvr*:bd*:svnEverex:pnXT5000*:pvr* + KEYBOARD_KEY_5c=media + KEYBOARD_KEY_65=f21 # Fn+F5 Touchpad toggle + KEYBOARD_KEY_67=prog3 # Fan speed control button + KEYBOARD_KEY_6f=brightnessup + KEYBOARD_KEY_7f=brightnessdown + KEYBOARD_KEY_b2=www + KEYBOARD_KEY_ec=mail + +########################################## +# Fujitsu +########################################## + +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pnAMILO*M*:pvr* + KEYBOARD_KEY_97=prog2 + KEYBOARD_KEY_9f=prog1 + +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pnAmilo Li 1718:* + KEYBOARD_KEY_d6=wlan + +# Amilo Li 2732 +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pnAMILO Li 2732:* + KEYBOARD_KEY_d9=brightnessdown # Fn+F8 brightness down + KEYBOARD_KEY_ef=brightnessup # Fn+F9 brightness up + KEYBOARD_KEY_a9=switchvideomode # Fn+F10 Cycle between available video outputs + +# Amilo Pa 2548 +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*AMILO Pa 2548*:pvr* + KEYBOARD_KEY_e0=volumedown + KEYBOARD_KEY_e1=volumeup + KEYBOARD_KEY_e5=prog1 + +# Amilo Pro Edition V3505 +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*AMILO Pro Edition V3505*:pvr* + KEYBOARD_KEY_a5=help # Fn+F1 + KEYBOARD_KEY_a9=switchvideomode # Fn+F3 + KEYBOARD_KEY_d9=brightnessdown # Fn+F8 + KEYBOARD_KEY_e0=brightnessup # Fn+F9 + +# Amilo Pro v3205 +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*AMILO Pro V3205*:pvr* + KEYBOARD_KEY_f4=f21 # FIXME: silent-mode decrease CPU/GPU clock + KEYBOARD_KEY_f7=switchvideomode # Fn+F3 + +# Amilo Si 1520 +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*Amilo Si 1520*:pvr* + KEYBOARD_KEY_e1=wlan + KEYBOARD_KEY_f3=wlan + KEYBOARD_KEY_ee=brightnessdown + KEYBOARD_KEY_e0=brightnessup + KEYBOARD_KEY_e2=bluetooth + KEYBOARD_KEY_f7=video + +# Esprimo Mobile V5 +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*ESPRIMO Mobile V5*:pvr* + KEYBOARD_KEY_a9=switchvideomode + KEYBOARD_KEY_d9=brightnessdown + KEYBOARD_KEY_df=sleep + KEYBOARD_KEY_ef=brightnessup + +# Esprimo Mobile V6 +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*ESPRIMO Mobile V6*:pvr* + KEYBOARD_KEY_ce=brightnessup + KEYBOARD_KEY_ef=brightnessdown + +########################################################### +# Genius +########################################################### + +# Slimstar 320 +keyboard:usb:v0458p0708d*dc*dsc*dp*ic*isc*ip*in01* + KEYBOARD_KEY_0900f0=scrollup + KEYBOARD_KEY_0900f1=scrolldown + KEYBOARD_KEY_0900f3=back + KEYBOARD_KEY_0900f2=forward + KEYBOARD_KEY_0900f5=wordprocessor + KEYBOARD_KEY_0900f6=spreadsheet + KEYBOARD_KEY_0900f4=presentation + KEYBOARD_KEY_0c0223=www + KEYBOARD_KEY_0900f7=chat + KEYBOARD_KEY_0900fb=prog1 + KEYBOARD_KEY_0900f8=close + KEYBOARD_KEY_0900f9=graphicseditor + KEYBOARD_KEY_0900fd=scale + KEYBOARD_KEY_0900fc=screenlock ########################################################### # Hewlett Packard @@ -321,347 +425,203 @@ keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHDX9494NR:pvr* KEYBOARD_KEY_d9=!f22 # touchpad on ########################################################### -# COMPAQ -########################################################### - -keyboard:dmi:bvn*:bvr*:bd*:svnCompaq*:pn*E500*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnCompaq*:pn*Evo N*:pvr* - KEYBOARD_KEY_a3=www # I key - KEYBOARD_KEY_9a=search - KEYBOARD_KEY_9e=email - KEYBOARD_KEY_9f=homepage - -########################################################### -# Samsung -########################################################### - -keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pvr* - KEYBOARD_KEY_74=prog1 # User key - KEYBOARD_KEY_75=www - KEYBOARD_KEY_78=mail - KEYBOARD_KEY_82=!switchvideomode # Fn+F4 CRT/LCD (high keycode: "displaytoggle") - KEYBOARD_KEY_83=!battery # Fn+F2 - KEYBOARD_KEY_84=!prog1 # Fn+F5 backlight on/off - KEYBOARD_KEY_86=!wlan # Fn+F9 - KEYBOARD_KEY_88=!brightnessup # Fn+Up - KEYBOARD_KEY_89=!brightnessdown # Fn+Down - KEYBOARD_KEY_b1=!prog2 # Fn+F7 run Samsung Magic Doctor (keypressed event is generated twice) - KEYBOARD_KEY_b3=!prog3 # Fn+F8 switch power mode (battery/dynamic/performance) - KEYBOARD_KEY_b4=!wlan # Fn+F9 (X60P) - KEYBOARD_KEY_f7=!f22 # Fn+F10 Touchpad on - KEYBOARD_KEY_f9=!f23 # Fn+F10 Touchpad off - -# Series 3 -keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*300E[457]*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*200E[45]*:pvr* - KEYBOARD_KEY_ce=! # Fn+F1 launch control setting - KEYBOARD_KEY_d5=! # Fn+F12 Wi-Fi toggle - -# Series 9 -keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*90X3A*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*900X[34]*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*900XC3*:pvr* - KEYBOARD_KEY_ce=! # Fn+F8 keyboard backlight up - KEYBOARD_KEY_8d=! # Fn+F7 keyboard backlight down - KEYBOARD_KEY_96=! # Fn+F1 performance mode (?) - KEYBOARD_KEY_97=! # Fn+F12 Wi-Fi toggle - KEYBOARD_KEY_d5=! # Fn+F6 battery life extender - -# SQ1US -keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pnSQ1US:pvr* - KEYBOARD_KEY_d4=menu - KEYBOARD_KEY_d8=f1 - KEYBOARD_KEY_d9=f10 - KEYBOARD_KEY_d6=f3 - KEYBOARD_KEY_d7=f9 - KEYBOARD_KEY_e4=f5 - KEYBOARD_KEY_ee=f11 - -# SX20S -keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*SX20S*:pvr* - KEYBOARD_KEY_74=mute - KEYBOARD_KEY_75=mute - KEYBOARD_KEY_77=f22 # Touchpad on - KEYBOARD_KEY_79=f23 # Touchpad off - -keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700Z*:pvr* - KEYBOARD_KEY_ba=ejectcd - KEYBOARD_KEY_96=keyboardbrightnessup - KEYBOARD_KEY_97=keyboardbrightnessdown - -keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700T*:pvr* - KEYBOARD_KEY_ad=leftmeta - -########################################################### -# Dell +# IBM ########################################################### -keyboard:dmi:bvn*:bvr*:bd*:svnDell:pvr* - KEYBOARD_KEY_81=playpause # Play/Pause - KEYBOARD_KEY_82=stopcd # Stop - KEYBOARD_KEY_83=previoussong # Previous song - KEYBOARD_KEY_84=nextsong # Next song - KEYBOARD_KEY_85=brightnessdown # Fn+Down Brightness Down - KEYBOARD_KEY_86=brightnessup # Fn+Up Brightness Up - KEYBOARD_KEY_87=battery # Fn+F3 battery icon - KEYBOARD_KEY_88=unknown # Fn+F2 Turn On/Off Wireless - handled in hardware - KEYBOARD_KEY_89=ejectclosecd # Fn+F10 Eject CD - KEYBOARD_KEY_8a=suspend # Fn+F1 hibernate - KEYBOARD_KEY_8b=switchvideomode # Fn+F8 CRT/LCD (high keycode: "displaytoggle") - KEYBOARD_KEY_8c=f23 # Fn+Right Auto Brightness - KEYBOARD_KEY_8F=switchvideomode # Fn+F7 aspect ratio - KEYBOARD_KEY_90=previoussong # Front panel previous song - KEYBOARD_KEY_91=prog1 # Wi-Fi Catcher (Dell-specific) - KEYBOARD_KEY_92=media # MediaDirect button (house icon) - KEYBOARD_KEY_93=f23 # FIXME Fn+Left Auto Brightness - KEYBOARD_KEY_95=camera # Shutter button - Takes a picture if optional camera available - KEYBOARD_KEY_97=email # Tablet email button - KEYBOARD_KEY_98=f21 # FIXME: Tablet screen rotation - KEYBOARD_KEY_99=nextsong # Front panel next song - KEYBOARD_KEY_9a=setup # Tablet tools button - KEYBOARD_KEY_9b=switchvideomode # Display toggle button - KEYBOARD_KEY_9e=f21 # Touchpad toggle - KEYBOARD_KEY_a2=playpause # Front panel play/pause - KEYBOARD_KEY_a4=stopcd # Front panel stop - KEYBOARD_KEY_ed=media # MediaDirect button - KEYBOARD_KEY_d8=screenlock # FIXME: Tablet lock button - KEYBOARD_KEY_d9=f21 # Touchpad toggle - -# -keyboard:dmi:bvn*:bvr*:bd*:svnDell:pnInspiron 910:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnDell:pnInspiron 101[012]:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnDell:pnInspiron 1110:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnDell:pnInspiron 1210:pvr* - KEYBOARD_KEY_84=wlan - -# Latitude XT2 -keyboard:dmi:bvn*:bvr*:bd*:svnDell:pnLatitude XT2:pvr* - KEYBOARD_KEY_9b=up # tablet rocker up - KEYBOARD_KEY_9e=enter # tablet rocker press - KEYBOARD_KEY_9f=back # tablet back - KEYBOARD_KEY_a3=down # tablet rocker down - -keyboard:dmi:bvn*:bvr*:bd*:svnDell Inc.:pnStudio 155[78]:pvr* - KEYBOARD_KEY_a0=! # mute - KEYBOARD_KEY_ae=! # volume down - KEYBOARD_KEY_b0=! # volume up - -# Dell Touchpad -keyboard:dmi:bvn*:bvr*:bd*:svnDell Inc.:pn:*Latitude*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnDell Inc.:pn:*Precision*:pvr* - KEYBOARD_KEY_9e=! +# thinkpad_acpi driver +keyboard:name:ThinkPad Extra Buttons:dmi:bvn*:bvr*:bd*:svnIBM*:pn*:pvr* + KEYBOARD_KEY_01=battery # Fn+F2 + KEYBOARD_KEY_02=screenlock # Fn+F3 + KEYBOARD_KEY_03=sleep # Fn+F4 + KEYBOARD_KEY_04=wlan # Fn+F5 + KEYBOARD_KEY_06=switchvideomode # Fn+F7 + KEYBOARD_KEY_07=zoom # Fn+F8 screen expand + KEYBOARD_KEY_08=f24 # Fn+F9 undock + KEYBOARD_KEY_0b=suspend # Fn+F12 + KEYBOARD_KEY_0f=brightnessup # Fn+Home + KEYBOARD_KEY_10=brightnessdown # Fn+End + KEYBOARD_KEY_11=kbdillumtoggle # Fn+PgUp - ThinkLight + KEYBOARD_KEY_13=zoom # Fn+Space + KEYBOARD_KEY_14=volumeup + KEYBOARD_KEY_15=volumedown + KEYBOARD_KEY_16=mute + KEYBOARD_KEY_17=prog1 # ThinkPad/ThinkVantage button (high keycode: "vendor") -# Dell XPS -keyboard:dmi:bvn*:bvr*:bd*:svnDell Inc.:pnXPS*:pvr* - KEYBOARD_KEY_8c=! +# IBM Thinkpad USB Keyboard Trackpoint +usb:v04B3p301[89]* + KEYBOARD_KEY_900f0=screenlock + KEYBOARD_KEY_900f1=wlan + KEYBOARD_KEY_900f2=switchvideomode + KEYBOARD_KEY_900f3=suspend + KEYBOARD_KEY_900f4=brightnessup + KEYBOARD_KEY_900f5=brightnessdown + KEYBOARD_KEY_900f8=zoom ########################################################### -# Microsoft +# Inventec ########################################################### -# Microsoft Natural Ergonomic Keyboard 4000 -keyboard:usb:v045Ep00DB* - KEYBOARD_KEY_c022d=zoomin - KEYBOARD_KEY_c022e=zoomout +# Symphony +keyboard:dmi:bvn*:bvr*:bd*:svnINVENTEC:pnSYMPHONY 6.0/7.0:pvr* + KEYBOARD_KEY_f3=prog2 + KEYBOARD_KEY_f4=prog1 ########################################################### -# MSI +# Lenovo ########################################################### -keyboard:name:MSI Laptop hotkeys:dmi:bvn*:bvr*:bd*:svn*:pnM[iI][cC][rR][oO]-S[tT][aA][rR]*:pvr* - KEYBOARD_KEY_0213=f22 - KEYBOARD_KEY_0214=f23 - -########################################## -# Acer -########################################## - -# Acer platform kernel driver -keyboard:name:Acer WMI hotkeys:dmi:bvn*:bvr*:bd*:svn*:pnAcer*:pvr* - KEYBOARD_KEY_82=f21 - -# Aspire 5720 -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire 5720*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnZG8*:pvr* - KEYBOARD_KEY_84=bluetooth # sent when bluetooth module missing, and key pressed - KEYBOARD_KEY_92=media # Acer arcade - KEYBOARD_KEY_d4=bluetooth # Bluetooth on - KEYBOARD_KEY_d9=bluetooth # Bluetooth off - KEYBOARD_KEY_f4=prog3 # e-key - -# Aspire 5920g -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire 5920G:* - KEYBOARD_KEY_8a=media - KEYBOARD_KEY_92=media - KEYBOARD_KEY_a6=setup - KEYBOARD_KEY_b2=www - KEYBOARD_KEY_d9=bluetooth # (toggle) on-to-off - -# Aspire 6920 -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire 6920:* - KEYBOARD_KEY_d9=bluetooth # (toggle) on-to-off - KEYBOARD_KEY_92=media - KEYBOARD_KEY_9e=back - KEYBOARD_KEY_83=rewind - KEYBOARD_KEY_89=fastforward - -# Aspire 8930 -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire 8930:* - KEYBOARD_KEY_ca=prog3 # key 'HOLD' on CineDash Media Console - KEYBOARD_KEY_83=rewind - KEYBOARD_KEY_89=fastforward - KEYBOARD_KEY_92=media # key 'ARCADE' on CineDash Media Console - KEYBOARD_KEY_9e=back - -# Travelmate C300 -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*C3[01]0*:pvr* - KEYBOARD_KEY_67=f24 # FIXME: rotate screen - KEYBOARD_KEY_68=up - KEYBOARD_KEY_69=down - KEYBOARD_KEY_6b=fn - KEYBOARD_KEY_6c=screenlock # FIXME: lock tablet device/buttons - -# -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pn* -keyboard:dmi:bvn*:bvr*:bd*:svnGateway*:pnA0A1*:pvr* - KEYBOARD_KEY_a5=help # Fn+F1 - KEYBOARD_KEY_a6=setup # Fn+F2 Acer eSettings - KEYBOARD_KEY_a7=battery # Fn+F3 Power Management - KEYBOARD_KEY_a9=switchvideomode # Fn+F5 - KEYBOARD_KEY_b3=euro - KEYBOARD_KEY_b4=dollar - KEYBOARD_KEY_ce=brightnessup # Fn+Right - KEYBOARD_KEY_d4=bluetooth # (toggle) off-to-on - KEYBOARD_KEY_d5=wlan # (toggle) on-to-off - KEYBOARD_KEY_d6=wlan # (toggle) off-to-on - KEYBOARD_KEY_d7=bluetooth # (toggle) on-to-off - KEYBOARD_KEY_d8=bluetooth # (toggle) off-to-on - KEYBOARD_KEY_d9=brightnessup # Fn+Right - KEYBOARD_KEY_ee=brightnessup # Fn+Right - KEYBOARD_KEY_ef=brightnessdown # Fn+Left - KEYBOARD_KEY_f1=f22 # Fn+F7 Touchpad toggle (off-to-on) - KEYBOARD_KEY_f2=f23 # Fn+F7 Touchpad toggle (on-to-off) - KEYBOARD_KEY_f3=prog2 # "P2" programmable button - KEYBOARD_KEY_f4=prog1 # "P1" programmable button - KEYBOARD_KEY_f5=presentation - KEYBOARD_KEY_f8=fn - KEYBOARD_KEY_f9=f23 # Launch NTI shadow - -# -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5210*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5220*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5610*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5620*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5720*:pvr* - KEYBOARD_KEY_ee=screenlock - -# -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*6292*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*8471*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*4720*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*7720*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire 1810T*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAO751h:* -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAO531h:* - KEYBOARD_KEY_d9=bluetooth - -# -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*4720*:pvr* - KEYBOARD_KEY_b2=www - KEYBOARD_KEY_ee=screenlock +# thinkpad_acpi driver +keyboard:name:ThinkPad Extra Buttons:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn* + KEYBOARD_KEY_01=screenlock + KEYBOARD_KEY_02=battery + KEYBOARD_KEY_03=sleep + KEYBOARD_KEY_04=wlan + KEYBOARD_KEY_06=switchvideomode + KEYBOARD_KEY_07=f21 + KEYBOARD_KEY_08=f24 + KEYBOARD_KEY_0b=suspend + KEYBOARD_KEY_0f=brightnessup + KEYBOARD_KEY_10=brightnessdown + KEYBOARD_KEY_11=kbdillumtoggle + KEYBOARD_KEY_13=zoom + KEYBOARD_KEY_14=volumeup + KEYBOARD_KEY_15=volumedown + KEYBOARD_KEY_16=mute + KEYBOARD_KEY_17=prog1 + KEYBOARD_KEY_1a=f20 # -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate 6593:* -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire 1640:* - KEYBOARD_KEY_b2=www - KEYBOARD_KEY_ee=screenlock" +keyboard:name:Ideapad extra buttons:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn* + KEYBOARD_KEY_42=f23 + KEYBOARD_KEY_43=f22 -########################################## -# Fujitsu -########################################## +# ThinkPad Keyboard with TrackPoint +keyboard:usb:v17EFp6009* + KEYBOARD_KEY_090012=screenlock # Fn+F2 + KEYBOARD_KEY_090013=battery # Fn+F3 + KEYBOARD_KEY_090014=wlan # Fn+F5 + KEYBOARD_KEY_090016=switchvideomode # Fn+F7 + KEYBOARD_KEY_090017=f21 # Fn+F8 touchpad toggle + KEYBOARD_KEY_090019=suspend # Fn+F12 + KEYBOARD_KEY_09001a=brightnessup # Fn+Home + KEYBOARD_KEY_09001b=brightnessdown # Fn+End + KEYBOARD_KEY_09001d=zoom # Fn+Space + KEYBOARD_KEY_090011=prog1 # ThinkVantage button + KEYBOARD_KEY_090015=camera # Fn+F6 headset/camera VoIP key ?? + KEYBOARD_KEY_090010=f20 # Microphone mute button; should be micmute -keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pnAMILO*M*:pvr* - KEYBOARD_KEY_97=prog2 - KEYBOARD_KEY_9f=prog1 +# Lenovo 3000 +keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*3000*:pvr* + KEYBOARD_KEY_8b=switchvideomode # Fn+F7 video + KEYBOARD_KEY_96=wlan # Fn+F5 wireless + KEYBOARD_KEY_97=sleep # Fn+F4 suspend + KEYBOARD_KEY_98=suspend # Fn+F12 hibernate + KEYBOARD_KEY_b4=prog1 # Lenovo Care -keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pnAmilo Li 1718:* - KEYBOARD_KEY_d6=wlan +# lenovo-ideapad +keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pnS10-*:pvr* + KEYBOARD_KEY_81=rfkill # does nothing in BIOS + KEYBOARD_KEY_83=display_off # BIOS toggles screen state + KEYBOARD_KEY_b9=brightnessup # does nothing in BIOS + KEYBOARD_KEY_ba=brightnessdown # does nothing in BIOS + KEYBOARD_KEY_f1=camera # BIOS toggles camera power + KEYBOARD_KEY_f2=f21 # touchpad toggle (key alternately emits F2 and F3) + KEYBOARD_KEY_f3=f21 -# Amilo Li 2732 -keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pnAMILO Li 2732:* - KEYBOARD_KEY_d9=brightnessdown # Fn+F8 brightness down - KEYBOARD_KEY_ef=brightnessup # Fn+F9 brightness up - KEYBOARD_KEY_a9=switchvideomode # Fn+F10 Cycle between available video outputs +# Thinkpad X200_Tablet +keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pnThinkPad X2* Tablet*:pvr* + KEYBOARD_KEY_5d=menu + KEYBOARD_KEY_63=fn + KEYBOARD_KEY_66=screenlock + KEYBOARD_KEY_67=cyclewindows # bezel circular arrow + KEYBOARD_KEY_68=setup # bezel setup / menu + KEYBOARD_KEY_6c=direction # rotate screen -# Amilo Pa 2548 -keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*AMILO Pa 2548*:pvr* - KEYBOARD_KEY_e0=volumedown - KEYBOARD_KEY_e1=volumeup - KEYBOARD_KEY_e5=prog1 +# ThinkPad X6 Tablet +keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pnThinkPad X6*:pvr* + KEYBOARD_KEY_6c=f21 # rotate + KEYBOARD_KEY_68=screenlock # screenlock + KEYBOARD_KEY_6b=esc # escape + KEYBOARD_KEY_6d=right # right on d-pad + KEYBOARD_KEY_6e=left # left on d-pad + KEYBOARD_KEY_71=up # up on d-pad + KEYBOARD_KEY_6f=down # down on d-pad + KEYBOARD_KEY_69=enter # enter on d-pad -# Amilo Pro Edition V3505 -keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*AMILO Pro Edition V3505*:pvr* - KEYBOARD_KEY_a5=help # Fn+F1 - KEYBOARD_KEY_a9=switchvideomode # Fn+F3 - KEYBOARD_KEY_d9=brightnessdown # Fn+F8 - KEYBOARD_KEY_e0=brightnessup # Fn+F9 +# IdeaPad +keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad Y550*:pvr* + KEYBOARD_KEY_95=media + KEYBOARD_KEY_a3=play -# Amilo Pro v3205 -keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*AMILO Pro V3205*:pvr* - KEYBOARD_KEY_f4=f21 # FIXME: silent-mode decrease CPU/GPU clock - KEYBOARD_KEY_f7=switchvideomode # Fn+F3 +# V480 +keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*Lenovo V480*:pvr* + KEYBOARD_KEY_f1=f21 -# Amilo Si 1520 -keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*Amilo Si 1520*:pvr* - KEYBOARD_KEY_e1=wlan - KEYBOARD_KEY_f3=wlan - KEYBOARD_KEY_ee=brightnessdown - KEYBOARD_KEY_e0=brightnessup - KEYBOARD_KEY_e2=bluetooth - KEYBOARD_KEY_f7=video +# IdeaPad +keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad U300s*:pvr* + KEYBOARD_KEY_f1=f21 + KEYBOARD_KEY_ce=f20 -# Esprimo Mobile V5 -keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*ESPRIMO Mobile V5*:pvr* - KEYBOARD_KEY_a9=switchvideomode - KEYBOARD_KEY_d9=brightnessdown - KEYBOARD_KEY_df=sleep - KEYBOARD_KEY_ef=brightnessup +########################################################### +# Logitech +########################################################### -# Esprimo Mobile V6 -keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*ESPRIMO Mobile V6*:pvr* - KEYBOARD_KEY_ce=brightnessup - KEYBOARD_KEY_ef=brightnessdown +# Logitech Cordless Wave Pro +keyboard:usb:v046DpC52[9b]* + KEYBOARD_KEY_0c01b6=camera + KEYBOARD_KEY_0c0183=media + KEYBOARD_KEY_0c0184=wordprocessor + KEYBOARD_KEY_0c0186=spreadsheet + KEYBOARD_KEY_0c018e=calendar + KEYBOARD_KEY_0c0223=homepage + KEYBOARD_KEY_0c01bc=messenger + KEYBOARD_KEY_0c018a=mail + KEYBOARD_KEY_0c0221=search + KEYBOARD_KEY_0c00b8=ejectcd + KEYBOARD_KEY_0c022d=zoomin + KEYBOARD_KEY_0c022e=zoomout ########################################################### -# Toshiba +# Maxdata ########################################################### -# Satellite A100 -keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSATELLITE A100:pvr* - KEYBOARD_KEY_a4=stopcd - KEYBOARD_KEY_b2=www +# Pro 7000 +keyboard:dmi:bvn*:bvr*:bd*:svnMAXDATA:pnPro 7000*:pvr* + KEYBOARD_KEY_97=prog2 + KEYBOARD_KEY_9f=prog1 + KEYBOARD_KEY_a0=mute # Fn+F5 + KEYBOARD_KEY_82=www + KEYBOARD_KEY_ec=email + KEYBOARD_KEY_ae=volumedown # Fn+Down + KEYBOARD_KEY_b0=volumeup # Fn+Up + KEYBOARD_KEY_df=suspend # Fn+F2 + KEYBOARD_KEY_f5=help -# Satellite A110 -keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite A110:pvr* - KEYBOARD_KEY_92=stop - KEYBOARD_KEY_93=www - KEYBOARD_KEY_94=media - KEYBOARD_KEY_9e=f22 # Touchpad on - KEYBOARD_KEY_9f=f23 # Touchpad off - KEYBOARD_KEY_b9=nextsong - KEYBOARD_KEY_d9=brightnessup - KEYBOARD_KEY_ee=screenlock - KEYBOARD_KEY_f4=previoussong - KEYBOARD_KEY_f7=playpause +########################################################### +# Medion +########################################################### -# Satellite M30X -keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite M30X:pvr* - KEYBOARD_KEY_ef=brightnessdown - KEYBOARD_KEY_d9=brightnessup - KEYBOARD_KEY_ee=screenlock - KEYBOARD_KEY_93=media - KEYBOARD_KEY_9e=f22 # touchpad enable - KEYBOARD_KEY_9f=f23 # touchpad disable +# FID2060 +keyboard:dmi:bvn*:bvr*:bd*:svnMEDION*:pn*FID2060*:pvr* + KEYBOARD_KEY_6b=channeldown # Thottle Down + KEYBOARD_KEY_6d=channelup # Thottle Up + +# NB-A555 +keyboard:dmi:bvn*:bvr*:bd*:svnMEDIONNB:pnA555*:pvr* + KEYBOARD_KEY_63=www # N button + KEYBOARD_KEY_66=prog1 # link 1 button + KEYBOARD_KEY_67=email # envelope button + KEYBOARD_KEY_69=prog2 # link 2 button + +########################################################### +# Microsoft +########################################################### + +# Microsoft Natural Ergonomic Keyboard 4000 +keyboard:usb:v045Ep00DB* + KEYBOARD_KEY_c022d=zoomin + KEYBOARD_KEY_c022e=zoomout ########################################################### # Micro Star @@ -689,89 +649,24 @@ keyboard:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pnGE70*:pvr* keyboard:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn*:pvr* KEYBOARD_KEY_c2=ejectcd -# -keyboard:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pn*U-100*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pn*U100*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pn*N033:* - KEYBOARD_KEY_f7=reserved - KEYBOARD_KEY_f8=reserved - -# -keyboard:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pnU90/U100:* - KEYBOARD_KEY_e4=reserved - -########################################################### -# Medion -########################################################### - -# FID2060 -keyboard:dmi:bvn*:bvr*:bd*:svnMEDION*:pn*FID2060*:pvr* - KEYBOARD_KEY_6b=channeldown # Thottle Down - KEYBOARD_KEY_6d=channelup # Thottle Up - -# NB-A555 -keyboard:dmi:bvn*:bvr*:bd*:svnMEDIONNB:pnA555*:pvr* - KEYBOARD_KEY_63=www # N button - KEYBOARD_KEY_66=prog1 # link 1 button - KEYBOARD_KEY_67=email # envelope button - KEYBOARD_KEY_69=prog2 # link 2 button - -########################################################### -# Genius -########################################################### - -# Slimstar 320 -keyboard:usb:v0458p0708d*dc*dsc*dp*ic*isc*ip*in01* - KEYBOARD_KEY_0900f0=scrollup - KEYBOARD_KEY_0900f1=scrolldown - KEYBOARD_KEY_0900f3=back - KEYBOARD_KEY_0900f2=forward - KEYBOARD_KEY_0900f5=wordprocessor - KEYBOARD_KEY_0900f6=spreadsheet - KEYBOARD_KEY_0900f4=presentation - KEYBOARD_KEY_0c0223=www - KEYBOARD_KEY_0900f7=chat - KEYBOARD_KEY_0900fb=prog1 - KEYBOARD_KEY_0900f8=close - KEYBOARD_KEY_0900f9=graphicseditor - KEYBOARD_KEY_0900fd=scale - KEYBOARD_KEY_0900fc=screenlock - -########################################################### -# Asus -########################################################### - -keyboard:dmi:bvn*:bvr*:bd*:svnASUS:* - KEYBOARD_KEY_ed=volumeup - KEYBOARD_KEY_ee=volumedown - KEYBOARD_KEY_ef=mute - -########################################################### -# VIA -########################################################### - -keyboard:dmi:bvn*:bvr*:bd*:svnVIA:pnK8N800:pvr* - KEYBOARD_KEY_81=prog1 - -########################################################### -# Everex -########################################################### +# +keyboard:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pn*U-100*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pn*U100*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pn*N033:* + KEYBOARD_KEY_f7=reserved + KEYBOARD_KEY_f8=reserved -keyboard:dmi:bvn*:bvr*:bd*:svnEverex:pnXT5000*:pvr* - KEYBOARD_KEY_5c=media - KEYBOARD_KEY_65=f21 # Fn+F5 Touchpad toggle - KEYBOARD_KEY_67=prog3 # Fan speed control button - KEYBOARD_KEY_6f=brightnessup - KEYBOARD_KEY_7f=brightnessdown - KEYBOARD_KEY_b2=www - KEYBOARD_KEY_ec=mail +# +keyboard:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pnU90/U100:* + KEYBOARD_KEY_e4=reserved ########################################################### -# Compal +# MSI ########################################################### -keyboard:dmi:bvn*:bvr*:bd*:svnCOMPAL:pnHEL80I:* - KEYBOARD_KEY_84=wlan +keyboard:name:MSI Laptop hotkeys:dmi:bvn*:bvr*:bd*:svn*:pnM[iI][cC][rR][oO]-S[tT][aA][rR]*:pvr* + KEYBOARD_KEY_0213=f22 + KEYBOARD_KEY_0214=f23 ########################################################### # OLPC @@ -834,40 +729,6 @@ keyboard:dmi:bvn*:bvr*:bd*:svnOLPC:pnXO:* KEYBOARD_KEY_e7=kp7 # home KEYBOARD_KEY_e8=kp1 # end -########################################################### -# Alienware -########################################################### - -keyboard:dmi:bvn*:bvr*:bd*:svnAlienware*:pn* - KEYBOARD_KEY_8a=ejectcd - -########################################################### -# Zepto -########################################################### - -# Znote -keyboard:dmi:bvn*:bvr*:bd*:svnZepto:pnZnote:* - KEYBOARD_KEY_93=switchvideomode # Fn+F3 Toggle Video Output - KEYBOARD_KEY_95=brightnessdown # Fn+F4 Brightness Down - KEYBOARD_KEY_91=brightnessup # Fn+F5 Brightness Up - KEYBOARD_KEY_a5=f23 # Fn+F6 Disable Touchpad - KEYBOARD_KEY_a6=f22 # Fn+F6 Enable Touchpad - KEYBOARD_KEY_a7=bluetooth # Fn+F10 Enable Bluetooth - KEYBOARD_KEY_a9=bluetooth # Fn+F10 Disable Bluetooth - KEYBOARD_KEY_f1=wlan # RF Switch Off - KEYBOARD_KEY_f2=wlan # RF Switch On - KEYBOARD_KEY_f4=prog1 # P1 Button - KEYBOARD_KEY_f3=prog2 # P2 Button - KEYBOARD_KEY_a0=! # mute - KEYBOARD_KEY_ae=! # volume down - KEYBOARD_KEY_b0=! # volume up - -# Znote 6615WD -keyboard:dmi:bvn*:bvr*:bd*:svnZepto:pnZnote 6615WD:* - KEYBOARD_KEY_a0=! # mute - KEYBOARD_KEY_ae=! # volume down - KEYBOARD_KEY_b0=! # volume up - ########################################################### # Onkyo ########################################################### @@ -888,6 +749,18 @@ keyboard:dmi:bvn*:bvr*:bd*:svnONKYO CORPORATION:pnONKYOPC:* KEYBOARD_KEY_f9=brightnessdown # Fn+A KEYBOARD_KEY_fb=wlan # Fn+J +########################################################### +# OQO +########################################################### + +# Model 2 +keyboard:dmi:bvn*:bvr*:bd*:svnOQO Inc.*:pnOQO Model 2*:pvr* + KEYBOARD_KEY_8e=wlan + KEYBOARD_KEY_f0=switchvideomode + KEYBOARD_KEY_f1=mute + KEYBOARD_KEY_f2=volumedown + KEYBOARD_KEY_f3=volumeup + ########################################################### # Quanta ########################################################### @@ -896,48 +769,175 @@ keyboard:dmi:bvn*:bvr*:bd*:svn*:pn*:pvr*:rvnQuanta:rn30B7:rvr65.2B:* KEYBOARD_KEY_88=media # "quick play ########################################################### -# BenQ +# Samsung ########################################################### -keyboard:dmi:bvn*:bvr*:bd*:svn*BenQ*:pn*Joybook R22*:pvr* - KEYBOARD_KEY_6e=wlan +keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pvr* + KEYBOARD_KEY_74=prog1 # User key + KEYBOARD_KEY_75=www + KEYBOARD_KEY_78=mail + KEYBOARD_KEY_82=!switchvideomode # Fn+F4 CRT/LCD (high keycode: "displaytoggle") + KEYBOARD_KEY_83=!battery # Fn+F2 + KEYBOARD_KEY_84=!prog1 # Fn+F5 backlight on/off + KEYBOARD_KEY_86=!wlan # Fn+F9 + KEYBOARD_KEY_88=!brightnessup # Fn+Up + KEYBOARD_KEY_89=!brightnessdown # Fn+Down + KEYBOARD_KEY_b1=!prog2 # Fn+F7 run Samsung Magic Doctor (keypressed event is generated twice) + KEYBOARD_KEY_b3=!prog3 # Fn+F8 switch power mode (battery/dynamic/performance) + KEYBOARD_KEY_b4=!wlan # Fn+F9 (X60P) + KEYBOARD_KEY_f7=!f22 # Fn+F10 Touchpad on + KEYBOARD_KEY_f9=!f23 # Fn+F10 Touchpad off + +# Series 3 +keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*300E[457]*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*200E[45]*:pvr* + KEYBOARD_KEY_ce=! # Fn+F1 launch control setting + KEYBOARD_KEY_d5=! # Fn+F12 Wi-Fi toggle + +# Series 9 +keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*90X3A*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*900X[34]*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*900XC3*:pvr* + KEYBOARD_KEY_ce=! # Fn+F8 keyboard backlight up + KEYBOARD_KEY_8d=! # Fn+F7 keyboard backlight down + KEYBOARD_KEY_96=! # Fn+F1 performance mode (?) + KEYBOARD_KEY_97=! # Fn+F12 Wi-Fi toggle + KEYBOARD_KEY_d5=! # Fn+F6 battery life extender + +# SQ1US +keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pnSQ1US:pvr* + KEYBOARD_KEY_d4=menu + KEYBOARD_KEY_d8=f1 + KEYBOARD_KEY_d9=f10 + KEYBOARD_KEY_d6=f3 + KEYBOARD_KEY_d7=f9 + KEYBOARD_KEY_e4=f5 + KEYBOARD_KEY_ee=f11 + +# SX20S +keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*SX20S*:pvr* + KEYBOARD_KEY_74=mute + KEYBOARD_KEY_75=mute + KEYBOARD_KEY_77=f22 # Touchpad on + KEYBOARD_KEY_79=f23 # Touchpad off + +keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700Z*:pvr* + KEYBOARD_KEY_ba=ejectcd + KEYBOARD_KEY_96=keyboardbrightnessup + KEYBOARD_KEY_97=keyboardbrightnessdown + +keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700T*:pvr* + KEYBOARD_KEY_ad=leftmeta ########################################################### -# Maxdata +# SONY ########################################################### -# Pro 7000 -keyboard:dmi:bvn*:bvr*:bd*:svnMAXDATA:pnPro 7000*:pvr* - KEYBOARD_KEY_97=prog2 - KEYBOARD_KEY_9f=prog1 - KEYBOARD_KEY_a0=mute # Fn+F5 - KEYBOARD_KEY_82=www - KEYBOARD_KEY_ec=email - KEYBOARD_KEY_ae=volumedown # Fn+Down - KEYBOARD_KEY_b0=volumeup # Fn+Up - KEYBOARD_KEY_df=suspend # Fn+F2 - KEYBOARD_KEY_f5=help +# sony-laptop driver +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn* + KEYBOARD_KEY_06=mute # Fn+F2 + KEYBOARD_KEY_07=volumedown # Fn+F3 + KEYBOARD_KEY_08=volumeup # Fn+F4 + KEYBOARD_KEY_09=brightnessdown # Fn+F5 + KEYBOARD_KEY_0a=brightnessup # Fn+F6 + KEYBOARD_KEY_0b=switchvideomode # Fn+F7 + KEYBOARD_KEY_0e=zoom # Fn+F10 + KEYBOARD_KEY_10=suspend # Fn+F12 + +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-C1*:pvr* +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-K25*:pvr* +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-F[1-6]*:pvr* +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-FX*:pvr* +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-FRV*:pvr* +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-GR*:pvr* +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-TR*:pvr* +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-NV*:pvr* +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-Z*:pvr* +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*VGN-S360*:pvr* + KEYBOARD_KEY_06=battery + KEYBOARD_KEY_07=mute + +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVGN-AR71*:pvr* +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVGN-FW*:pvr* +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVGN-Z21*:pvr* + KEYBOARD_KEY_00=brightnessdown # Fn+F5 + KEYBOARD_KEY_10=brightnessup # Fn+F6 + KEYBOARD_KEY_11=switchvideomode # Fn+F7 + KEYBOARD_KEY_12=zoomout + KEYBOARD_KEY_14=zoomin + KEYBOARD_KEY_15=suspend # Fn+F12 + KEYBOARD_KEY_17=prog1 + KEYBOARD_KEY_20=media + +keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVPC*:pvr* + KEYBOARD_KEY_05=f21 # Fn+F1 -> KEY_F21 (The actual touchpad toggle) + KEYBOARD_KEY_0d=zoomout # Fn+F9 + KEYBOARD_KEY_0e=zoomin # Fn+F10 ########################################################### -# OQO +# Toshiba ########################################################### -# Model 2 -keyboard:dmi:bvn*:bvr*:bd*:svnOQO Inc.*:pnOQO Model 2*:pvr* - KEYBOARD_KEY_8e=wlan - KEYBOARD_KEY_f0=switchvideomode - KEYBOARD_KEY_f1=mute - KEYBOARD_KEY_f2=volumedown - KEYBOARD_KEY_f3=volumeup +# Satellite A100 +keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSATELLITE A100:pvr* + KEYBOARD_KEY_a4=stopcd + KEYBOARD_KEY_b2=www + +# Satellite A110 +keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite A110:pvr* + KEYBOARD_KEY_92=stop + KEYBOARD_KEY_93=www + KEYBOARD_KEY_94=media + KEYBOARD_KEY_9e=f22 # Touchpad on + KEYBOARD_KEY_9f=f23 # Touchpad off + KEYBOARD_KEY_b9=nextsong + KEYBOARD_KEY_d9=brightnessup + KEYBOARD_KEY_ee=screenlock + KEYBOARD_KEY_f4=previoussong + KEYBOARD_KEY_f7=playpause + +# Satellite M30X +keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite M30X:pvr* + KEYBOARD_KEY_ef=brightnessdown + KEYBOARD_KEY_d9=brightnessup + KEYBOARD_KEY_ee=screenlock + KEYBOARD_KEY_93=media + KEYBOARD_KEY_9e=f22 # touchpad enable + KEYBOARD_KEY_9f=f23 # touchpad disable ########################################################### -# Inventec +# VIA ########################################################### -# Symphony -keyboard:dmi:bvn*:bvr*:bd*:svnINVENTEC:pnSYMPHONY 6.0/7.0:pvr* - KEYBOARD_KEY_f3=prog2 - KEYBOARD_KEY_f4=prog1 +keyboard:dmi:bvn*:bvr*:bd*:svnVIA:pnK8N800:pvr* + KEYBOARD_KEY_81=prog1 + +########################################################### +# Zepto +########################################################### + +# Znote +keyboard:dmi:bvn*:bvr*:bd*:svnZepto:pnZnote:* + KEYBOARD_KEY_93=switchvideomode # Fn+F3 Toggle Video Output + KEYBOARD_KEY_95=brightnessdown # Fn+F4 Brightness Down + KEYBOARD_KEY_91=brightnessup # Fn+F5 Brightness Up + KEYBOARD_KEY_a5=f23 # Fn+F6 Disable Touchpad + KEYBOARD_KEY_a6=f22 # Fn+F6 Enable Touchpad + KEYBOARD_KEY_a7=bluetooth # Fn+F10 Enable Bluetooth + KEYBOARD_KEY_a9=bluetooth # Fn+F10 Disable Bluetooth + KEYBOARD_KEY_f1=wlan # RF Switch Off + KEYBOARD_KEY_f2=wlan # RF Switch On + KEYBOARD_KEY_f4=prog1 # P1 Button + KEYBOARD_KEY_f3=prog2 # P2 Button + KEYBOARD_KEY_a0=! # mute + KEYBOARD_KEY_ae=! # volume down + KEYBOARD_KEY_b0=! # volume up + +# Znote 6615WD +keyboard:dmi:bvn*:bvr*:bd*:svnZepto:pnZnote 6615WD:* + KEYBOARD_KEY_a0=! # mute + KEYBOARD_KEY_ae=! # volume down + KEYBOARD_KEY_b0=! # volume up ########################################################### # Other -- cgit v1.2.1 From 6c5a28255bea4385289149b4617c86a24eec519f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 14 Jul 2013 23:36:14 -0400 Subject: systemd: fix NULL dereference when disabling a nonexistent instance Assertion 'p' failed at src/shared/path-util.c:51, function path_get_file_name(). Aborting. The unit file could not be found, and i->path would not be set. In 02b9e969 a code path was added which attempts to remove symlinks to a nonexistent (removed) unit file. This worked OK in case of non-instance services, but broke in the case of instance services. Behaviour wrt. to instance units is changed in the way that 02b9e969 changed it for non-instance units: it is now possible to remove instance symlinks to a template unit that has been removed. This patch isn't a full fix, because the behaviour wrt. to enabling and disabling instance units is still broken: e.g it is possible to start autovt@tty5.service, but it is not possible to enable it, because autovt@.service is a symlink, and on the other hand, disabling getty@tty5.service removes all symlinks to getty@.service, which is wrong too. But segfaults make bad pr, so let's add at least this partial fix for now. --- src/shared/install.c | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/shared/install.c b/src/shared/install.c index 116106824f..07e06c425f 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -1062,8 +1062,8 @@ static int unit_file_search( info->path = path; else { if (r == -ENOENT && unit_name_is_instance(info->name)) { - /* unit file doesn't exist, however instance enablement was request */ - /* we will check if it is possible to load template unit file */ + /* Unit file doesn't exist, however instance enablement was requested. + * We will check if it is possible to load template unit file. */ char *template = NULL, *template_path = NULL, *template_dir = NULL; @@ -1074,7 +1074,7 @@ static int unit_file_search( return -ENOMEM; } - /* we will reuse path variable since we don't need it anymore */ + /* We will reuse path variable since we don't need it anymore. */ template_dir = path; *(strrchr(path, '/') + 1) = '\0'; @@ -1085,7 +1085,7 @@ static int unit_file_search( return -ENOMEM; } - /* let's try to load template unit */ + /* Let's try to load template unit. */ r = unit_file_load(c, info, template_path, allow_symlink); if (r >= 0) { info->path = strdup(template_path); @@ -1425,16 +1425,30 @@ static int install_context_mark_for_removal( r += q; if (unit_name_is_instance(i->name)) { - char *unit_file = NULL; + char *unit_file; + + if (i->path) { + unit_file = path_get_file_name(i->path); + + if (unit_name_is_instance(unit_file)) + /* unit file named as instance exists, thus all symlinks + * pointing to it will be removed */ + q = mark_symlink_for_removal(remove_symlinks_to, i->name); + else + /* does not exist, thus we will mark for removal symlinks + * to template unit file */ + q = mark_symlink_for_removal(remove_symlinks_to, unit_file); + } else { + /* If i->path is not set, it means that we didn't actually find + * the unit file. But we can still remove symlinks to the + * nonexistent template. */ + unit_file = unit_name_template(i->name); + if (!unit_file) + return log_oom(); - unit_file = path_get_file_name(i->path); - - if (unit_name_is_instance(unit_file)) - /* unit file named as instance exists, thus all symlinks pointing to it, will be removed */ - q = mark_symlink_for_removal(remove_symlinks_to, i->name); - else - /* does not exist, thus we will mark for removal symlinks to template unit file */ q = mark_symlink_for_removal(remove_symlinks_to, unit_file); + free(unit_file); + } } else q = mark_symlink_for_removal(remove_symlinks_to, i->name); -- cgit v1.2.1 From b8547c10c82994f2b8eab4510629139439b49371 Mon Sep 17 00:00:00 2001 From: Shawn Landden Date: Sun, 14 Jul 2013 20:13:09 -0700 Subject: journalctl: add --force option to recreate FSS --- man/journalctl.xml | 8 ++++++++ src/journal/journalctl.c | 24 +++++++++++++++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/man/journalctl.xml b/man/journalctl.xml index 8dbfb3f0f3..71b1babb10 100644 --- a/man/journalctl.xml +++ b/man/journalctl.xml @@ -600,6 +600,14 @@ for details. + + + + When --setup-keys is passed and + Forward Secure Sealing has already been set up, + recreate FSS keys. + + diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 32665b7f78..5f44fce080 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -79,6 +79,7 @@ static int arg_priorities = 0xFF; static const char *arg_verify_key = NULL; #ifdef HAVE_GCRYPT static usec_t arg_interval = DEFAULT_FSS_INTERVAL_USEC; +static bool arg_force = false; #endif static usec_t arg_since, arg_until; static bool arg_since_set = false, arg_until_set = false; @@ -149,6 +150,7 @@ static int help(void) { " --update-catalog Update the message catalog database\n" #ifdef HAVE_GCRYPT " --setup-keys Generate new FSS key pair\n" + " --force Force overriding new FSS key pair with --setup-keys\n" " --verify Verify journal file consistency\n" #endif , program_invocation_short_name); @@ -179,6 +181,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_LIST_CATALOG, ARG_DUMP_CATALOG, ARG_UPDATE_CATALOG, + ARG_FORCE, }; static const struct option options[] = { @@ -187,6 +190,7 @@ static int parse_argv(int argc, char *argv[]) { { "no-pager", no_argument, NULL, ARG_NO_PAGER }, { "pager-end", no_argument, NULL, 'e' }, { "follow", no_argument, NULL, 'f' }, + { "force", no_argument, NULL, ARG_FORCE }, { "output", required_argument, NULL, 'o' }, { "all", no_argument, NULL, 'a' }, { "full", no_argument, NULL, 'l' }, @@ -375,6 +379,10 @@ static int parse_argv(int argc, char *argv[]) { break; #ifdef HAVE_GCRYPT + case ARG_FORCE: + arg_force = true; + break; + case ARG_SETUP_KEYS: arg_action = ACTION_SETUP_KEYS; break; @@ -397,6 +405,7 @@ static int parse_argv(int argc, char *argv[]) { case ARG_SETUP_KEYS: case ARG_VERIFY_KEY: case ARG_INTERVAL: + case ARG_FORCE: log_error("Forward-secure sealing not available."); return -ENOTSUP; #endif @@ -756,9 +765,18 @@ static int setup_keys(void) { return log_oom(); if (access(p, F_OK) >= 0) { - log_error("Sealing key file %s exists already.", p); - r = -EEXIST; - goto finish; + if (arg_force) { + r = unlink(p); + if (r < 0) { + log_error("unlink(\"%s\") failed: %m", p); + r = -errno; + goto finish; + } + } else { + log_error("Sealing key file %s exists already. (--force to recreate)", p); + r = -EEXIST; + goto finish; + } } if (asprintf(&k, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss.tmp.XXXXXX", -- cgit v1.2.1 From b4ecc959733d9d258d8ed0e8179368ee844a5578 Mon Sep 17 00:00:00 2001 From: Thomas Hindoe Paaboel Andersen Date: Tue, 16 Jul 2013 00:07:36 +0200 Subject: tests: add more tests for shared/util.c --- src/test/test-util.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/test/test-util.c b/src/test/test-util.c index 9396aebd63..4768310fbe 100644 --- a/src/test/test-util.c +++ b/src/test/test-util.c @@ -260,6 +260,18 @@ static void test_undecchar(void) { assert_se(undecchar('9') == 9); } +static void test_cescape(void) { + _cleanup_free_ char *escaped; + escaped = cescape("abc\\\"\b\f\n\r\t\v\003\177\234\313"); + assert_se(streq(escaped, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\003\\177\\234\\313")); +} + +static void test_cunescape(void) { + _cleanup_free_ char *unescaped; + unescaped = cunescape("abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\003\\177\\234\\313"); + assert_se(streq(unescaped, "abc\\\"\b\f\n\r\t\v\003\177\234\313")); +} + static void test_foreach_word(void) { char *w, *state; size_t l; @@ -477,6 +489,38 @@ static void test_parse_bytes(void) { assert_se(parse_bytes("-10B 20K", &bytes) == -ERANGE); } +static void test_strextend(void) { + _cleanup_free_ char *str = strdup("0123"); + strextend(&str, "456", "78", "9", NULL); + assert_se(streq(str, "0123456789")); +} + +static void test_strrep(void) { + _cleanup_free_ char *one, *three, *zero; + one = strrep("waldo", 1); + three = strrep("waldo", 3); + zero = strrep("waldo", 0); + + assert_se(streq(one, "waldo")); + assert_se(streq(three, "waldowaldowaldo")); + assert_se(streq(zero, "")); +} + +static void test_parse_user_at_host(void) { + _cleanup_free_ char *both = strdup("waldo@waldoscomputer"); + _cleanup_free_ char *onlyhost = strdup("mikescomputer"); + char *user = NULL, *host = NULL; + + parse_user_at_host(both, &user, &host); + assert_se(streq(user, "waldo")); + assert_se(streq(host, "waldoscomputer")); + + user = host = NULL; + parse_user_at_host(onlyhost, &user, &host); + assert_se(user == NULL); + assert_se(streq(host, "mikescomputer")); +} + int main(int argc, char *argv[]) { test_streq_ptr(); test_first_word(); @@ -496,6 +540,8 @@ int main(int argc, char *argv[]) { test_unoctchar(); test_decchar(); test_undecchar(); + test_cescape(); + test_cunescape(); test_foreach_word(); test_foreach_word_quoted(); test_default_term_for_tty(); @@ -506,6 +552,9 @@ int main(int argc, char *argv[]) { test_get_process_comm(); test_protect_errno(); test_parse_bytes(); + test_strextend(); + test_strrep(); + test_parse_user_at_host(); return 0; } -- cgit v1.2.1 From 36398225b44367c89f11f42810e4f79652b09a09 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Tue, 9 Jul 2013 18:09:08 +0200 Subject: travis: Add a travis.yml for doing CI after commits Instruct travis-ci to build systemd and create a tarball. In case of an error travis-ci will complain on IRC. The systemd testsuite currently requires the host to have a recent version of systemd installed and running. This is not the case for the Ubuntu VM of travis-ci. This means make check and make distcheck will result in a build failure and to avoid this these commands are not executed. This requires a one time configuration on travis-ci for the repo on github by the owner of the repo. --- .travis.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..42433fd4d0 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,13 @@ +language: c +compiler: + - gcc +before_install: + - sudo apt-get update -qq + - sudo apt-get install autotools-dev automake autoconf libtool libdbus-1-dev libcap-dev libblkid-dev libpam-dev libcryptsetup-dev libaudit-dev libacl1-dev libattr1-dev libselinux-dev liblzma-dev libgcrypt-dev libqrencode-dev libmicrohttpd-dev gtk-doc-tools gperf +script: ./autogen.sh && ./configure --enable-gtk-doc --enable-gtk-doc-pdf && make V=1 && make dist V=1 +notifications: + irc: + channels: + - "irc.freenode.org#systemd" + on_success: change + on_failure: always -- cgit v1.2.1 From 248aa28ff27418ad074439014d476ed8cd2e01db Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 12 Jul 2013 19:47:08 +0200 Subject: update TODO --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index 5d4ba8f65e..6087052d48 100644 --- a/TODO +++ b/TODO @@ -52,6 +52,8 @@ CGroup Rework Completion: * man: document new bus apis +* Send SIGHUP and SIGTERM in session scopes + Features: * Get rid of systemd-sysv: -- cgit v1.2.1 From d907c2086716681936755f28ac80b3445c6d0196 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 15 Jul 2013 23:54:28 +0200 Subject: update TODO --- TODO | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/TODO b/TODO index 6087052d48..88d9ae60b0 100644 --- a/TODO +++ b/TODO @@ -56,6 +56,12 @@ CGroup Rework Completion: Features: +* journald: optionally, when messages with a high log prioerity are logged, sync() immeidately. + +* introduce %v resolving to the string returned by "uname -r" + +* systemctl list-unit-files should list generated files (and probably with a new state "generated" for them, or so) + * Get rid of systemd-sysv: https://fedoraproject.org/wiki/User:Toshio/Systemd_Convert_draft -- cgit v1.2.1 From dac70dc77769f32b202ab07984687593de22f6b3 Mon Sep 17 00:00:00 2001 From: Frederic Crozat Date: Mon, 15 Jul 2013 18:33:57 +0200 Subject: util: recognize 'ncp' as an alias to 'ncpfs' ncp is also used for Netware mount point, recognize it as such. Fixes https://bugzilla.novell.com/show_bug.cgi?id=828905. --- src/shared/util.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/shared/util.c b/src/shared/util.c index ceee6f2c90..5c7204a567 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -1610,6 +1610,7 @@ bool fstype_is_network(const char *fstype) { "cifs\0" "smbfs\0" "ncpfs\0" + "ncp\0" "nfs\0" "nfs4\0" "gfs\0" -- cgit v1.2.1 From e7d90b71272f921b2d5a8f73a26fdd19f546ad07 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Sat, 13 Jul 2013 13:19:36 +0200 Subject: cryptsetup: Move password query out of main Also use _cleanup_free_ where possible. --- src/cryptsetup/cryptsetup.c | 153 +++++++++++++++++++++----------------------- 1 file changed, 72 insertions(+), 81 deletions(-) diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c index 347394db8e..994a0e0f80 100644 --- a/src/cryptsetup/cryptsetup.c +++ b/src/cryptsetup/cryptsetup.c @@ -215,7 +215,8 @@ finish: } static char *disk_mount_point(const char *label) { - char *mp = NULL, *device = NULL; + char *mp = NULL; + _cleanup_free_ char *device = NULL; FILE *f = NULL; struct mntent *m; @@ -238,11 +239,68 @@ finish: if (f) endmntent(f); - free(device); - return mp; } +static int get_password(const char *name, usec_t until, bool accept_cached, char ***passwords) { + int r; + char **p; + _cleanup_free_ char *text = NULL; + + assert(name); + assert(passwords); + + if (asprintf(&text, "Please enter passphrase for disk %s!", name) < 0) + return log_oom(); + + r = ask_password_auto(text, "drive-harddisk", until, accept_cached, passwords); + if (r < 0) { + log_error("Failed to query password: %s", strerror(-r)); + return r; + } + + if (opt_verify) { + _cleanup_strv_free_ char **passwords2 = NULL; + + assert(strv_length(*passwords) == 1); + + if (asprintf(&text, "Please enter passphrase for disk %s! (verification)", name) < 0) + return log_oom(); + + r = ask_password_auto(text, "drive-harddisk", until, false, &passwords2); + if (r < 0) { + log_error("Failed to query verification password: %s", strerror(-r)); + return r; + } + + assert(strv_length(passwords2) == 1); + + if (!streq(*passwords[0], passwords2[0])) { + log_warning("Passwords did not match, retrying."); + return -EAGAIN; + } + } + + 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))) + return log_oom(); + + strncpy(c, *p, opt_key_size); + free(*p); + *p = c; + } + + return 0; +} + static int help(void) { printf("%s attach VOLUME SOURCEDEVICE [PASSWORD] [OPTIONS]\n" @@ -257,9 +315,6 @@ static int help(void) { 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; if (argc <= 1) { help(); @@ -281,9 +336,12 @@ int main(int argc, char *argv[]) { uint32_t flags = 0; int k; unsigned try; - const char *key_file = NULL; usec_t until; crypt_status_info status; + const char *key_file = NULL, *cipher = NULL, *cipher_mode = NULL, + *hash = NULL, *name = NULL; + _cleanup_free_ char *description = NULL, *name_buffer = NULL, + *mount_point = NULL, *truncated_cipher = NULL; /* Arguments: systemd-cryptsetup attach VOLUME SOURCE-DEVICE [PASSWORD] [OPTIONS] */ @@ -386,73 +444,14 @@ int main(int argc, char *argv[]) { for (try = 0; try < opt_tries; try++) { bool pass_volume_key = false; - - strv_free(passwords); - passwords = NULL; + _cleanup_strv_free_ char **passwords = NULL; if (!key_file) { - char *text, **p; - - if (asprintf(&text, "Please enter passphrase for disk %s!", name) < 0) { - log_oom(); - 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)); + k = get_password(name, until, try == 0 && !opt_verify, &passwords); + if (k == -EAGAIN) + continue; + else if (k < 0) 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_oom(); - 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_oom(); - goto finish; - } - - strncpy(c, *p, opt_key_size); - free(*p); - *p = c; - } } k = 0; @@ -464,8 +463,8 @@ int main(int argc, char *argv[]) { struct crypt_params_plain params = { .hash = hash }; /* for CRYPT_PLAIN limit reads - * from keyfile to key length, and - * ignore keyfile-size */ + * from keyfile to key length, and + * ignore keyfile-size */ opt_keyfile_size = opt_key_size / 8; /* In contrast to what the name @@ -579,13 +578,5 @@ finish: free(opt_cipher); free(opt_hash); - free(truncated_cipher); - - strv_free(passwords); - - free(description); - free(mount_point); - free(name_buffer); - return r; } -- cgit v1.2.1 From 10fb4e35fd8a44340f695e49230dc61b5766d47a Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Sat, 13 Jul 2013 13:19:37 +0200 Subject: cryptsetup: Move attaching of the device out of main --- src/cryptsetup/cryptsetup.c | 222 +++++++++++++++++++++++--------------------- 1 file changed, 114 insertions(+), 108 deletions(-) diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c index 994a0e0f80..e84ebba683 100644 --- a/src/cryptsetup/cryptsetup.c +++ b/src/cryptsetup/cryptsetup.c @@ -301,6 +301,102 @@ static int get_password(const char *name, usec_t until, bool accept_cached, char return 0; } +static int attach_luks_or_plain(struct crypt_device *cd, + const char *name, + const char *key_file, + char **passwords, + uint32_t flags) { + int r = 0; + bool pass_volume_key = false; + + assert(cd); + assert(name); + assert(key_file || passwords); + + if (!opt_type || streq(opt_type, CRYPT_LUKS1)) + r = crypt_load(cd, CRYPT_LUKS1, NULL); + + if ((!opt_type && r < 0) || streq_ptr(opt_type, CRYPT_PLAIN)) { + struct crypt_params_plain params = {}; + const char *cipher, *cipher_mode; + _cleanup_free_ char *truncated_cipher = NULL; + + if (opt_hash) { + /* plain isn't a real hash type. it just means "use no hash" */ + if (!streq(opt_hash, "plain")) + params.hash = opt_hash; + } else + params.hash = "ripemd160"; + + if (opt_cipher) { + size_t l; + + l = strcspn(opt_cipher, "-"); + truncated_cipher = strndup(opt_cipher, l); + if (!truncated_cipher) + return log_oom(); + + cipher = truncated_cipher; + cipher_mode = opt_cipher[l] ? opt_cipher+l+1 : "plain"; + } else { + cipher = "aes"; + cipher_mode = "cbc-essiv:sha256"; + } + + /* for CRYPT_PLAIN limit reads + * from keyfile to key length, and + * ignore keyfile-size */ + opt_keyfile_size = opt_key_size / 8; + + /* 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. */ + r = crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, + NULL, NULL, opt_keyfile_size, ¶ms); + + /* hash == NULL implies the user passed "plain" */ + pass_volume_key = (params.hash == NULL); + } + + if (r < 0) { + log_error("Loading of cryptographic parameters failed: %s", strerror(-r)); + return r; + } + + 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, + crypt_get_device_name(cd)); + + if (key_file) { + r = crypt_activate_by_keyfile_offset(cd, name, CRYPT_ANY_SLOT, + key_file, opt_keyfile_size, + opt_keyfile_offset, flags); + if (r < 0) { + log_error("Failed to activate with key file '%s': %s", key_file, strerror(-r)); + return -EAGAIN; + } + } else { + char **p; + + STRV_FOREACH(p, passwords) { + if (pass_volume_key) + r = crypt_activate_by_volume_key(cd, name, *p, opt_key_size, flags); + else + r = crypt_activate_by_passphrase(cd, name, CRYPT_ANY_SLOT, *p, strlen(*p), flags); + + if (r >= 0) + break; + } + } + + return r; +} + static int help(void) { printf("%s attach VOLUME SOURCEDEVICE [PASSWORD] [OPTIONS]\n" @@ -335,13 +431,11 @@ int main(int argc, char *argv[]) { if (streq(argv[1], "attach")) { uint32_t flags = 0; int k; - unsigned try; + unsigned tries; usec_t until; crypt_status_info status; - const char *key_file = NULL, *cipher = NULL, *cipher_mode = NULL, - *hash = NULL, *name = NULL; - _cleanup_free_ char *description = NULL, *name_buffer = NULL, - *mount_point = NULL, *truncated_cipher = NULL; + const char *key_file = NULL, *name = NULL; + _cleanup_free_ char *description = NULL, *name_buffer = NULL, *mount_point = NULL; /* Arguments: systemd-cryptsetup attach VOLUME SOURCE-DEVICE [PASSWORD] [OPTIONS] */ @@ -417,122 +511,34 @@ int main(int argc, char *argv[]) { opt_tries = opt_tries > 0 ? opt_tries : 3; opt_key_size = (opt_key_size > 0 ? opt_key_size : 256); - if (opt_hash) { - /* plain isn't a real hash type. it just means "use no hash" */ - if (!streq(opt_hash, "plain")) - hash = opt_hash; - } else - hash = "ripemd160"; - - if (opt_cipher) { - size_t l; - l = strcspn(opt_cipher, "-"); - truncated_cipher = strndup(opt_cipher, l); - - if (!truncated_cipher) { - log_oom(); - goto finish; - } + if (key_file) { + struct stat st; - cipher = truncated_cipher; - cipher_mode = opt_cipher[l] ? opt_cipher+l+1 : "plain"; - } else { - cipher = "aes"; - cipher_mode = "cbc-essiv:sha256"; + /* Ideally we'd do this on the open fd, but since this is just a + * warning it's OK to do this in two steps. */ + if (stat(key_file, &st) >= 0 && (st.st_mode & 0005)) + log_warning("Key file %s is world-readable. This is not a good idea!", key_file); } - for (try = 0; try < opt_tries; try++) { - bool pass_volume_key = false; + for (tries = 0; tries < opt_tries; tries++) { _cleanup_strv_free_ char **passwords = NULL; if (!key_file) { - k = get_password(name, until, try == 0 && !opt_verify, &passwords); + k = get_password(name, until, tries == 0 && !opt_verify, &passwords); if (k == -EAGAIN) continue; else if (k < 0) goto finish; } - 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 = { .hash = hash }; - - /* for CRYPT_PLAIN limit reads - * from keyfile to key length, and - * ignore keyfile-size */ - opt_keyfile_size = opt_key_size / 8; - - /* 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_keyfile_size, - ¶ms); - - /* hash == NULL implies the user passed "plain" */ - pass_volume_key = (hash == NULL); - } - - 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) { - struct stat st; - - /* Ideally we'd do this on the open - * fd, but since this is just a - * warning it's OK to do this in two - * steps */ - if (stat(key_file, &st) >= 0 && (st.st_mode & 0005)) - log_warning("Key file %s is world-readable. That's certainly not a good idea.", key_file); - - k = crypt_activate_by_keyfile_offset( - cd, argv[2], CRYPT_ANY_SLOT, key_file, opt_keyfile_size, - opt_keyfile_offset, flags); - if (k < 0) { - log_error("Failed to activate with key file '%s': %s", key_file, strerror(-k)); - key_file = NULL; - continue; - } - } 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; - } - } - + k = attach_luks_or_plain(cd, argv[2], key_file, passwords, flags); if (k >= 0) break; - - if (k != -EPERM) { + else if (k == -EAGAIN) { + key_file = NULL; + continue; + } else if (k != -EPERM) { log_error("Failed to activate: %s", strerror(-k)); goto finish; } @@ -540,8 +546,8 @@ int main(int argc, char *argv[]) { log_warning("Invalid passphrase."); } - if (try >= opt_tries) { - log_error("Too many attempts."); + if (tries >= opt_tries) { + log_error("Too many attempts; giving up."); r = EXIT_FAILURE; goto finish; } -- cgit v1.2.1 From 8cf3ca80680b43015971cbbf4625517ae859d50c Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Sat, 13 Jul 2013 13:19:38 +0200 Subject: cryptsetup: Add tcrypt support Tcrypt uses a different approach to passphrases/key files. The passphrase and all key files are incorporated into the "password" to open the volume. So, the idea of slots that provide a way to open the volume with different passphrases/key files that are independent from each other like with LUKS does not apply. Therefore, we use the key file from /etc/crypttab as the source for the passphrase. The actual key files that are combined with the passphrase into a password are provided as a new option in /etc/crypttab and can be given multiple times if more than one key file is used by a volume. --- configure.ac | 2 +- man/crypttab.xml | 300 +++++++++++++++++++++++++++----------------- src/cryptsetup/cryptsetup.c | 79 +++++++++++- 3 files changed, 258 insertions(+), 123 deletions(-) diff --git a/configure.ac b/configure.ac index afbe8e9048..6f5fee5fcf 100644 --- a/configure.ac +++ b/configure.ac @@ -576,7 +576,7 @@ AC_SUBST(AUDIT_LIBS) have_libcryptsetup=no AC_ARG_ENABLE(libcryptsetup, AS_HELP_STRING([--disable-libcryptsetup], [disable libcryptsetup tools])) if test "x$enable_libcryptsetup" != "xno"; then - PKG_CHECK_MODULES(LIBCRYPTSETUP, [ libcryptsetup >= 1.4.2 ], + PKG_CHECK_MODULES(LIBCRYPTSETUP, [ libcryptsetup >= 1.6.0 ], [AC_DEFINE(HAVE_LIBCRYPTSETUP, 1, [Define if libcryptsetup is available]) have_libcryptsetup=yes], have_libcryptsetup=no) if test "x$have_libcryptsetup" = xno -a "x$enable_libcryptsetup" = xyes; then AC_MSG_ERROR([*** libcryptsetup support requested but libraries not found]) diff --git a/man/crypttab.xml b/man/crypttab.xml index e52b7e6015..298f39e0e3 100644 --- a/man/crypttab.xml +++ b/man/crypttab.xml @@ -75,23 +75,29 @@ fields are mandatory, the remaining two are optional. + Setting up encrypted block devices using this file + supports three encryption modes: LUKS, TrueCrypt and plain. + See cryptsetup8 + for more information about each mode. When no mode is specified + in the options field and the block device contains a LUKS + signature, it is opened as a LUKS device; otherwise, it is + assumed to be in raw dm-crypt (plain mode) format. + The first field contains the name of the resulting encrypted block device; the device is set up within /dev/mapper/. The second field contains a path to the - underlying block device, or a specification of a block + underlying block device or file, or a specification of a block device via UUID= followed by the - UUID. If the block device contains a LUKS signature, - it is opened as a LUKS encrypted partition; otherwise, - it is assumed to be a raw dm-crypt partition. + UUID. The third field specifies the encryption password. If the field is not present or the password - is set to none, the password has to be manually - entered during system boot. Otherwise, the field is - interpreted as a path to a file containing the - encryption password. For swap encryption, + is set to none or -, + the password has to be manually entered during system boot. + Otherwise, the field is interpreted as a absolute path to + a file containing the encryption password. For swap encryption, /dev/urandom or the hardware device /dev/hw_random can be used as the password file; using @@ -104,181 +110,237 @@ options are recognized: + + + allow-discards + + Allow discard requests to be + passed through the encrypted block device. This + improves performance on SSD storage but has + security implications. + + cipher= - Specifies the cipher - to use; see + Specifies the cipher to use. See cryptsetup8 - for possible values and the default - value of this option. A cipher with - unpredictable IV values, such as - aes-cbc-essiv:sha256, - is recommended. + for possible values and the default value of + this option. A cipher with unpredictable IV + values, such as aes-cbc-essiv:sha256, + is recommended. - - size= + hash= - Specifies the key size - in bits; see + Specifies the hash to use for + password hashing. See cryptsetup8 - for possible values and the default - value of this - option. + for possible values and the default value of + this option. + + keyfile-offset= + + Specifies the number of bytes to + skip at the start of the key file. See + cryptsetup8 + for possible values and the default value of + this option. + keyfile-size= Specifies the maximum number - of bytes to read from the keyfile; see + of bytes to read from the key file. See cryptsetup8 - for possible values and the default - value of this option. This option is ignored - in plain encryption mode, as the keyfile-size is then given by the key size. + for possible values and the default value of + this option. This option is ignored in plain + encryption mode, as the key file size is then + given by the key size. - - keyfile-offset= + luks - Specifies the number - of bytes to skip at the start of - the keyfile; see - cryptsetup8 - for possible values and the default - value of this option. + Force LUKS mode. When this mode + is used the following options are ignored since + they are provided by the LUKS header on the + device: cipher=, + hash=, + size=. - - hash= + noauto - Specifies the hash to - use for password hashing; see - cryptsetup8 for possible values and - the default value of this - option. + This device will not be + automatically unlocked on boot. - tries= + nofail - Specifies the maximum - number of times the user is queried - for a password. + The system will not wait for the + device to show up and be unlocked at boot, and + not fail the boot if it does not show up. - verify + plain - If the encryption - password is read from console, it has - to be entered twice (to prevent - typos). + Force plain encryption mode. read-onlyreadonly - Set up the encrypted - block device in read-only - mode. + Set up the encrypted block + device in read-only mode. - allow-discards + size= - Allow discard requests - to be passed through the encrypted - block device. This improves - performance on SSD storage but has - security - implications. + Specifies the key size + in bits. See + cryptsetup8 + for possible values and the default value of + this option. - luks + swap - Force LUKS mode. + The encrypted block device will + be used as a swap device, and will be formatted + accordingly after setting up the encrypted + block device, with + mkswap8. + This option implies plain. + + WARNING: Using the swap + option will destroy the contents of the named + partition during every boot, so make sure the + underlying block device is specified correctly. - plain + tcrypt + + Use TrueCrypt encryption mode. + When this mode is used the following options are + ignored since they are provided by the TrueCrypt + header on the device or do not apply: + cipher=, + hash=, + keyfile-offset=, + keyfile-size=, + size=. + + When this mode is used, the passphrase is + read from the key file given in the third field. + Only the first line of this file is read, + excluding the new line character. + + Note that the TrueCrypt format uses both + passphrase and key files to derive a password + for the volume. Therefore, the passphrase and + all key files need to be provided. Use + tcrypt-keyfile= to provide + the absolute path to all key files. When using + an empty passphrase in combination with one or + more key files, use /dev/null + as the password file in the third field. + - Force plain encryption - mode. + + tcrypt-hidden + + Use the hidden TrueCrypt volume. + This implies tcrypt. + + This will map the hidden volume that is + inside of the volume provided in the second + field. Please note that there is no protection + for the hidden volume if the outer volume is + mounted instead. See + cryptsetup8 + for more information on this limitation. - timeout= + tcrypt-keyfile= + + Specifies the absolute path to a + key file to use for a TrueCrypt volume. This + implies tcrypt and can be + used more than once to provide several key + files. - Specify the timeout - for querying for a password. If no - unit is specified seconds is used. - Supported units are s, ms, us, min, h, - d. A timeout of 0 waits indefinitely - (which is the - default). + See the entry for tcrypt + on the behavior of the passphrase and key files + when using TrueCrypt encryption mode. - noauto + tcrypt-system + + Use TrueCrypt in system + encryption mode. This implies + tcrypt. + + Please note that when using this mode, the + whole device needs to be given in the second + field instead of the partition. For example: if + /dev/sda2 is the system + encrypted TrueCrypt patition, /dev/sda + has to be given. + + + + timeout= - This device will not - be automatically unlocked on - boot. + Specifies the timeout for + querying for a password. If no unit is + specified, seconds is used. Supported units are + s, ms, us, min, h, d. A timeout of 0 waits + indefinitely (which is the default). - nofail + tmp + + The encrypted block device will + be prepared for using it as /tmp; + it will be formatted using + mke2fs8. + This option implies plain. - The system will not - wait for the device to show up and be - unlocked at boot, and not fail the - boot if it does not show - up. + WARNING: Using the tmp + option will destroy the contents of the named + partition during every boot, so make sure the + underlying block device is specified correctly. - swap + tries= - The encrypted block - device will be used as a swap - partition, and will be formatted as a - swap partition after setting up the - encrypted block device, with - mkswap8. - - WARNING: Using the - swap option will - destroy the contents of the named - partition during every boot, so make - sure the underlying block device is - specified - correctly. + Specifies the maximum number of + times the user is queried for a password. - tmp + verify - The encrypted block - device will be prepared for using it - as /tmp - partition: it will be formatted using - mke2fs8. - - WARNING: Using the - tmp option will - destroy the contents of the named - partition during every boot, so make - sure the underlying block device is - specified - correctly. + If the encryption password is + read from console, it has to be entered twice to + prevent typos. + At early boot and when the system manager @@ -291,12 +353,14 @@ Example /etc/crypttab example - Set up two encrypted block devices with - LUKS: one normal one for storage, and another - one for usage as swap device. - - luks-2505567a-9e27-4efe-a4d5-15ad146c258b UUID=2505567a-9e27-4efe-a4d5-15ad146c258b - timeout=0 -swap /dev/sda7 /dev/urandom swap + Set up four encrypted block devices. One using + LUKS for normal storage, another one for usage as a swap + device and two TrueCrypt volumes. + + luks UUID=2505567a-9e27-4efe-a4d5-15ad146c258b +swap /dev/sda7 /dev/urandom swap +truecrypt /dev/sda2 /etc/container_password tcrypt +hidden /mnt/tc_hidden /null tcrypt-hidden,tcrypt-keyfile=/etc/keyfile diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c index e84ebba683..3a2cfe459b 100644 --- a/src/cryptsetup/cryptsetup.c +++ b/src/cryptsetup/cryptsetup.c @@ -27,6 +27,7 @@ #include #include +#include "fileio.h" #include "log.h" #include "util.h" #include "path-util.h" @@ -34,7 +35,7 @@ #include "ask-password-api.h" #include "def.h" -static const char *opt_type = NULL; /* LUKS1 or PLAIN */ +static const char *opt_type = NULL; /* CRYPT_LUKS1, CRYPT_TCRYPT or CRYPT_PLAIN */ static char *opt_cipher = NULL; static unsigned opt_key_size = 0; static unsigned opt_keyfile_size = 0; @@ -44,6 +45,9 @@ static unsigned opt_tries = 0; static bool opt_readonly = false; static bool opt_verify = false; static bool opt_discards = false; +static bool opt_tcrypt_hidden = false; +static bool opt_tcrypt_system = false; +static char **opt_tcrypt_keyfiles = NULL; static usec_t opt_timeout = 0; /* Options Debian's crypttab knows we don't: @@ -82,6 +86,14 @@ static int parse_one_option(const char *option) { return 0; } + } else if (startswith(option, "tcrypt-keyfile=")) { + + opt_type = CRYPT_TCRYPT; + if (path_is_absolute(option+15)) + opt_tcrypt_keyfiles = strv_append(opt_tcrypt_keyfiles, strdup(option+15)); + else + log_error("Key file path '%s' is not absolute. Ignoring.", option+15); + } else if (startswith(option, "keyfile-size=")) { if (safe_atou(option+13, &opt_keyfile_size) < 0) { @@ -121,7 +133,15 @@ static int parse_one_option(const char *option) { opt_discards = true; else if (streq(option, "luks")) opt_type = CRYPT_LUKS1; - else if (streq(option, "plain") || + else if (streq(option, "tcrypt")) + opt_type = CRYPT_TCRYPT; + else if (streq(option, "tcrypt-hidden")) { + opt_type = CRYPT_TCRYPT; + opt_tcrypt_hidden = true; + } else if (streq(option, "tcrypt-system")) { + opt_type = CRYPT_TCRYPT; + opt_tcrypt_system = true; + } else if (streq(option, "plain") || streq(option, "swap") || streq(option, "tmp")) opt_type = CRYPT_PLAIN; @@ -301,6 +321,53 @@ static int get_password(const char *name, usec_t until, bool accept_cached, char return 0; } +static int attach_tcrypt(struct crypt_device *cd, + const char *name, + const char *key_file, + char **passwords, + uint32_t flags) { + int r = 0; + _cleanup_free_ char *passphrase = NULL; + struct crypt_params_tcrypt params = { + .flags = CRYPT_TCRYPT_LEGACY_MODES, + .keyfiles = (const char **)opt_tcrypt_keyfiles, + .keyfiles_count = strv_length(opt_tcrypt_keyfiles) + }; + + assert(cd); + assert(name); + assert(key_file || passwords); + + if (opt_tcrypt_hidden) + params.flags |= CRYPT_TCRYPT_HIDDEN_HEADER; + + if (opt_tcrypt_system) + params.flags |= CRYPT_TCRYPT_SYSTEM_HEADER; + + if (key_file) { + r = read_one_line_file(key_file, &passphrase); + if (r < 0) { + log_error("Failed to read password file '%s': %s", key_file, strerror(-r)); + return -EAGAIN; + } + + params.passphrase = passphrase; + } else + params.passphrase = passwords[0]; + params.passphrase_size = strlen(params.passphrase); + + r = crypt_load(cd, CRYPT_TCRYPT, ¶ms); + if (r < 0) { + if (key_file && r == -EPERM) { + log_error("Failed to activate using password file '%s'.", key_file); + return -EAGAIN; + } + return r; + } + + return crypt_activate_by_volume_key(cd, name, NULL, 0, flags);; +} + static int attach_luks_or_plain(struct crypt_device *cd, const char *name, const char *key_file, @@ -450,7 +517,7 @@ int main(int argc, char *argv[]) { !streq(argv[4], "none")) { if (!path_is_absolute(argv[4])) - log_error("Password file path %s is not absolute. Ignoring.", argv[4]); + log_error("Password file path '%s' is not absolute. Ignoring.", argv[4]); else key_file = argv[4]; } @@ -532,7 +599,10 @@ int main(int argc, char *argv[]) { goto finish; } - k = attach_luks_or_plain(cd, argv[2], key_file, passwords, flags); + if (streq_ptr(opt_type, CRYPT_TCRYPT)) + k = attach_tcrypt(cd, argv[2], key_file, passwords, flags); + else + k = attach_luks_or_plain(cd, argv[2], key_file, passwords, flags); if (k >= 0) break; else if (k == -EAGAIN) { @@ -583,6 +653,7 @@ finish: free(opt_cipher); free(opt_hash); + strv_free(opt_tcrypt_keyfiles); return r; } -- cgit v1.2.1 From 77a9e8de6572db6ba5ca49023937b67fc835f356 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 15 Jul 2013 21:03:17 -0400 Subject: man: add note about paging and colors to journalctl(1) --- TODO | 2 +- man/journalctl.xml | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/TODO b/TODO index 88d9ae60b0..3fa384cf2f 100644 --- a/TODO +++ b/TODO @@ -357,7 +357,7 @@ Features: - refuse taking lower-case variable names in sd_journal_send() and friends. - journald: we currently rotate only after MaxUse+MaxFilesize has been reached. - journal: deal nicely with byte-by-byte copied files, especially regards header - - journalctl: show multiline log messages sanely, expand tabs, and show all valid utf8 messages + - journalctl: expand tabs - journal: store euid in journal if it differs from uid - journal: sanely deal with entries which are larger than the individual file size, but where the components would fit - Replace utmp, wtmp, btmp, and lastlog completely with journal diff --git a/man/journalctl.xml b/man/journalctl.xml index 71b1babb10..b8b29b4cb5 100644 --- a/man/journalctl.xml +++ b/man/journalctl.xml @@ -107,6 +107,20 @@ users who are members of the adm group get access to the system journal and the journals of other users. + + The output is paged through + less by default, and long lines are + "truncated" to screen width. The hidden part can be + viewed by using the left-arrow and right-arrow + keys. Paging can be disabled, see + and section Environment + below. + + When outputing to a tty, lines are colored + according to priority: lines of level ERROR and higher + are colored red, lines of level NOTICE and higher are + highlighted, and other lines are displayed normally. + -- cgit v1.2.1 From 31a7eb86f18b0466681d6fbe80c148f96c551c80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 15 Jul 2013 21:34:57 -0400 Subject: systemd: do not output status messages once gettys are running Make Type=idle communication bidirectional: when bootup is finished, the manager, as before, signals idling Type=idle jobs to continue. However, if the boot takes too long, idling jobs signal the manager that they have had enough, wait a tiny bit more, and continue, taking ownership of the console. The manager, when signalled that Type=idle jobs are done, makes a note and will not write to the console anymore. This is a cosmetic issue, but quite noticable, so let's just fix it. Based on Harald Hoyer's patch. https://bugs.freedesktop.org/show_bug.cgi?id=54247 http://unix.stackexchange.com/questions/51805/systemd-messages-after-starting-login/ --- src/core/execute.c | 42 +++++++++++++++++++++------ src/core/manager.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/core/manager.h | 7 +++-- src/core/transaction.c | 5 +++- src/core/unit.c | 12 +++++--- 5 files changed, 125 insertions(+), 19 deletions(-) diff --git a/src/core/execute.c b/src/core/execute.c index 50d2d49ba8..43b571e043 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -69,6 +69,7 @@ #include "unit.h" #define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC) +#define IDLE_TIMEOUT2_USEC (1*USEC_PER_SEC) /* This assumes there is a 'tty' group */ #define TTY_MODE 0620 @@ -977,6 +978,35 @@ static int apply_seccomp(uint32_t *syscall_filter) { return 0; } +static void do_idle_pipe_dance(int idle_pipe[4]) { + assert(idle_pipe); + + if (idle_pipe[1] >= 0) + close_nointr_nofail(idle_pipe[1]); + if (idle_pipe[2] >= 0) + close_nointr_nofail(idle_pipe[2]); + + if (idle_pipe[0] >= 0) { + int r; + + r = fd_wait_for_event(idle_pipe[0], POLLHUP, IDLE_TIMEOUT_USEC); + + if (idle_pipe[3] >= 0 && r == 0 /* timeout */) { + /* Signal systemd that we are bored and want to continue. */ + write(idle_pipe[3], "x", 1); + + /* Wait for systemd to react to the signal above. */ + fd_wait_for_event(idle_pipe[0], POLLHUP, IDLE_TIMEOUT2_USEC); + } + + close_nointr_nofail(idle_pipe[0]); + + } + + if (idle_pipe[3] >= 0) + close_nointr_nofail(idle_pipe[3]); +} + int exec_spawn(ExecCommand *command, char **argv, ExecContext *context, @@ -989,7 +1019,7 @@ int exec_spawn(ExecCommand *command, CGroupControllerMask cgroup_mask, const char *cgroup_path, const char *unit_id, - int idle_pipe[2], + int idle_pipe[4], pid_t *ret) { _cleanup_strv_free_ char **files_env = NULL; @@ -1083,14 +1113,8 @@ int exec_spawn(ExecCommand *command, goto fail_child; } - if (idle_pipe) { - if (idle_pipe[1] >= 0) - close_nointr_nofail(idle_pipe[1]); - if (idle_pipe[0] >= 0) { - fd_wait_for_event(idle_pipe[0], POLLHUP, IDLE_TIMEOUT_USEC); - close_nointr_nofail(idle_pipe[0]); - } - } + if (idle_pipe) + do_idle_pipe_dance(idle_pipe); /* Close sockets very early to make sure we don't * block init reexecution because it cannot bind its diff --git a/src/core/manager.c b/src/core/manager.c index 2e98181b37..ad1a8d6179 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -273,6 +273,58 @@ static void manager_print_jobs_in_progress(Manager *m) { m->jobs_in_progress_iteration++; } +static int manager_watch_idle_pipe(Manager *m) { + struct epoll_event ev = { + .events = EPOLLIN, + .data.ptr = &m->idle_pipe_watch, + }; + int r; + + if (m->idle_pipe_watch.type != WATCH_INVALID) + return 0; + + if (m->idle_pipe[2] < 0) + return 0; + + m->idle_pipe_watch.type = WATCH_IDLE_PIPE; + m->idle_pipe_watch.fd = m->idle_pipe[2]; + if (m->idle_pipe_watch.fd < 0) { + log_error("Failed to create timerfd: %m"); + r = -errno; + goto err; + } + + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->idle_pipe_watch.fd, &ev) < 0) { + log_error("Failed to add idle_pipe fd to epoll: %m"); + r = -errno; + goto err; + } + + log_debug("Set up idle_pipe watch."); + log_debug("m->epoll_fd=%d m->idle_pipe_watch.fd=%d", + m->epoll_fd, m->idle_pipe_watch.fd); + + return 0; + +err: + if (m->idle_pipe_watch.fd >= 0) + close_nointr_nofail(m->idle_pipe_watch.fd); + watch_init(&m->idle_pipe_watch); + return r; +} + +static void manager_unwatch_idle_pipe(Manager *m) { + if (m->idle_pipe_watch.type != WATCH_IDLE_PIPE) + return; + + log_debug("m->epoll_fd=%d m->idle_pipe_watch.fd=%d", + m->epoll_fd, m->idle_pipe_watch.fd); + assert_se(epoll_ctl(m->epoll_fd, EPOLL_CTL_DEL, m->idle_pipe_watch.fd, NULL) >= 0); + watch_init(&m->idle_pipe_watch); + + log_debug("Closed idle_pipe watch."); +} + static int manager_setup_time_change(Manager *m) { struct epoll_event ev = { .events = EPOLLIN, @@ -445,7 +497,7 @@ int manager_new(SystemdRunningAs running_as, bool reexecuting, Manager **_m) { m->name_data_slot = m->conn_data_slot = m->subscribed_data_slot = -1; m->exit_code = _MANAGER_EXIT_CODE_INVALID; m->pin_cgroupfs_fd = -1; - m->idle_pipe[0] = m->idle_pipe[1] = -1; + m->idle_pipe[0] = m->idle_pipe[1] = m->idle_pipe[2] = m->idle_pipe[3] = -1; watch_init(&m->signal_watch); watch_init(&m->mount_watch); @@ -657,6 +709,11 @@ static void manager_clear_jobs_and_units(Manager *m) { m->n_running_jobs = 0; } +static void close_idle_pipe(Manager *m) { + close_pipe(m->idle_pipe); + close_pipe(m->idle_pipe + 2); +} + void manager_free(Manager *m) { UnitType c; int i; @@ -701,7 +758,7 @@ void manager_free(Manager *m) { hashmap_free(m->cgroup_unit); set_free_free(m->unit_path_cache); - close_pipe(m->idle_pipe); + close_idle_pipe(m); free(m->switch_root); free(m->switch_root_init); @@ -1138,6 +1195,9 @@ unsigned manager_dispatch_run_queue(Manager *m) { if (m->n_running_jobs > 0) manager_watch_jobs_in_progress(m); + if (m->n_on_console > 0) + manager_watch_idle_pipe(m); + return n; } @@ -1691,6 +1751,14 @@ static int process_event(Manager *m, struct epoll_event *ev) { break; } + case WATCH_IDLE_PIPE: { + m->no_console_output = true; + + manager_unwatch_idle_pipe(m); + close_idle_pipe(m); + break; + } + default: log_error("event type=%i", w->type); assert_not_reached("Unknown epoll event type."); @@ -2384,7 +2452,8 @@ void manager_check_finished(Manager *m) { } /* Notify Type=idle units that we are done now */ - close_pipe(m->idle_pipe); + manager_unwatch_idle_pipe(m); + close_idle_pipe(m); /* Turn off confirm spawn now */ m->confirm_spawn = false; @@ -2660,6 +2729,9 @@ static bool manager_get_show_status(Manager *m) { if (m->running_as != SYSTEMD_SYSTEM) return false; + if (m->no_console_output) + return false; + if (m->show_status) return true; diff --git a/src/core/manager.h b/src/core/manager.h index 6d5241497d..bd068ac3c9 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -63,7 +63,8 @@ enum WatchType { WATCH_DBUS_WATCH, WATCH_DBUS_TIMEOUT, WATCH_TIME_CHANGE, - WATCH_JOBS_IN_PROGRESS + WATCH_JOBS_IN_PROGRESS, + WATCH_IDLE_PIPE, }; struct Watch { @@ -135,6 +136,7 @@ struct Manager { Watch signal_watch; Watch time_change_watch; Watch jobs_in_progress_watch; + Watch idle_pipe_watch; int epoll_fd; @@ -227,6 +229,7 @@ struct Manager { bool show_status; bool confirm_spawn; + bool no_console_output; ExecOutput default_std_output, default_std_error; @@ -244,7 +247,7 @@ struct Manager { unsigned jobs_in_progress_iteration; /* Type=idle pipes */ - int idle_pipe[2]; + int idle_pipe[4]; char *switch_root; char *switch_root_init; diff --git a/src/core/transaction.c b/src/core/transaction.c index 5259a5b7ca..27efef7cc6 100644 --- a/src/core/transaction.c +++ b/src/core/transaction.c @@ -733,8 +733,11 @@ int transaction_activate(Transaction *tr, Manager *m, JobMode mode, DBusError *e * feature for cosmetics, not actually useful for * anything beyond that. */ - if (m->idle_pipe[0] < 0 && m->idle_pipe[1] < 0) + if (m->idle_pipe[0] < 0 && m->idle_pipe[1] < 0 && + m->idle_pipe[2] < 0 && m->idle_pipe[3] < 0) { pipe2(m->idle_pipe, O_NONBLOCK|O_CLOEXEC); + pipe2(m->idle_pipe + 2, O_NONBLOCK|O_CLOEXEC); + } } return 0; diff --git a/src/core/unit.c b/src/core/unit.c index b245356887..f4f92f0fca 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -1425,10 +1425,14 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su if (UNIT_IS_INACTIVE_OR_FAILED(os) != UNIT_IS_INACTIVE_OR_FAILED(ns)) { ExecContext *ec = unit_get_exec_context(u); if (ec && exec_context_may_touch_console(ec)) { - if (UNIT_IS_INACTIVE_OR_FAILED(ns)) - m->n_on_console--; - else - m->n_on_console++; + if (UNIT_IS_INACTIVE_OR_FAILED(ns)) { + m->n_on_console --; + + if (m->n_on_console == 0) + /* unset no_console_output flag, since the console is free */ + m->no_console_output = 0; + } else + m->n_on_console ++; } } -- cgit v1.2.1 From 65cd79f7f574532e5f91d581aaff923c29655bbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 15 Jul 2013 22:20:06 -0400 Subject: man: add FILES section to systemd-journald.service(8) --- man/systemd-journald.service.xml | 37 ++++++++++++++++++++++++++++++++++++- src/core/manager.c | 4 ---- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/man/systemd-journald.service.xml b/man/systemd-journald.service.xml index d751f9b855..45091c62ab 100644 --- a/man/systemd-journald.service.xml +++ b/man/systemd-journald.service.xml @@ -191,6 +191,40 @@ directory. + + Files + + + + /etc/systemd/journald.conf + + Configure + systemd-journald + behaviour. See + journald.conf5. + + + + + /var/log/journal/machine-id/*.journal + /var/log/journal/machine-id/*.journal~ + + systemd-journald + writes entries to files in + /var/log/journal/machine-id/ + with the .journal + suffix. If the daemon is stopped + uncleanly, or if the files are found + to be corrupted, they are renamed + using the .journal~ + suffix, and + systemd-journald + starts writing to a new file. + + + + + See Also @@ -199,7 +233,8 @@ journald.conf5, systemd.journal-fields7, sd-journal3, - setfacl1 + setfacl1, + pydoc systemd.journal. diff --git a/src/core/manager.c b/src/core/manager.c index ad1a8d6179..6c082c96b9 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -301,8 +301,6 @@ static int manager_watch_idle_pipe(Manager *m) { } log_debug("Set up idle_pipe watch."); - log_debug("m->epoll_fd=%d m->idle_pipe_watch.fd=%d", - m->epoll_fd, m->idle_pipe_watch.fd); return 0; @@ -317,8 +315,6 @@ static void manager_unwatch_idle_pipe(Manager *m) { if (m->idle_pipe_watch.type != WATCH_IDLE_PIPE) return; - log_debug("m->epoll_fd=%d m->idle_pipe_watch.fd=%d", - m->epoll_fd, m->idle_pipe_watch.fd); assert_se(epoll_ctl(m->epoll_fd, EPOLL_CTL_DEL, m->idle_pipe_watch.fd, NULL) >= 0); watch_init(&m->idle_pipe_watch); -- cgit v1.2.1 From fa7deadb074dfbe473cf3bd942768dbd94cbf7c3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 16 Jul 2013 03:30:45 +0200 Subject: update TODO --- TODO | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/TODO b/TODO index 3fa384cf2f..08626ec5c4 100644 --- a/TODO +++ b/TODO @@ -56,6 +56,10 @@ CGroup Rework Completion: Features: +* when parsing calendar timestamps support the UTC timezone (even if we won't support arbitrary timezone specs, support UTC itself certainly makes sense) + +* when a kernel driver logs in a tight loop we should ratelimit that too. + * journald: optionally, when messages with a high log prioerity are logged, sync() immeidately. * introduce %v resolving to the string returned by "uname -r" -- cgit v1.2.1 From 3a83211689bdf4ab617a4fb79e11980c50918123 Mon Sep 17 00:00:00 2001 From: Shawn Landden Date: Mon, 15 Jul 2013 18:10:56 -0700 Subject: journal: add logging of effective capabilities _CAP_EFFECTIVE I think this is the most important of the capabilities bitmasks to log. --- TODO | 2 -- man/systemd.journal-fields.xml | 9 +++++++++ src/journal/journald-server.c | 7 +++++++ src/shared/util.c | 34 ++++++++++++++++++++++++++++++++++ src/shared/util.h | 1 + 5 files changed, 51 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index 08626ec5c4..3621ce32a5 100644 --- a/TODO +++ b/TODO @@ -220,8 +220,6 @@ Features: * teach ConditionKernelCommandLine= globs or regexes (in order to match foobar={no,0,off}) -* we should log capabilities too - * Support SO_REUSEPORT with socket activation: - Let systemd maintain a pool of servers. - Use for seamless upgrades, by running the new server before stopping the diff --git a/man/systemd.journal-fields.xml b/man/systemd.journal-fields.xml index ed62edc849..452406c676 100644 --- a/man/systemd.journal-fields.xml +++ b/man/systemd.journal-fields.xml @@ -196,6 +196,15 @@ + + _CAP_EFFECTIVE= + + The effective capabilities7 of + the process the journal entry + originates from. + + + _AUDIT_SESSION= _AUDIT_LOGINUID= diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 6beaa8a729..332ba41363 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -578,6 +578,13 @@ static void dispatch_message_real( IOVEC_SET_STRING(iovec[n++], x); } + r = get_process_capeff(ucred->pid, &t); + if (r >= 0) { + x = strappenda("_CAP_EFFECTIVE=", t); + free(t); + IOVEC_SET_STRING(iovec[n++], x); + } + #ifdef HAVE_AUDIT r = audit_session_from_pid(ucred->pid, &audit); if (r >= 0) { diff --git a/src/shared/util.c b/src/shared/util.c index 5c7204a567..19ca8ad135 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -726,6 +726,40 @@ int is_kernel_thread(pid_t pid) { return 0; } +int get_process_capeff(pid_t pid, char **capeff) { + const char *p; + _cleanup_free_ char *status = NULL; + char *t = NULL; + int r; + + assert(capeff); + assert(pid >= 0); + + if (pid == 0) + p = "/proc/self/status"; + else + p = procfs_file_alloca(pid, "status"); + + r = read_full_file(p, &status, NULL); + if (r < 0) + return r; + + t = strstr(status, "\nCapEff:\t"); + if (!t) + return -ENOENT; + + for (t += strlen("\nCapEff:\t"); t[0] == '0'; t++) + continue; + + if (t[0] == '\n') + t--; + + *capeff = strndup(t, strchr(t, '\n') - t); + if (!*capeff) + return -ENOMEM; + + return 0; +} int get_process_exe(pid_t pid, char **name) { const char *p; diff --git a/src/shared/util.h b/src/shared/util.h index ddb21b4a9c..fac08ca43c 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -210,6 +210,7 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char * int get_process_exe(pid_t pid, char **name); int get_process_uid(pid_t pid, uid_t *uid); int get_process_gid(pid_t pid, gid_t *gid); +int get_process_capeff(pid_t pid, char **capeff); char hexchar(int x) _const_; int unhexchar(char c) _const_; -- cgit v1.2.1 From 7801356442578ff6e1c65844eb9e65c819af4660 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 15 Jul 2013 23:04:52 -0400 Subject: build-sys: discover the path to kexec during build time https://bugs.freedesktop.org/show_bug.cgi?id=55248 --- Makefile.am | 1 + configure.ac | 2 ++ src/core/shutdown.c | 2 +- src/login/logind-action.c | 2 +- 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index 9105274c0d..44cfd3ea1c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -165,6 +165,7 @@ AM_CPPFLAGS = \ -DUDEVLIBEXECDIR=\"$(udevlibexecdir)\" \ -DPOLKIT_AGENT_BINARY_PATH=\"$(bindir)/pkttyagent\" \ -DQUOTACHECK=\"$(QUOTACHECK)\" \ + -DKEXEC=\"$(KEXEC)\" \ -I $(top_srcdir)/src \ -I $(top_srcdir)/src/shared \ -I $(top_srcdir)/src/login \ diff --git a/configure.ac b/configure.ac index 6f5fee5fcf..94afe51d74 100644 --- a/configure.ac +++ b/configure.ac @@ -76,6 +76,8 @@ AC_PATH_PROG([KILL], [kill], [/usr/bin/kill]) AC_PATH_PROG([KMOD], [kmod], [/usr/bin/kmod]) +AC_PATH_PROG([KEXEC], [kexec], [/usr/sbin/kexec]) + # gtkdocize greps for '^GTK_DOC_CHECK', so it needs to be on its own line m4_ifdef([GTK_DOC_CHECK], [ GTK_DOC_CHECK([1.18],[--flavour no-tmpl])], diff --git a/src/core/shutdown.c b/src/core/shutdown.c index 10a52bd117..4709746de4 100644 --- a/src/core/shutdown.c +++ b/src/core/shutdown.c @@ -318,7 +318,7 @@ int main(int argc, char *argv[]) { log_warning("kexec failed. Falling back to normal reboot."); } else { /* Child */ - const char *args[3] = { "/sbin/kexec", "-e", NULL }; + const char *args[3] = { KEXEC, "-e", NULL }; execv(args[0], (char * const *) args); return EXIT_FAILURE; } diff --git a/src/login/logind-action.c b/src/login/logind-action.c index c930591023..74114ee0a1 100644 --- a/src/login/logind-action.c +++ b/src/login/logind-action.c @@ -81,7 +81,7 @@ int manager_handle_action( else if (handle == HANDLE_HYBRID_SLEEP) supported = can_sleep("hybrid-sleep") > 0; else if (handle == HANDLE_KEXEC) - supported = access("/sbin/kexec", X_OK) >= 0; + supported = access(KEXEC, X_OK) >= 0; else supported = true; -- cgit v1.2.1 From b31c6d8d4f33502d6060e708f5252ee2ea8648ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 15 Jul 2013 23:13:12 -0400 Subject: build-sys: make generated man pages part of the distribution tarball They were removed by mistake, and since we ship .html files, we certainly should ship man pages. https://bugs.freedesktop.org/show_bug.cgi?id=61753 --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 44cfd3ea1c..0be3e79f1c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -607,7 +607,7 @@ EXTRA_DIST += \ $(XML_FILES) \ $(HTML_FILES) \ $(HTML_ALIAS) \ - $(dist_MANS) \ + $(man_MANS) \ make-man-index.py \ make-directive-index.py \ xml_helper.py -- cgit v1.2.1 From f3c19b70fa970321ec06d3bd2497f5abd525efc9 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Tue, 16 Jul 2013 09:06:57 +0200 Subject: keymap: Drop non-existant Samsung 900XC3 Revert commit 90fc91d0065 again. There is no 900XC3 model, that's 900X3C and already covered by the 900X3* match. See https://launchpad.net/bugs/1012365 --- src/udev/keymap/95-keyboard-force-release.rules | 2 +- src/udev/keymap/95-keymap.rules | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/udev/keymap/95-keyboard-force-release.rules b/src/udev/keymap/95-keyboard-force-release.rules index 431a28358a..8bfe17d679 100644 --- a/src/udev/keymap/95-keyboard-force-release.rules +++ b/src/udev/keymap/95-keyboard-force-release.rules @@ -19,7 +19,7 @@ DRIVER!="atkbd", GOTO="force_release_end" ENV{DMI_VENDOR}="$attr{[dmi/id]sys_vendor}" ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", RUN+="keyboard-force-release.sh $devpath samsung-other" -ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*90X3A*|*900X3*|*900X4*|*900XC3*", RUN+="keyboard-force-release.sh $devpath samsung-series-9" +ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*90X3A*|*900X3*|*900X4*", RUN+="keyboard-force-release.sh $devpath samsung-series-9" ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*300E5*|*300E4*|*300E7*|*270E5*|*270E4*", RUN+="keyboard-force-release.sh $devpath samsung-series-3" ENV{DMI_VENDOR}=="Dell Inc.", ATTR{[dmi/id]product_name}=="Studio 1557|Studio 1558", RUN+="keyboard-force-release.sh $devpath common-volume-keys" diff --git a/src/udev/keymap/95-keymap.rules b/src/udev/keymap/95-keymap.rules index 60f0bf7ac2..4d6ec556c2 100644 --- a/src/udev/keymap/95-keymap.rules +++ b/src/udev/keymap/95-keymap.rules @@ -153,7 +153,7 @@ ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="* ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="SQ1US", RUN+="keymap $name samsung-sq1us" ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*700Z*", RUN+="keymap $name 0xBA ejectcd 0x96 keyboardbrightnessup 0x97 keyboardbrightnessdown" ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*700T*", RUN+="keymap $name 0xAD leftmeta" -ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*90X3A*|*900X3*|*900X4*|*900XC3*", RUN+="keymap $name samsung-series-9" +ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*90X3A*|*900X3*|*900X4*", RUN+="keymap $name samsung-series-9" ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*300E5*|*300E4*|*300E7*|*270E5*|*270E4*", RUN+="keymap $name samsung-series-3" ENV{DMI_VENDOR}=="TOSHIBA", ATTR{[dmi/id]product_name}=="SATELLITE A100", RUN+="keymap $name toshiba-satellite_a100" -- cgit v1.2.1 From 97a9313cafccf772ce03f5ebd36fe4d9d8412583 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 16 Jul 2013 14:13:55 +0200 Subject: hwdb: follow: "keymap: Drop non-existant Samsung 900XC3" --- hwdb/60-keyboard.hwdb | 1 - 1 file changed, 1 deletion(-) diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index dae8c85310..1068dedb3b 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -797,7 +797,6 @@ keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*200E[45]*:pvr* # Series 9 keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*90X3A*:pvr* keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*900X[34]*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*900XC3*:pvr* KEYBOARD_KEY_ce=! # Fn+F8 keyboard backlight up KEYBOARD_KEY_8d=! # Fn+F7 keyboard backlight down KEYBOARD_KEY_96=! # Fn+F1 performance mode (?) -- cgit v1.2.1 From 36c0868b67a9387d39c97983d3d22cfce0fedc62 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 16 Jul 2013 14:27:20 +0200 Subject: Update TODO --- TODO | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/TODO b/TODO index 3621ce32a5..735f1a7901 100644 --- a/TODO +++ b/TODO @@ -56,7 +56,9 @@ CGroup Rework Completion: Features: -* when parsing calendar timestamps support the UTC timezone (even if we won't support arbitrary timezone specs, support UTC itself certainly makes sense) +* when parsing calendar timestamps support the UTC timezone (even if we won't support arbitrary timezone specs, support UTC itself certainly makes sense), also support syntaxes such as +0200 + +* journalctl: add an output mode that looks like classic /var/log/messages, but also outputs the cursor of the last entry so that people can write scripts that can run iteratively and always process data that has been added since the last time. * when a kernel driver logs in a tight loop we should ratelimit that too. -- cgit v1.2.1 From 7080ea16b5a0bfd71bfcdffc998e91f5273d47f9 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Tue, 16 Jul 2013 16:44:40 +0530 Subject: detect-virt: detect User-Mode Linux In a User-Mode Linux session: $ systemd-detect-virt none Although it is possible to reliably detect virtualization: $ cat /proc/cpuinfo processor : 0 vendor_id : User Mode Linux model name : UML mode : skas host : Linux kytes 3.11.0-rc1-00009-ge5fd680 (...) bogomips : 7007.43 So, grep for the string "\nvendor_id\t: User Mode Linux\n" in /proc/cpuinfo, and say "uml" when asked. --- man/systemd-detect-virt.xml | 1 + man/systemd.unit.xml | 1 + src/shared/virt.c | 11 +++++++++++ 3 files changed, 13 insertions(+) diff --git a/man/systemd-detect-virt.xml b/man/systemd-detect-virt.xml index 762b6ab992..f21493df64 100644 --- a/man/systemd-detect-virt.xml +++ b/man/systemd-detect-virt.xml @@ -70,6 +70,7 @@ microsoft, oracle, xen, bochs, chroot, + uml, openvz, lxc, lxc-libvirt, systemd-nspawn. diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index a14e452fa3..f45632a0e3 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -969,6 +969,7 @@ xen, bochs, chroot, + uml, openvz, lxc, lxc-libvirt, diff --git a/src/shared/virt.c b/src/shared/virt.c index 1c86a3dd1e..1abd6863ea 100644 --- a/src/shared/virt.c +++ b/src/shared/virt.c @@ -67,6 +67,7 @@ int detect_vm(const char **id) { const char *j, *k; bool hypervisor; _cleanup_free_ char *hvtype = NULL; + _cleanup_free_ char *cpuinfo_contents = NULL; int r; /* Try high-level hypervisor sysfs file first: @@ -164,6 +165,16 @@ int detect_vm(const char **id) { } #endif + + /* Detect User-Mode Linux by reading /proc/cpuinfo */ + r = read_full_file("/proc/cpuinfo", &cpuinfo_contents, NULL); + if (r < 0) + return r; + if (strstr(cpuinfo_contents, "\nvendor_id\t: User Mode Linux\n")) { + *id = "uml"; + return 1; + } + return 0; } -- cgit v1.2.1 From ddc77f62244bb41d5c8261517e2e1ff1b763fc94 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 16 Jul 2013 16:13:32 +0200 Subject: switch from udev keymaps to hwdb --- .gitignore | 1 - Makefile.am | 137 +------ configure.ac | 15 - hwdb/60-keyboard.hwdb | 2 +- keymaps/acer | 22 -- keymaps/acer-aspire_5720 | 5 - keymaps/acer-aspire_5920g | 5 - keymaps/acer-aspire_6920 | 5 - keymaps/acer-aspire_8930 | 5 - keymaps/acer-travelmate_c300 | 5 - keymaps/asus | 3 - keymaps/compaq-e_evo | 4 - keymaps/dell | 29 -- keymaps/dell-latitude-xt2 | 4 - keymaps/everex-xt5000 | 7 - keymaps/fujitsu-amilo_li_2732 | 3 - keymaps/fujitsu-amilo_pa_2548 | 3 - keymaps/fujitsu-amilo_pro_edition_v3505 | 4 - keymaps/fujitsu-amilo_pro_v3205 | 2 - keymaps/fujitsu-amilo_si_1520 | 6 - keymaps/fujitsu-esprimo_mobile_v5 | 4 - keymaps/fujitsu-esprimo_mobile_v6 | 2 - keymaps/genius-slimstar-320 | 35 -- keymaps/hewlett-packard | 12 - keymaps/hewlett-packard-2510p_2530p | 2 - keymaps/hewlett-packard-compaq_elitebook | 2 - keymaps/hewlett-packard-hdx9494nr | 3 - keymaps/hewlett-packard-pavilion | 3 - keymaps/hewlett-packard-presario-2100 | 3 - keymaps/hewlett-packard-tablet | 6 - keymaps/hewlett-packard-tx2 | 3 - keymaps/hewlett-packard_elitebook-8440p | 5 - keymaps/hewlett-packard_elitebook-8460p | 3 - keymaps/ibm-thinkpad-usb-keyboard-trackpoint | 7 - keymaps/inventec-symphony_6.0_7.0 | 2 - keymaps/lenovo-3000 | 5 - keymaps/lenovo-ideapad | 8 - keymaps/lenovo-thinkpad-usb-keyboard-trackpoint | 13 - keymaps/lenovo-thinkpad_x200_tablet | 6 - keymaps/lenovo-thinkpad_x6_tablet | 8 - keymaps/lg-x110 | 12 - keymaps/logitech-usb | 6 - keymaps/logitech-wave | 16 - keymaps/logitech-wave-cordless | 15 - keymaps/logitech-wave-pro-cordless | 12 - keymaps/maxdata-pro_7000 | 9 - keymaps/medion-fid2060 | 2 - keymaps/medionnb-a555 | 4 - keymaps/micro-star | 13 - keymaps/module-ibm | 16 - keymaps/module-lenovo | 17 - keymaps/module-sony | 8 - keymaps/module-sony-old | 2 - keymaps/module-sony-vgn | 8 - keymaps/module-sony-vpc | 4 - keymaps/olpc-xo | 74 ---- keymaps/onkyo | 14 - keymaps/oqo-model2 | 5 - keymaps/samsung-other | 14 - keymaps/samsung-series-3 | 3 - keymaps/samsung-series-9 | 5 - keymaps/samsung-sq1us | 7 - keymaps/samsung-sx20s | 4 - keymaps/toshiba-satellite_a100 | 2 - keymaps/toshiba-satellite_a110 | 10 - keymaps/toshiba-satellite_m30x | 6 - keymaps/zepto-znote | 11 - src/udev/keymap/.gitignore | 5 - src/udev/keymap/95-keyboard-force-release.rules | 60 ---- src/udev/keymap/95-keymap.rules | 181 ---------- src/udev/keymap/README.keymap.txt | 97 ----- src/udev/keymap/check-keymaps.sh | 38 -- src/udev/keymap/findkeyboards | 68 ---- src/udev/keymap/keyboard-force-release.sh.in | 22 -- src/udev/keymap/keymap.c | 453 ------------------------ 75 files changed, 3 insertions(+), 1619 deletions(-) delete mode 100644 keymaps/acer delete mode 100644 keymaps/acer-aspire_5720 delete mode 100644 keymaps/acer-aspire_5920g delete mode 100644 keymaps/acer-aspire_6920 delete mode 100644 keymaps/acer-aspire_8930 delete mode 100644 keymaps/acer-travelmate_c300 delete mode 100644 keymaps/asus delete mode 100644 keymaps/compaq-e_evo delete mode 100644 keymaps/dell delete mode 100644 keymaps/dell-latitude-xt2 delete mode 100644 keymaps/everex-xt5000 delete mode 100644 keymaps/fujitsu-amilo_li_2732 delete mode 100644 keymaps/fujitsu-amilo_pa_2548 delete mode 100644 keymaps/fujitsu-amilo_pro_edition_v3505 delete mode 100644 keymaps/fujitsu-amilo_pro_v3205 delete mode 100644 keymaps/fujitsu-amilo_si_1520 delete mode 100644 keymaps/fujitsu-esprimo_mobile_v5 delete mode 100644 keymaps/fujitsu-esprimo_mobile_v6 delete mode 100644 keymaps/genius-slimstar-320 delete mode 100644 keymaps/hewlett-packard delete mode 100644 keymaps/hewlett-packard-2510p_2530p delete mode 100644 keymaps/hewlett-packard-compaq_elitebook delete mode 100644 keymaps/hewlett-packard-hdx9494nr delete mode 100644 keymaps/hewlett-packard-pavilion delete mode 100644 keymaps/hewlett-packard-presario-2100 delete mode 100644 keymaps/hewlett-packard-tablet delete mode 100644 keymaps/hewlett-packard-tx2 delete mode 100644 keymaps/hewlett-packard_elitebook-8440p delete mode 100644 keymaps/hewlett-packard_elitebook-8460p delete mode 100644 keymaps/ibm-thinkpad-usb-keyboard-trackpoint delete mode 100644 keymaps/inventec-symphony_6.0_7.0 delete mode 100644 keymaps/lenovo-3000 delete mode 100644 keymaps/lenovo-ideapad delete mode 100644 keymaps/lenovo-thinkpad-usb-keyboard-trackpoint delete mode 100644 keymaps/lenovo-thinkpad_x200_tablet delete mode 100644 keymaps/lenovo-thinkpad_x6_tablet delete mode 100644 keymaps/lg-x110 delete mode 100644 keymaps/logitech-usb delete mode 100644 keymaps/logitech-wave delete mode 100644 keymaps/logitech-wave-cordless delete mode 100644 keymaps/logitech-wave-pro-cordless delete mode 100644 keymaps/maxdata-pro_7000 delete mode 100644 keymaps/medion-fid2060 delete mode 100644 keymaps/medionnb-a555 delete mode 100644 keymaps/micro-star delete mode 100644 keymaps/module-ibm delete mode 100644 keymaps/module-lenovo delete mode 100644 keymaps/module-sony delete mode 100644 keymaps/module-sony-old delete mode 100644 keymaps/module-sony-vgn delete mode 100644 keymaps/module-sony-vpc delete mode 100644 keymaps/olpc-xo delete mode 100644 keymaps/onkyo delete mode 100644 keymaps/oqo-model2 delete mode 100644 keymaps/samsung-other delete mode 100644 keymaps/samsung-series-3 delete mode 100644 keymaps/samsung-series-9 delete mode 100644 keymaps/samsung-sq1us delete mode 100644 keymaps/samsung-sx20s delete mode 100644 keymaps/toshiba-satellite_a100 delete mode 100644 keymaps/toshiba-satellite_a110 delete mode 100644 keymaps/toshiba-satellite_m30x delete mode 100644 keymaps/zepto-znote delete mode 100644 src/udev/keymap/.gitignore delete mode 100644 src/udev/keymap/95-keyboard-force-release.rules delete mode 100644 src/udev/keymap/95-keymap.rules delete mode 100644 src/udev/keymap/README.keymap.txt delete mode 100755 src/udev/keymap/check-keymaps.sh delete mode 100755 src/udev/keymap/findkeyboards delete mode 100755 src/udev/keymap/keyboard-force-release.sh.in delete mode 100644 src/udev/keymap/keymap.c diff --git a/.gitignore b/.gitignore index f4f1e45926..bdf9d4afd8 100644 --- a/.gitignore +++ b/.gitignore @@ -12,7 +12,6 @@ /hostnamectl /install-tree /journalctl -/keymap /libtool /localectl /loginctl diff --git a/Makefile.am b/Makefile.am index 0be3e79f1c..7e6361c2e8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2154,7 +2154,8 @@ dist_udevhwdb_DATA = \ hwdb/20-usb-classes.hwdb \ hwdb/20-bluetooth-vendor-product.hwdb \ hwdb/20-acpi-vendor.hwdb \ - hwdb/20-OUI.hwdb + hwdb/20-OUI.hwdb \ + hwdb/60-keyboard.hwdb udevconfdir = $(sysconfdir)/udev dist_udevconf_DATA = \ @@ -2602,140 +2603,6 @@ EXTRA_DIST += \ src/gudev/seed-example-enum.js \ src/gudev/seed-example.js -# ------------------------------------------------------------------------------ -if ENABLE_KEYMAP -keymap_SOURCES = \ - src/udev/keymap/keymap.c - -keymap_CPPFLAGS = \ - $(AM_CPPFLAGS) -I src/udev/keymap - -keymap_LDADD = \ - libsystemd-shared.la - -nodist_keymap_SOURCES = \ - src/udev/keymap/keys-from-name.h \ - src/udev/keymap/keys-to-name.h - -BUILT_SOURCES += \ - $(nodist_keymap_SOURCES) - -udevlibexec_PROGRAMS += \ - keymap - -dist_doc_DATA += \ - src/udev/keymap/README.keymap.txt - -dist_udevrules_DATA += \ - src/udev/keymap/95-keymap.rules \ - src/udev/keymap/95-keyboard-force-release.rules - -dist_udevhome_SCRIPTS = \ - src/udev/keymap/findkeyboards \ - src/udev/keymap/keyboard-force-release.sh - -TESTS += \ - src/udev/keymap/check-keymaps.sh - -CLEANFILES += \ - src/udev/keymap/keys.txt \ - src/udev/keymap/keys-from-name.gperf \ - src/udev/keymap/keyboard-force-release.sh - -udevkeymapdir = $(udevlibexecdir)/keymaps -dist_udevkeymap_DATA = \ - keymaps/acer \ - keymaps/acer-aspire_5720 \ - keymaps/acer-aspire_8930 \ - keymaps/acer-aspire_5920g \ - keymaps/acer-aspire_6920 \ - keymaps/acer-travelmate_c300 \ - keymaps/asus \ - keymaps/compaq-e_evo \ - keymaps/dell \ - keymaps/dell-latitude-xt2 \ - keymaps/everex-xt5000 \ - keymaps/fujitsu-amilo_li_2732 \ - keymaps/fujitsu-amilo_pa_2548 \ - keymaps/fujitsu-amilo_pro_edition_v3505 \ - keymaps/fujitsu-amilo_pro_v3205 \ - keymaps/fujitsu-amilo_si_1520 \ - keymaps/fujitsu-esprimo_mobile_v5 \ - keymaps/fujitsu-esprimo_mobile_v6 \ - keymaps/genius-slimstar-320 \ - keymaps/hewlett-packard \ - keymaps/hewlett-packard-2510p_2530p \ - keymaps/hewlett-packard-compaq_elitebook \ - keymaps/hewlett-packard-pavilion \ - keymaps/hewlett-packard-presario-2100 \ - keymaps/hewlett-packard-tablet \ - keymaps/hewlett-packard-tx2 \ - keymaps/hewlett-packard_elitebook-8440p \ - keymaps/hewlett-packard_elitebook-8460p \ - keymaps/hewlett-packard-hdx9494nr \ - keymaps/ibm-thinkpad-usb-keyboard-trackpoint \ - keymaps/inventec-symphony_6.0_7.0 \ - keymaps/lenovo-3000 \ - keymaps/lenovo-ideapad \ - keymaps/lenovo-thinkpad-usb-keyboard-trackpoint \ - keymaps/lenovo-thinkpad_x6_tablet \ - keymaps/lenovo-thinkpad_x200_tablet \ - keymaps/lg-x110 \ - keymaps/logitech-usb \ - keymaps/logitech-wave \ - keymaps/logitech-wave-cordless \ - keymaps/logitech-wave-pro-cordless \ - keymaps/maxdata-pro_7000 \ - keymaps/medion-fid2060 \ - keymaps/medionnb-a555 \ - keymaps/micro-star \ - keymaps/module-ibm \ - keymaps/module-lenovo \ - keymaps/module-sony \ - keymaps/module-sony-old \ - keymaps/module-sony-vgn \ - keymaps/module-sony-vpc \ - keymaps/olpc-xo \ - keymaps/onkyo \ - keymaps/oqo-model2 \ - keymaps/samsung-other \ - keymaps/samsung-series-9 \ - keymaps/samsung-series-3 \ - keymaps/samsung-sq1us \ - keymaps/samsung-sx20s \ - keymaps/toshiba-satellite_a100 \ - keymaps/toshiba-satellite_a110 \ - keymaps/toshiba-satellite_m30x \ - keymaps/zepto-znote - -udevkeymapforcereldir = $(udevlibexecdir)/keymaps/force-release -dist_udevkeymapforcerel_DATA = \ - keymaps-force-release/dell-touchpad \ - keymaps-force-release/dell-xps \ - keymaps-force-release/hp-other \ - keymaps-force-release/samsung-other \ - keymaps-force-release/samsung-series-9 \ - keymaps-force-release/samsung-series-3 \ - keymaps-force-release/common-volume-keys - -src/udev/keymap/keys.txt: Makefile - $(AM_V_at)$(MKDIR_P) $(dir $@) - $(AM_V_GEN)$(CPP) $(CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) -dM -include linux/input.h - < /dev/null | $(AWK) '/^#define[ \t]+KEY_[^ ]+[ \t]+[0-9]/ { if ($$2 != "KEY_MAX") { print $$2 } }' | sed 's/^KEY_COFFEE$$/KEY_SCREENLOCK/' > $@ - -src/udev/keymap/keys-from-name.gperf: src/udev/keymap/keys.txt Makefile - $(AM_V_GEN)$(AWK) 'BEGIN{ print "struct key { const char* name; unsigned short id; };"; print "%null-strings"; print "%%";} { print $$1 ", " $$1 }' < $< > $@ - -src/udev/keymap/keys-from-name.h: src/udev/keymap/keys-from-name.gperf Makefile - $(AM_V_GPERF)$(GPERF) -L ANSI-C -t --ignore-case -N lookup_key -H hash_key_name -p -C < $< > $@ - -src/udev/keymap/keys-to-name.h: src/udev/keymap/keys.txt Makefile - $(AM_V_GEN)$(AWK) 'BEGIN{ print "const char* const key_names[KEY_CNT] = { "} { print "[" $$1 "] = \"" $$1 "\"," } END{print "};"}' < $< > $@ -endif - -EXTRA_DIST += \ - src/udev/keymap/check-keymaps.sh \ - src/udev/keymap/keyboard-force-release.sh.in - # ------------------------------------------------------------------------------ mtd_probe_SOURCES = \ src/udev/mtd_probe/mtd_probe.c \ diff --git a/configure.ac b/configure.ac index 94afe51d74..1cffbbb7e8 100644 --- a/configure.ac +++ b/configure.ac @@ -830,21 +830,6 @@ AS_IF([test "x$enable_gudev" = "xyes"], [ PKG_CHECK_MODULES([GLIB], [glib-2.0 >= AM_CONDITIONAL([ENABLE_GUDEV], [test "x$enable_gudev" = "xyes"]) AS_IF([test "x$enable_gudev" = "xyes"], [ AC_DEFINE(HAVE_GLIB, 1, [Define if glib is available]) ]) -# ------------------------------------------------------------------------------ -AC_ARG_ENABLE([keymap], - AS_HELP_STRING([--disable-keymap], [disable keymap fixup support @<:@default=enabled@:>@]), - [], [enable_keymap=yes]) -AS_IF([test "x$enable_keymap" = "xyes"], [ - AC_PATH_PROG([GPERF], [gperf]) - if test -z "$GPERF"; then - AC_MSG_ERROR([gperf is needed]) - fi - - AC_CHECK_HEADER([linux/input.h], [:], AC_MSG_ERROR([kernel headers not found])) - AC_SUBST([INCLUDE_PREFIX], [$(echo '#include ' | eval $ac_cpp -E - | sed -n '/linux\/input.h/ {s:.*"\(.*\)/linux/input.h".*:\1:; p; q}')]) -]) -AM_CONDITIONAL([ENABLE_KEYMAP], [test "x$enable_keymap" = "xyes"]) - # ------------------------------------------------------------------------------ have_manpages=no AC_ARG_ENABLE(manpages, AS_HELP_STRING([--disable-manpages], [disable manpages])) diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index 1068dedb3b..569b9c74fe 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -448,7 +448,7 @@ keyboard:name:ThinkPad Extra Buttons:dmi:bvn*:bvr*:bd*:svnIBM*:pn*:pvr* KEYBOARD_KEY_17=prog1 # ThinkPad/ThinkVantage button (high keycode: "vendor") # IBM Thinkpad USB Keyboard Trackpoint -usb:v04B3p301[89]* +keyboard:usb:v04B3p301[89]* KEYBOARD_KEY_900f0=screenlock KEYBOARD_KEY_900f1=wlan KEYBOARD_KEY_900f2=switchvideomode diff --git a/keymaps/acer b/keymaps/acer deleted file mode 100644 index a0c6fd278a..0000000000 --- a/keymaps/acer +++ /dev/null @@ -1,22 +0,0 @@ -0xA5 help # Fn+F1 -0xA6 setup # Fn+F2 Acer eSettings -0xA7 battery # Fn+F3 Power Management -0xA9 switchvideomode # Fn+F5 -0xB3 euro -0xB4 dollar -0xCE brightnessup # Fn+Right -0xD4 bluetooth # (toggle) off-to-on -0xD5 wlan # (toggle) on-to-off -0xD6 wlan # (toggle) off-to-on -0xD7 bluetooth # (toggle) on-to-off -0xD8 bluetooth # (toggle) off-to-on -0xD9 brightnessup # Fn+Right -0xEE brightnessup # Fn+Right -0xEF brightnessdown # Fn+Left -0xF1 f22 # Fn+F7 Touchpad toggle (off-to-on) -0xF2 f23 # Fn+F7 Touchpad toggle (on-to-off) -0xF3 prog2 # "P2" programmable button -0xF4 prog1 # "P1" programmable button -0xF5 presentation -0xF8 fn -0xF9 f23 # Launch NTI shadow diff --git a/keymaps/acer-aspire_5720 b/keymaps/acer-aspire_5720 deleted file mode 100644 index b9381f86c6..0000000000 --- a/keymaps/acer-aspire_5720 +++ /dev/null @@ -1,5 +0,0 @@ -0x84 bluetooth # sent when bluetooth module missing, and key pressed -0x92 media # Acer arcade -0xD4 bluetooth # Bluetooth on -0xD9 bluetooth # Bluetooth off -0xF4 prog3 # e-key diff --git a/keymaps/acer-aspire_5920g b/keymaps/acer-aspire_5920g deleted file mode 100644 index 633c4e854c..0000000000 --- a/keymaps/acer-aspire_5920g +++ /dev/null @@ -1,5 +0,0 @@ -0x8A media -0x92 media -0xA6 setup -0xB2 www -0xD9 bluetooth # (toggle) on-to-off diff --git a/keymaps/acer-aspire_6920 b/keymaps/acer-aspire_6920 deleted file mode 100644 index 699c954b4e..0000000000 --- a/keymaps/acer-aspire_6920 +++ /dev/null @@ -1,5 +0,0 @@ -0xD9 bluetooth # (toggle) on-to-off -0x92 media -0x9E back -0x83 rewind -0x89 fastforward diff --git a/keymaps/acer-aspire_8930 b/keymaps/acer-aspire_8930 deleted file mode 100644 index 8e36cd947c..0000000000 --- a/keymaps/acer-aspire_8930 +++ /dev/null @@ -1,5 +0,0 @@ -0xCA prog3 # key 'HOLD' on CineDash Media Console -0x83 rewind -0x89 fastforward -0x92 media # key 'ARCADE' on CineDash Media Console -0x9E back diff --git a/keymaps/acer-travelmate_c300 b/keymaps/acer-travelmate_c300 deleted file mode 100644 index bfef4cf868..0000000000 --- a/keymaps/acer-travelmate_c300 +++ /dev/null @@ -1,5 +0,0 @@ -0x67 f24 # FIXME: rotate screen -0x68 up -0x69 down -0x6B fn -0x6C screenlock # FIXME: lock tablet device/buttons diff --git a/keymaps/asus b/keymaps/asus deleted file mode 100644 index 2a5995f982..0000000000 --- a/keymaps/asus +++ /dev/null @@ -1,3 +0,0 @@ -0xED volumeup -0xEE volumedown -0xEF mute diff --git a/keymaps/compaq-e_evo b/keymaps/compaq-e_evo deleted file mode 100644 index 5fbc573aa4..0000000000 --- a/keymaps/compaq-e_evo +++ /dev/null @@ -1,4 +0,0 @@ -0xA3 www # I key -0x9A search -0x9E email -0x9F homepage diff --git a/keymaps/dell b/keymaps/dell deleted file mode 100644 index cef41d3e7b..0000000000 --- a/keymaps/dell +++ /dev/null @@ -1,29 +0,0 @@ -0x81 playpause # Play/Pause -0x82 stopcd # Stop -0x83 previoussong # Previous song -0x84 nextsong # Next song -0x85 brightnessdown # Fn+Down Brightness Down -0x86 brightnessup # Fn+Up Brightness Up -0x87 battery # Fn+F3 battery icon -0x88 unknown # Fn+F2 Turn On/Off Wireless - handled in hardware -0x89 ejectclosecd # Fn+F10 Eject CD -0x8A suspend # Fn+F1 hibernate -0x8B switchvideomode # Fn+F8 CRT/LCD (high keycode: "displaytoggle") -0x8C f23 # Fn+Right Auto Brightness -0x8F switchvideomode # Fn+F7 aspect ratio -0x90 previoussong # Front panel previous song -0x91 prog1 # Wi-Fi Catcher (Dell-specific) -0x92 media # MediaDirect button (house icon) -0x93 f23 # FIXME Fn+Left Auto Brightness -0x95 camera # Shutter button - Takes a picture if optional camera available -0x97 email # Tablet email button -0x98 f21 # FIXME: Tablet screen rotation -0x99 nextsong # Front panel next song -0x9A setup # Tablet tools button -0x9B switchvideomode # Display toggle button -0x9E f21 # Touchpad toggle -0xA2 playpause # Front panel play/pause -0xA4 stopcd # Front panel stop -0xED media # MediaDirect button -0xD8 screenlock # FIXME: Tablet lock button -0xD9 f21 # Touchpad toggle diff --git a/keymaps/dell-latitude-xt2 b/keymaps/dell-latitude-xt2 deleted file mode 100644 index 59ff6ff264..0000000000 --- a/keymaps/dell-latitude-xt2 +++ /dev/null @@ -1,4 +0,0 @@ -0x9B up # tablet rocker up -0x9E enter # tablet rocker press -0x9F back # tablet back -0xA3 down # tablet rocker down diff --git a/keymaps/everex-xt5000 b/keymaps/everex-xt5000 deleted file mode 100644 index bd89a23d3e..0000000000 --- a/keymaps/everex-xt5000 +++ /dev/null @@ -1,7 +0,0 @@ -0x5C media -0x65 f21 # Fn+F5 Touchpad toggle -0x67 prog3 # Fan speed control button -0x6F brightnessup -0x7F brightnessdown -0xB2 www -0xEC mail diff --git a/keymaps/fujitsu-amilo_li_2732 b/keymaps/fujitsu-amilo_li_2732 deleted file mode 100644 index c9b3198d1b..0000000000 --- a/keymaps/fujitsu-amilo_li_2732 +++ /dev/null @@ -1,3 +0,0 @@ -0xD9 brightnessdown # Fn+F8 brightness down -0xEF brightnessup # Fn+F9 brightness up -0xA9 switchvideomode # Fn+F10 Cycle between available video outputs diff --git a/keymaps/fujitsu-amilo_pa_2548 b/keymaps/fujitsu-amilo_pa_2548 deleted file mode 100644 index f7b0c52444..0000000000 --- a/keymaps/fujitsu-amilo_pa_2548 +++ /dev/null @@ -1,3 +0,0 @@ -0xE0 volumedown -0xE1 volumeup -0xE5 prog1 diff --git a/keymaps/fujitsu-amilo_pro_edition_v3505 b/keymaps/fujitsu-amilo_pro_edition_v3505 deleted file mode 100644 index fd95b000c6..0000000000 --- a/keymaps/fujitsu-amilo_pro_edition_v3505 +++ /dev/null @@ -1,4 +0,0 @@ -0xA5 help # Fn+F1 -0xA9 switchvideomode # Fn+F3 -0xD9 brightnessdown # Fn+F8 -0xE0 brightnessup # Fn+F9 diff --git a/keymaps/fujitsu-amilo_pro_v3205 b/keymaps/fujitsu-amilo_pro_v3205 deleted file mode 100644 index 8cbf239464..0000000000 --- a/keymaps/fujitsu-amilo_pro_v3205 +++ /dev/null @@ -1,2 +0,0 @@ -0xF4 f21 # FIXME: silent-mode decrease CPU/GPU clock -0xF7 switchvideomode # Fn+F3 diff --git a/keymaps/fujitsu-amilo_si_1520 b/keymaps/fujitsu-amilo_si_1520 deleted file mode 100644 index 1419bd9b5e..0000000000 --- a/keymaps/fujitsu-amilo_si_1520 +++ /dev/null @@ -1,6 +0,0 @@ -0xE1 wlan -0xF3 wlan -0xEE brightnessdown -0xE0 brightnessup -0xE2 bluetooth -0xF7 video diff --git a/keymaps/fujitsu-esprimo_mobile_v5 b/keymaps/fujitsu-esprimo_mobile_v5 deleted file mode 100644 index d3d056b366..0000000000 --- a/keymaps/fujitsu-esprimo_mobile_v5 +++ /dev/null @@ -1,4 +0,0 @@ -0xA9 switchvideomode -0xD9 brightnessdown -0xDF sleep -0xEF brightnessup diff --git a/keymaps/fujitsu-esprimo_mobile_v6 b/keymaps/fujitsu-esprimo_mobile_v6 deleted file mode 100644 index 52c70c50cb..0000000000 --- a/keymaps/fujitsu-esprimo_mobile_v6 +++ /dev/null @@ -1,2 +0,0 @@ -0xCE brightnessup -0xEF brightnessdown diff --git a/keymaps/genius-slimstar-320 b/keymaps/genius-slimstar-320 deleted file mode 100644 index d0a3656dd8..0000000000 --- a/keymaps/genius-slimstar-320 +++ /dev/null @@ -1,35 +0,0 @@ -# Genius SlimStar 320 -# -# Only buttons which are not properly mapped yet are configured below - -# "Scroll wheel", a circular up/down/left/right button. Aimed for scolling, -# but since there are no scrollleft/scrollright, let's map to back/forward. -0x900f0 scrollup -0x900f1 scrolldown -0x900f3 back -0x900f2 forward - -# Multimedia buttons, left side (from left to right) -# [W] -0x900f5 wordprocessor -# [Ex] -0x900f6 spreadsheet -# [P] -0x900f4 presentation -# Other five (calculator, playpause, stop, mute and eject) are OK - -# Right side, from left to right -# [e] -0xc0223 www -# "man" -0x900f7 chat -# "Y" -0x900fb prog1 -# [X] -0x900f8 close -# "picture" -0x900f9 graphicseditor -# "two windows" -0x900fd scale -# "lock" -0x900fc screenlock diff --git a/keymaps/hewlett-packard b/keymaps/hewlett-packard deleted file mode 100644 index 3f5f5ace6f..0000000000 --- a/keymaps/hewlett-packard +++ /dev/null @@ -1,12 +0,0 @@ -0x81 fn_esc -0x89 battery # Fn+F8 -0x8A screenlock # Fn+F6 -0x8B camera -0x8C media # music -0x8E dvd -0xB1 help -0xB3 f23 # FIXME: Auto brightness -0xD7 wlan -0x92 brightnessdown # Fn+F7 (Fn+F9 on 6730b) -0x97 brightnessup # Fn+F8 (Fn+F10 on 6730b) -0xEE switchvideomode # Fn+F4 diff --git a/keymaps/hewlett-packard-2510p_2530p b/keymaps/hewlett-packard-2510p_2530p deleted file mode 100644 index 41ad2e9b5a..0000000000 --- a/keymaps/hewlett-packard-2510p_2530p +++ /dev/null @@ -1,2 +0,0 @@ -0xD8 f23 # touchpad off -0xD9 f22 # touchpad on diff --git a/keymaps/hewlett-packard-compaq_elitebook b/keymaps/hewlett-packard-compaq_elitebook deleted file mode 100644 index 42007c5483..0000000000 --- a/keymaps/hewlett-packard-compaq_elitebook +++ /dev/null @@ -1,2 +0,0 @@ -0x88 presentation -0xD9 help # I key (high keycode: "info") diff --git a/keymaps/hewlett-packard-hdx9494nr b/keymaps/hewlett-packard-hdx9494nr deleted file mode 100644 index 39e8b4c9f7..0000000000 --- a/keymaps/hewlett-packard-hdx9494nr +++ /dev/null @@ -1,3 +0,0 @@ -0xB2 www # Fn+F3 -0xD8 f23 # touchpad off -0xD9 f22 # touchpad on diff --git a/keymaps/hewlett-packard-pavilion b/keymaps/hewlett-packard-pavilion deleted file mode 100644 index 60d1191106..0000000000 --- a/keymaps/hewlett-packard-pavilion +++ /dev/null @@ -1,3 +0,0 @@ -0x88 media # FIXME: quick play -0xD8 f23 # touchpad off -0xD9 f22 # touchpad on diff --git a/keymaps/hewlett-packard-presario-2100 b/keymaps/hewlett-packard-presario-2100 deleted file mode 100644 index 1df39dcbd2..0000000000 --- a/keymaps/hewlett-packard-presario-2100 +++ /dev/null @@ -1,3 +0,0 @@ -0xF0 help -0xF1 screenlock -0xF3 search diff --git a/keymaps/hewlett-packard-tablet b/keymaps/hewlett-packard-tablet deleted file mode 100644 index d19005ab90..0000000000 --- a/keymaps/hewlett-packard-tablet +++ /dev/null @@ -1,6 +0,0 @@ -0x82 prog2 # Funny Key -0x83 prog1 # Q -0x84 tab -0x85 esc -0x86 pageup -0x87 pagedown diff --git a/keymaps/hewlett-packard-tx2 b/keymaps/hewlett-packard-tx2 deleted file mode 100644 index 36a690fcf6..0000000000 --- a/keymaps/hewlett-packard-tx2 +++ /dev/null @@ -1,3 +0,0 @@ -0xC2 media -0xD8 f23 # Toggle touchpad button on tx2 (OFF) -0xD9 f22 # Toggle touchpad button on tx2 (ON) diff --git a/keymaps/hewlett-packard_elitebook-8440p b/keymaps/hewlett-packard_elitebook-8440p deleted file mode 100644 index e0c2a1a859..0000000000 --- a/keymaps/hewlett-packard_elitebook-8440p +++ /dev/null @@ -1,5 +0,0 @@ -0x88 www -0xA0 mute -0xAE volumedown -0xB0 volumeup -0xEC mail diff --git a/keymaps/hewlett-packard_elitebook-8460p b/keymaps/hewlett-packard_elitebook-8460p deleted file mode 100644 index 59035f4005..0000000000 --- a/keymaps/hewlett-packard_elitebook-8460p +++ /dev/null @@ -1,3 +0,0 @@ -0xF8 wlan # Wireless HW switch button -0xB3 prog1 # Fn+F11 - Ambient Light Sensor button -0xB1 prog2 # Fn+ESC - System information button diff --git a/keymaps/ibm-thinkpad-usb-keyboard-trackpoint b/keymaps/ibm-thinkpad-usb-keyboard-trackpoint deleted file mode 100644 index 027e50bf88..0000000000 --- a/keymaps/ibm-thinkpad-usb-keyboard-trackpoint +++ /dev/null @@ -1,7 +0,0 @@ -0x900f0 screenlock -0x900f1 wlan -0x900f2 switchvideomode -0x900f3 suspend -0x900f4 brightnessup -0x900f5 brightnessdown -0x900f8 zoom diff --git a/keymaps/inventec-symphony_6.0_7.0 b/keymaps/inventec-symphony_6.0_7.0 deleted file mode 100644 index 4a8b4ba5a7..0000000000 --- a/keymaps/inventec-symphony_6.0_7.0 +++ /dev/null @@ -1,2 +0,0 @@ -0xF3 prog2 -0xF4 prog1 diff --git a/keymaps/lenovo-3000 b/keymaps/lenovo-3000 deleted file mode 100644 index 7973369a9d..0000000000 --- a/keymaps/lenovo-3000 +++ /dev/null @@ -1,5 +0,0 @@ -0x8B switchvideomode # Fn+F7 video -0x96 wlan # Fn+F5 wireless -0x97 sleep # Fn+F4 suspend -0x98 suspend # Fn+F12 hibernate -0xB4 prog1 # Lenovo Care diff --git a/keymaps/lenovo-ideapad b/keymaps/lenovo-ideapad deleted file mode 100644 index 0de16466b4..0000000000 --- a/keymaps/lenovo-ideapad +++ /dev/null @@ -1,8 +0,0 @@ -# Key codes observed on S10-3, assumed valid on other IdeaPad models -0x81 rfkill # does nothing in BIOS -0x83 display_off # BIOS toggles screen state -0xB9 brightnessup # does nothing in BIOS -0xBA brightnessdown # does nothing in BIOS -0xF1 camera # BIOS toggles camera power -0xf2 f21 # touchpad toggle (key alternately emits F2 and F3) -0xf3 f21 diff --git a/keymaps/lenovo-thinkpad-usb-keyboard-trackpoint b/keymaps/lenovo-thinkpad-usb-keyboard-trackpoint deleted file mode 100644 index 78701acbc7..0000000000 --- a/keymaps/lenovo-thinkpad-usb-keyboard-trackpoint +++ /dev/null @@ -1,13 +0,0 @@ -0x90012 screenlock # Fn+F2 -0x90013 battery # Fn+F3 -0x90014 wlan # Fn+F5 -0x90016 switchvideomode # Fn+F7 -0x90017 f21 # Fn+F8 touchpad toggle -0x90019 suspend # Fn+F12 -0x9001A brightnessup # Fn+Home -0x9001B brightnessdown # Fn+End -0x9001D zoom # Fn+Space -0x90011 prog1 # ThinkVantage button - -0x90015 camera # Fn+F6 headset/camera VoIP key ?? -0x90010 f20 # Microphone mute button; should be micmute, but see https://mail.gnome.org/archives/commits-list/2013-January/msg05822.html diff --git a/keymaps/lenovo-thinkpad_x200_tablet b/keymaps/lenovo-thinkpad_x200_tablet deleted file mode 100644 index f22ec65a5b..0000000000 --- a/keymaps/lenovo-thinkpad_x200_tablet +++ /dev/null @@ -1,6 +0,0 @@ -0x5D menu -0x63 fn -0x66 screenlock -0x67 cyclewindows # bezel circular arrow -0x68 setup # bezel setup / menu -0x6c direction # rotate screen diff --git a/keymaps/lenovo-thinkpad_x6_tablet b/keymaps/lenovo-thinkpad_x6_tablet deleted file mode 100644 index 49c5f64f4c..0000000000 --- a/keymaps/lenovo-thinkpad_x6_tablet +++ /dev/null @@ -1,8 +0,0 @@ -0x6C f21 # rotate -0x68 screenlock # screenlock -0x6B esc # escape -0x6D right # right on d-pad -0x6E left # left on d-pad -0x71 up # up on d-pad -0x6F down # down on d-pad -0x69 enter # enter on d-pad diff --git a/keymaps/lg-x110 b/keymaps/lg-x110 deleted file mode 100644 index bbc29a13e9..0000000000 --- a/keymaps/lg-x110 +++ /dev/null @@ -1,12 +0,0 @@ -0xA0 mute # Fn+F9 -0xAE volumedown # Fn+Left -0xAF search # Fn+F3 -0xB0 volumeup # Fn+Right -0xB1 battery # Fn+F10 Info -0xB3 suspend # Fn+F12 -0xDF sleep # Fn+F4 -# 0xE2 bluetooth # satellite dish2 -0xE4 f21 # Fn+F5 Touchpad toggle -0xF6 wlan # Fn+F6 -0xF7 reserved # Fn+Down brightness down -0xF8 reserved # Fn+Up brightness up diff --git a/keymaps/logitech-usb b/keymaps/logitech-usb deleted file mode 100644 index b575aa7c47..0000000000 --- a/keymaps/logitech-usb +++ /dev/null @@ -1,6 +0,0 @@ -0x90001 shop # Shopping -0x90002 config # iTouch -0x90003 finance # Finance -0x90004 prog1 # My Sites -0x90005 prog2 # Community -0xC0183 media # Media diff --git a/keymaps/logitech-wave b/keymaps/logitech-wave deleted file mode 100644 index 781dbe26f7..0000000000 --- a/keymaps/logitech-wave +++ /dev/null @@ -1,16 +0,0 @@ -0x9001C scale # expo -0x9001F zoomout # zoom out -0x90020 zoomin # zoom in -0x9003D prog1 # gadget -0x90005 camera # camera -0x90018 media # media center -0x90041 wordprocessor # Fn+F1 (Word) -0x90042 spreadsheet # Fn+F2 (Excel) -0x90043 calendar # Fn+F3 (calendar) -0x90044 prog2 # Fn+F4 (program a) -0x90045 prog3 # Fn+F5 (program b) -0x90046 prog4 # Fn+F6 (program c) -0x90048 messenger # Fn+F8 (MSN messenger) -0x9002D find # Fn+F10 (search www) -0x9004B search # Fn+F11 (search PC) -0x9004C ejectclosecd # Fn+F12 (eject) diff --git a/keymaps/logitech-wave-cordless b/keymaps/logitech-wave-cordless deleted file mode 100644 index b40c4dbff7..0000000000 --- a/keymaps/logitech-wave-cordless +++ /dev/null @@ -1,15 +0,0 @@ -0xD4 zoomin -0xCC zoomout -0xC0183 media -0xC1005 camera -0xC101F zoomout -0xC1020 zoomin -0xC1041 wordprocessor -0xC1042 spreadsheet -0xC1043 calendar -0xC1044 prog2 # Fn+F4 (program a) -0xC1045 prog3 # Fn+F5 (program b) -0xC1046 prog4 # Fn+F6 (program c) -0xC1048 messenger -0xC104A find # Fn+F10 (search www) -0xC104C ejectclosecd diff --git a/keymaps/logitech-wave-pro-cordless b/keymaps/logitech-wave-pro-cordless deleted file mode 100644 index e7aa02206c..0000000000 --- a/keymaps/logitech-wave-pro-cordless +++ /dev/null @@ -1,12 +0,0 @@ -0xC01B6 camera -0xC0183 media -0xC0184 wordprocessor -0xC0186 spreadsheet -0xC018E calendar -0xC0223 homepage -0xC01BC messenger -0xC018A mail -0xC0221 search -0xC00B8 ejectcd -0xC022D zoomin -0xC022E zoomout diff --git a/keymaps/maxdata-pro_7000 b/keymaps/maxdata-pro_7000 deleted file mode 100644 index 0d5bbf3ce5..0000000000 --- a/keymaps/maxdata-pro_7000 +++ /dev/null @@ -1,9 +0,0 @@ -0x97 prog2 -0x9F prog1 -0xA0 mute # Fn+F5 -0x82 www -0xEC email -0xAE volumedown # Fn+Down -0xB0 volumeup # Fn+Up -0xDF suspend # Fn+F2 -0xF5 help diff --git a/keymaps/medion-fid2060 b/keymaps/medion-fid2060 deleted file mode 100644 index 75b1647e43..0000000000 --- a/keymaps/medion-fid2060 +++ /dev/null @@ -1,2 +0,0 @@ -0x6B channeldown # Thottle Down -0x6D channelup # Thottle Up diff --git a/keymaps/medionnb-a555 b/keymaps/medionnb-a555 deleted file mode 100644 index b69618308b..0000000000 --- a/keymaps/medionnb-a555 +++ /dev/null @@ -1,4 +0,0 @@ -0x63 www # N button -0x66 prog1 # link 1 button -0x67 email # envelope button -0x69 prog2 # link 2 button diff --git a/keymaps/micro-star b/keymaps/micro-star deleted file mode 100644 index c283cde8bb..0000000000 --- a/keymaps/micro-star +++ /dev/null @@ -1,13 +0,0 @@ -0xA0 mute # Fn+F9 -0xAE volumedown # Fn+F7 -0xB0 volumeup # Fn+F8 -0xB2 www # e button -0xDF sleep # Fn+F12 -0xE2 bluetooth # satellite dish2 -0xE4 f21 # Fn+F3 Touchpad disable -0xEC email # envelope button -0xEE camera # Fn+F6 camera disable -0xF6 wlan # satellite dish1 -0xF7 brightnessdown # Fn+F4 -0xF8 brightnessup # Fn+F5 -0xF9 search diff --git a/keymaps/module-ibm b/keymaps/module-ibm deleted file mode 100644 index ee61b6cf3b..0000000000 --- a/keymaps/module-ibm +++ /dev/null @@ -1,16 +0,0 @@ -0x01 battery # Fn+F2 -0x02 screenlock # Fn+F3 -0x03 sleep # Fn+F4 -0x04 wlan # Fn+F5 -0x06 switchvideomode # Fn+F7 -0x07 zoom # Fn+F8 screen expand -0x08 f24 # Fn+F9 undock -0x0B suspend # Fn+F12 -0x0F brightnessup # Fn+Home -0x10 brightnessdown # Fn+End -0x11 kbdillumtoggle # Fn+PgUp - ThinkLight -0x13 zoom # Fn+Space -0x14 volumeup -0x15 volumedown -0x16 mute -0x17 prog1 # ThinkPad/ThinkVantage button (high keycode: "vendor") diff --git a/keymaps/module-lenovo b/keymaps/module-lenovo deleted file mode 100644 index ed31899d0f..0000000000 --- a/keymaps/module-lenovo +++ /dev/null @@ -1,17 +0,0 @@ -0x1 screenlock # Fn+F2 -0x2 battery # Fn+F3 -0x3 sleep # Fn+F4 -0x4 wlan # Fn+F5 -0x6 switchvideomode # Fn+F7 -0x7 f21 # Fn+F8 touchpadtoggle -0x8 f24 # Fn+F9 undock -0xB suspend # Fn+F12 -0xF brightnessup # Fn+Home -0x10 brightnessdown # Fn+End -0x11 kbdillumtoggle # Fn+PgUp - ThinkLight -0x13 zoom # Fn+Space -0x14 volumeup -0x15 volumedown -0x16 mute -0x17 prog1 # ThinkPad/ThinkVantage button (high keycode: "vendor") -0x1A f20 # Microphone mute button; should be micmute, but see https://mail.gnome.org/archives/commits-list/2013-January/msg05822.html diff --git a/keymaps/module-sony b/keymaps/module-sony deleted file mode 100644 index 5d3742b463..0000000000 --- a/keymaps/module-sony +++ /dev/null @@ -1,8 +0,0 @@ -0x06 mute # Fn+F2 -0x07 volumedown # Fn+F3 -0x08 volumeup # Fn+F4 -0x09 brightnessdown # Fn+F5 -0x0A brightnessup # Fn+F6 -0x0B switchvideomode # Fn+F7 -0x0E zoom # Fn+F10 -0x10 suspend # Fn+F12 diff --git a/keymaps/module-sony-old b/keymaps/module-sony-old deleted file mode 100644 index 596a34258a..0000000000 --- a/keymaps/module-sony-old +++ /dev/null @@ -1,2 +0,0 @@ -0x06 battery -0x07 mute diff --git a/keymaps/module-sony-vgn b/keymaps/module-sony-vgn deleted file mode 100644 index cb4ce33717..0000000000 --- a/keymaps/module-sony-vgn +++ /dev/null @@ -1,8 +0,0 @@ -0x00 brightnessdown # Fn+F5 -0x10 brightnessup # Fn+F6 -0x11 switchvideomode # Fn+F7 -0x12 zoomout -0x14 zoomin -0x15 suspend # Fn+F12 -0x17 prog1 -0x20 media diff --git a/keymaps/module-sony-vpc b/keymaps/module-sony-vpc deleted file mode 100644 index 1b52779535..0000000000 --- a/keymaps/module-sony-vpc +++ /dev/null @@ -1,4 +0,0 @@ -# 0x05 touchpad_toggle # fn_f1 -> KEY_TOUCHPAD_TOGGLE -0x05 f21 # fn_f1 -> KEY_F21 (The actual touchpad toggle) -0x0d zoomout # fn_f9 -0x0e zoomin # fn_f10 diff --git a/keymaps/olpc-xo b/keymaps/olpc-xo deleted file mode 100644 index 0fa497211a..0000000000 --- a/keymaps/olpc-xo +++ /dev/null @@ -1,74 +0,0 @@ -0x59 fn -0x81 fn_esc -0xF9 camera -0xF8 sound # Fn+CAMERA = Mic - - -# Function key mappings, as per -# http://dev.laptop.org/ticket/10213#comment:20 -# -# Unmodified F1-F8 produce F1-F8, so no remap necessary. -# Unmodified F9-F12 control brightness and volume. -0x43 brightnessdown -0x44 brightnessup -0x57 volumedown -0x58 volumeup - -# Fn-modified fkeys all produce the unmodified version of the key. -0xBB f1 -0xBC f2 -0xBD f3 -0xBE f4 -0xBF f5 -0xC0 f6 -0xC1 f7 -0xC2 f8 -0xC3 f9 -0xC4 f10 -0xD7 f11 -0xD8 f12 - - -# Using F13-F21 for the .5 F keys right now. -0xF7 f13 -0xF6 f14 -0xF5 f15 -0xF4 f16 -0xF3 f17 -0xF2 f18 -0xF1 f19 -0xF0 f20 -0xEF f21 - -0xEE chat -0xE4 chat # Just mapping Fn+Chat to Chat for now -0xDD menu # Frame -0xDA prog1 # Fn+Frame - -# The Fn of some keys is other keys -0xD3 delete -0xD2 insert -0xC9 pageup -0xD1 pagedown -0xC7 home -0xCF end - -# Language key - don't ask what they are doing as KEY_HP -0x73 hp -0x7E hp - -0xDB leftmeta # left grab -0xDC rightmeta # right grab -0x85 rightmeta # Right grab releases on a different scancode -0xD6 kbdillumtoggle # Fn+Space -0x69 switchvideomode # Brightness key - -# Game keys -0x65 kp8 # up -0x66 kp2 # down -0x67 kp4 # left -0x68 kp6 # right -0xE5 kp9 # pgup -0xE6 kp3 # pgdn -0xE7 kp7 # home -0xE8 kp1 # end diff --git a/keymaps/onkyo b/keymaps/onkyo deleted file mode 100644 index 8fc4cffa92..0000000000 --- a/keymaps/onkyo +++ /dev/null @@ -1,14 +0,0 @@ -0xA0 mute # Fn+D -0xAE volumedown # Fn+F -0xB0 volumeup # Fn+G -0xDF sleep # Fn+W -0xE0 bluetooth # Fn+H -0xE2 cyclewindows # Fn+Esc -0xEE battery # Fn+Q -0xF0 media # Fn+R -0xF5 switchvideomode # Fn+E -0xF6 camera # Fn+T -0xF7 f21 # Fn+Y (touchpad toggle) -0xF8 brightnessup # Fn+S -0xF9 brightnessdown # Fn+A -0xFB wlan # Fn+J diff --git a/keymaps/oqo-model2 b/keymaps/oqo-model2 deleted file mode 100644 index b7f4851abe..0000000000 --- a/keymaps/oqo-model2 +++ /dev/null @@ -1,5 +0,0 @@ -0x8E wlan -0xF0 switchvideomode -0xF1 mute -0xF2 volumedown -0xF3 volumeup diff --git a/keymaps/samsung-other b/keymaps/samsung-other deleted file mode 100644 index d950c2cbd9..0000000000 --- a/keymaps/samsung-other +++ /dev/null @@ -1,14 +0,0 @@ -0x74 prog1 # User key -0x75 www -0x78 mail -0x82 switchvideomode # Fn+F4 CRT/LCD (high keycode: "displaytoggle") -0x83 battery # Fn+F2 -0x84 prog1 # Fn+F5 backlight on/off -0x86 wlan # Fn+F9 -0x88 brightnessup # Fn+Up -0x89 brightnessdown # Fn+Down -0xB1 prog2 # Fn+F7 run Samsung Magic Doctor (keypressed event is generated twice) -0xB3 prog3 # Fn+F8 switch power mode (battery/dynamic/performance) -0xB4 wlan # Fn+F9 (X60P) -0xF7 f22 # Fn+F10 Touchpad on -0xF9 f23 # Fn+F10 Touchpad off diff --git a/keymaps/samsung-series-3 b/keymaps/samsung-series-3 deleted file mode 100644 index 303a428b47..0000000000 --- a/keymaps/samsung-series-3 +++ /dev/null @@ -1,3 +0,0 @@ -0xCE prog1 # Fn+F1 launch control setting -0xB3 prog2 # Fn+F11 performance mode -0xD5 wlan # Fn+F12 Wi-Fi toggle diff --git a/keymaps/samsung-series-9 b/keymaps/samsung-series-9 deleted file mode 100644 index c0712f02a0..0000000000 --- a/keymaps/samsung-series-9 +++ /dev/null @@ -1,5 +0,0 @@ -0x96 kbdillumup # Fn+F8 keyboard backlight up -0x97 kbdillumdown # Fn+F7 keyboard backlight down -0xD5 wlan # Fn+F12 Wi-Fi toggle -0xCE prog1 # Fn+F1 performance mode -0x8D prog2 # Fn+F6 battery life extender diff --git a/keymaps/samsung-sq1us b/keymaps/samsung-sq1us deleted file mode 100644 index ea2141ef84..0000000000 --- a/keymaps/samsung-sq1us +++ /dev/null @@ -1,7 +0,0 @@ -0xD4 menu -0xD8 f1 -0xD9 f10 -0xD6 f3 -0xD7 f9 -0xE4 f5 -0xEE f11 diff --git a/keymaps/samsung-sx20s b/keymaps/samsung-sx20s deleted file mode 100644 index 9d954ee415..0000000000 --- a/keymaps/samsung-sx20s +++ /dev/null @@ -1,4 +0,0 @@ -0x74 mute -0x75 mute -0x77 f22 # Touchpad on -0x79 f23 # Touchpad off diff --git a/keymaps/toshiba-satellite_a100 b/keymaps/toshiba-satellite_a100 deleted file mode 100644 index 22007be71b..0000000000 --- a/keymaps/toshiba-satellite_a100 +++ /dev/null @@ -1,2 +0,0 @@ -0xA4 stopcd -0xB2 www diff --git a/keymaps/toshiba-satellite_a110 b/keymaps/toshiba-satellite_a110 deleted file mode 100644 index 1429409351..0000000000 --- a/keymaps/toshiba-satellite_a110 +++ /dev/null @@ -1,10 +0,0 @@ -0x92 stop -0x93 www -0x94 media -0x9E f22 # Touchpad on -0x9F f23 # Touchpad off -0xB9 nextsong -0xD9 brightnessup -0xEE screenlock -0xF4 previoussong -0xF7 playpause diff --git a/keymaps/toshiba-satellite_m30x b/keymaps/toshiba-satellite_m30x deleted file mode 100644 index 26e0bbd939..0000000000 --- a/keymaps/toshiba-satellite_m30x +++ /dev/null @@ -1,6 +0,0 @@ -0xef brightnessdown -0xd9 brightnessup -0xee screenlock -0x93 media -0x9e f22 # touchpad enable -0x9f f23 # touchpad disable diff --git a/keymaps/zepto-znote b/keymaps/zepto-znote deleted file mode 100644 index cf72fda47b..0000000000 --- a/keymaps/zepto-znote +++ /dev/null @@ -1,11 +0,0 @@ -0x93 switchvideomode # Fn+F3 Toggle Video Output -0x95 brightnessdown # Fn+F4 Brightness Down -0x91 brightnessup # Fn+F5 Brightness Up -0xA5 f23 # Fn+F6 Disable Touchpad -0xA6 f22 # Fn+F6 Enable Touchpad -0xA7 bluetooth # Fn+F10 Enable Bluetooth -0XA9 bluetooth # Fn+F10 Disable Bluetooth -0xF1 wlan # RF Switch Off -0xF2 wlan # RF Switch On -0xF4 prog1 # P1 Button -0xF3 prog2 # P2 Button diff --git a/src/udev/keymap/.gitignore b/src/udev/keymap/.gitignore deleted file mode 100644 index 4567584f4e..0000000000 --- a/src/udev/keymap/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -keyboard-force-release.sh -keys-from-name.gperf -keys-from-name.h -keys-to-name.h -keys.txt diff --git a/src/udev/keymap/95-keyboard-force-release.rules b/src/udev/keymap/95-keyboard-force-release.rules deleted file mode 100644 index 8bfe17d679..0000000000 --- a/src/udev/keymap/95-keyboard-force-release.rules +++ /dev/null @@ -1,60 +0,0 @@ -# Set model specific atkbd force_release quirk -# -# Several laptops have hotkeys which don't generate release events, -# which can cause problems with software key repeat. -# The atkbd driver has a quirk handler for generating synthetic -# release events, which can be configured via sysfs since 2.6.32. -# Simply add a file with a list of scancodes for your laptop model -# in /usr/lib/udev/keymaps, and add a rule here. -# If the hotkeys also need a keymap assignment you can copy the -# scancodes from the keymap file, otherwise you can run -# /usr/lib/udev/keymap -i /dev/input/eventX -# on a Linux vt to find out. - -ACTION=="remove", GOTO="force_release_end" -SUBSYSTEM!="serio", GOTO="force_release_end" -KERNEL!="serio*", GOTO="force_release_end" -DRIVER!="atkbd", GOTO="force_release_end" - -ENV{DMI_VENDOR}="$attr{[dmi/id]sys_vendor}" - -ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", RUN+="keyboard-force-release.sh $devpath samsung-other" -ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*90X3A*|*900X3*|*900X4*", RUN+="keyboard-force-release.sh $devpath samsung-series-9" -ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*300E5*|*300E4*|*300E7*|*270E5*|*270E4*", RUN+="keyboard-force-release.sh $devpath samsung-series-3" - -ENV{DMI_VENDOR}=="Dell Inc.", ATTR{[dmi/id]product_name}=="Studio 1557|Studio 1558", RUN+="keyboard-force-release.sh $devpath common-volume-keys" -ENV{DMI_VENDOR}=="Dell Inc.", ATTR{[dmi/id]product_name}=="*Latitude*|*Precision*", RUN+="keyboard-force-release.sh $devpath dell-touchpad" -ENV{DMI_VENDOR}=="Dell Inc.", ATTR{[dmi/id]product_name}=="XPS*", RUN+="keyboard-force-release.sh $devpath dell-xps" - -ENV{DMI_VENDOR}=="FUJITSU SIEMENS", ATTR{[dmi/id]product_name}=="AMILO*", RUN+="keyboard-force-release.sh $devpath common-volume-keys" - -ENV{DMI_VENDOR}=="FOXCONN", ATTR{[dmi/id]product_name}=="QBOOK", RUN+="keyboard-force-release.sh $devpath common-volume-keys" - -ENV{DMI_VENDOR}=="MTC", ATTR{[dmi/id]product_version}=="A0", RUN+="keyboard-force-release.sh $devpath common-volume-keys" - -ENV{DMI_VENDOR}=="Mio Technology", ATTR{[dmi/id]product_name}=="N890", RUN+="keyboard-force-release.sh $devpath common-volume-keys" - -ENV{DMI_VENDOR}=="PEGATRON CORP.", ATTR{[dmi/id]product_name}=="Spring Peak", RUN+="keyboard-force-release.sh $devpath common-volume-keys" - -ENV{DMI_VENDOR}=="TOSHIBA", ATTR{[dmi/id]product_name}=="Satellite [uU]300*|Satellite Pro [uU]300*|Satellite [uU]305*|SATELLITE [uU]500*", RUN+="keyboard-force-release.sh $devpath common-volume-keys" - -ENV{DMI_VENDOR}=="Viooo Corporation", ATTR{[dmi/id]product_name}=="PT17", RUN+="keyboard-force-release.sh $devpath common-volume-keys" - -# These are all the HP laptops that setup a touchpad toggle key -ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*[pP][aA][vV][iI][lL][iI][oO][nN]*", RUN+="keyboard-force-release.sh $devpath hp-other" -ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*[tT][xX]2*", RUN+="keyboard-force-release.sh $devpath hp-other" -ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*2510p*|*2530p*|HP G60 Notebook PC|HDX9494NR", RUN+="keyboard-force-release.sh $devpath hp-other" - -ENV{DMI_VENDOR}=="Zepto", ATTR{[dmi/id]product_name}=="Znote 6615WD", RUN+="keyboard-force-release.sh $devpath common-volume-keys" - -ENV{DMI_VENDOR}=="Zepto", ATTR{[dmi/id]product_name}=="Znote", ATTR{[dmi/id]product_version}=="6625WD", RUN+="keyboard-force-release.sh $devpath common-volume-keys" - -ENV{DMI_VENDOR}=="HANNspree", ATTR{[dmi/id]product_name}=="SN10E100", RUN+="keyboard-force-release.sh $devpath common-volume-keys" - -ENV{DMI_VENDOR}=="GIGABYTE", ATTR{[dmi/id]product_name}=="i1520M", RUN+="keyboard-force-release.sh $devpath common-volume-keys" - -ENV{DMI_VENDOR}=="BenQ", ATTR{[dmi/id]product_name}=="*nScreen*|Joybook Lite*", RUN+="keyboard-force-release.sh $devpath common-volume-keys" - -ENV{DMI_VENDOR}=="DIXONSP", ATTR{[dmi/id]product_name}=="DIXON*", RUN+="keyboard-force-release.sh $devpath common-volume-keys" - -LABEL="force_release_end" diff --git a/src/udev/keymap/95-keymap.rules b/src/udev/keymap/95-keymap.rules deleted file mode 100644 index 4d6ec556c2..0000000000 --- a/src/udev/keymap/95-keymap.rules +++ /dev/null @@ -1,181 +0,0 @@ -# Set model specific hotkey keycodes. -# -# Key map overrides can be specified by either giving scancode/keyname pairs -# directly as keymap arguments (if there are just one or two to change), or as -# a file name (in /usr/lib/udev/keymaps), which has to contain scancode/keyname -# pairs. - -ACTION=="remove", GOTO="keyboard_end" -KERNEL!="event*", GOTO="keyboard_end" -ENV{ID_INPUT_KEY}=="", GOTO="keyboard_end" -SUBSYSTEMS=="bluetooth", GOTO="keyboard_end" - -SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id" -SUBSYSTEMS=="usb", GOTO="keyboard_usbcheck" -GOTO="keyboard_modulecheck" - -# -# The following are external USB keyboards -# - -LABEL="keyboard_usbcheck" - -ENV{ID_VENDOR}=="Genius", ENV{ID_MODEL_ID}=="0708", ENV{ID_USB_INTERFACE_NUM}=="01", RUN+="keymap $name genius-slimstar-320" -ENV{ID_VENDOR}=="Logitech*", ATTRS{name}=="Logitech USB Multimedia Keyboard", RUN+="keymap $name logitech-wave" -ENV{ID_VENDOR}=="Logitech*", ATTRS{name}=="Logitech USB Receiver", RUN+="keymap $name logitech-wave-cordless" -ENV{ID_VENDOR}=="Logitech*", ATTRS{name}=="* Logitech USB Keyboard*", RUN+="keymap $name logitech-usb" -# Logitech Cordless Wave Pro looks slightly weird; some hotkeys are coming through the mouse interface -ENV{ID_VENDOR_ID}=="046d", ENV{ID_MODEL_ID}=="c52[9b]", ATTRS{name}=="Logitech USB Receiver", RUN+="keymap $name logitech-wave-pro-cordless" - -ENV{ID_VENDOR}=="Lite-On_Technology_Corp*", ATTRS{name}=="Lite-On Technology Corp. ThinkPad USB Keyboard with TrackPoint", RUN+="keymap $name lenovo-thinkpad-usb-keyboard-trackpoint" -ENV{ID_VENDOR_ID}=="04b3", ENV{ID_MODEL_ID}=="301[89]", RUN+="keymap $name ibm-thinkpad-usb-keyboard-trackpoint" - -ENV{ID_VENDOR}=="Microsoft", ENV{ID_MODEL_ID}=="00db", RUN+="keymap $name 0xc022d zoomin 0xc022e zoomout" - -GOTO="keyboard_end" - -# -# The following are exposed as separate input devices with low key codes, thus -# we need to check their input device product name -# - -LABEL="keyboard_modulecheck" - -ENV{DMI_VENDOR}="$attr{[dmi/id]sys_vendor}" -ENV{DMI_VENDOR}=="", GOTO="keyboard_end" - -ENV{DMI_VENDOR}=="LENOVO*", KERNELS=="input*", ATTRS{name}=="ThinkPad Extra Buttons", RUN+="keymap $name module-lenovo" -ENV{DMI_VENDOR}=="LENOVO*", KERNELS=="input*", ATTRS{name}=="Ideapad extra buttons", RUN+="keymap $name 0x42 f23 0x43 f22" - -ENV{DMI_VENDOR}=="IBM*", KERNELS=="input*", ATTRS{name}=="ThinkPad Extra Buttons", RUN+="keymap $name module-ibm" -ENV{DMI_VENDOR}=="Sony*", KERNELS=="input*", ATTRS{name}=="Sony Vaio Keys", RUN+="keymap $name module-sony" -ENV{DMI_VENDOR}=="Acer*", KERNELS=="input*", ATTRS{name}=="Acer WMI hotkeys", RUN+="keymap $name 0x82 f21" -ENV{DMI_VENDOR}=="MICRO-STAR*|Micro-Star*", KERNELS=="input*", ATTRS{name}=="MSI Laptop hotkeys", RUN+="keymap $name 0x213 f22 0x214 f23" - -# Older Vaios have some different keys -ENV{DMI_VENDOR}=="Sony*", ATTR{[dmi/id]product_name}=="*PCG-C1*|*PCG-K25*|*PCG-F1*|*PCG-F2*|*PCG-F3*|*PCG-F4*|*PCG-F5*|*PCG-F6*|*PCG-FX*|*PCG-FRV*|*PCG-GR*|*PCG-TR*|*PCG-NV*|*PCG-Z*|*VGN-S360*", ATTRS{name}=="Sony Vaio Keys", RUN+="keymap $name module-sony-old" - -# Some Sony VGN/VPC models have yet another one -ENV{DMI_VENDOR}=="Sony*", ATTR{[dmi/id]product_name}=="VGN-AR71*|VGN-FW*|VGN-Z21*", ATTRS{name}=="Sony Vaio Keys", RUN+="keymap $name module-sony-vgn" -ENV{DMI_VENDOR}=="Sony*", ATTR{[dmi/id]product_name}=="VPC*", ATTRS{name}=="Sony Vaio Keys", RUN+="keymap $name module-sony-vpc" - - -# -# The following rules belong to standard i8042 AT keyboard with high key codes. -# - -DRIVERS=="atkbd", GOTO="keyboard_vendorcheck" -GOTO="keyboard_end" - -LABEL="keyboard_vendorcheck" - -ENV{DMI_VENDOR}=="Dell*", RUN+="keymap $name dell" -ENV{DMI_VENDOR}=="Dell*", ATTR{[dmi/id]product_name}=="Inspiron 910|Inspiron 1010|Inspiron 1011|Inspiron 1012|Inspiron 1110|Inspiron 1210", RUN+="keymap $name 0x84 wlan" -ENV{DMI_VENDOR}=="Dell*", ATTR{[dmi/id]product_name}=="Latitude XT2", RUN+="keymap $name dell-latitude-xt2" - -ENV{DMI_VENDOR}=="Compaq*", ATTR{[dmi/id]product_name}=="*E500*|*Evo N*", RUN+="keymap $name compaq-e_evo" - -ENV{DMI_VENDOR}=="LENOVO*", ATTR{[dmi/id]product_version}=="*3000*", RUN+="keymap $name lenovo-3000" -ENV{DMI_VENDOR}=="LENOVO*", ATTR{[dmi/id]product_version}=="ThinkPad X6*", ATTR{[dmi/id]product_version}=="* Tablet", RUN+="keymap $name lenovo-thinkpad_x6_tablet" -ENV{DMI_VENDOR}=="LENOVO*", ATTR{[dmi/id]product_version}=="ThinkPad X2* Tablet*", ATTR{[dmi/id]product_version}=="* Tablet", RUN+="keymap $name lenovo-thinkpad_x200_tablet" -ENV{DMI_VENDOR}=="LENOVO*", ATTR{[dmi/id]product_version}=="*IdeaPad*", RUN+="keymap $name lenovo-ideapad" -ENV{DMI_VENDOR}=="LENOVO*", ATTR{[dmi/id]product_name}=="S10-*", RUN+="keymap $name lenovo-ideapad" -ENV{DMI_VENDOR}=="LENOVO", ATTR{[dmi/id]product_version}=="*IdeaPad Y550*", RUN+="keymap $name 0x95 media 0xA3 play" -ENV{DMI_VENDOR}=="LENOVO", ATTR{[dmi/id]product_version}=="*Lenovo V480*", RUN+="keymap $name 0xf1 f21" -# 0xf1 is touchpad toggle, 0xCE is microphone mute in Lenovo U300s -ENV{DMI_VENDOR}=="LENOVO", ATTR{[dmi/id]product_version}=="*IdeaPad U300s*", RUN+="keymap $name 0xf1 f21 0xCE f20" - -ENV{DMI_VENDOR}=="Hewlett-Packard*", RUN+="keymap $name hewlett-packard" -ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*[tT][aA][bB][lL][eE][tT]*", RUN+="keymap $name hewlett-packard-tablet" -ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*[pP][aA][vV][iI][lL][iI][oO][nN]*", RUN+="keymap $name hewlett-packard-pavilion" -ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*Compaq*|*EliteBook*|*2230s*", RUN+="keymap $name hewlett-packard-compaq_elitebook" -ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*Presario*CQ*", RUN+="keymap $name 0xD8 f21 0xD9 f21" -ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*2510p*|*2530p*|HP G60 Notebook PC", RUN+="keymap $name hewlett-packard-2510p_2530p" -ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*[tT][xX]2*", RUN+="keymap $name hewlett-packard-tx2" -ENV{DMI_VENDOR}=="Hewlett-Packard", ATTR{[dmi/id]product_name}=="Presario 2100*", RUN+="keymap $name hewlett-packard-presario-2100" -ENV{DMI_VENDOR}=="Hewlett-Packard", ATTR{[dmi/id]product_name}=="HP G62 Notebook PC", RUN+="keymap $name 0xB2 www" -ENV{DMI_VENDOR}=="Hewlett-Packard", ATTR{[dmi/id]product_name}=="HP ProBook*", RUN+="keymap $name 0xF8 rfkill 0xB2 www" -ENV{DMI_VENDOR}=="Hewlett-Packard", ATTR{[dmi/id]product_name}=="HP EliteBook 8440p", RUN+="keymap $name hewlett-packard_elitebook-8440p" -ENV{DMI_VENDOR}=="Hewlett-Packard", ATTR{[dmi/id]product_name}=="HP EliteBook 8460p", RUN+="keymap $name hewlett-packard_elitebook-8460p" -ENV{DMI_VENDOR}=="Hewlett-Packard", ATTR{[dmi/id]product_name}=="HDX9494NR", RUN+="keymap $name hewlett-packard-hdx9494nr" -# HP Pavilion dv6315ea has empty DMI_VENDOR -ATTR{[dmi/id]board_vendor}=="Quanta", ATTR{[dmi/id]board_name}=="30B7", ATTR{[dmi/id]board_version}=="65.2B", RUN+="keymap $name 0x88 media" # "quick play - -# Gateway clone of Acer Aspire One AOA110/AOA150 -ENV{DMI_VENDOR}=="Gateway*", ATTR{[dmi/id]product_name}=="*AOA1*", RUN+="keymap $name acer" - -ENV{DMI_VENDOR}=="Acer*", RUN+="keymap $name acer" -ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="Extensa*", ATTR{[dmi/id]product_name}=="*5210*|*5220*|*5610*|*5620*|*5720*", RUN+="keymap $name 0xEE screenlock" -ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="TravelMate*C3[01]0*", RUN+="keymap $name acer-travelmate_c300" -ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="TravelMate*6292*|TravelMate*8471*|TravelMate*4720*|TravelMate*7720*|Aspire 1810T*|AO751h|AO531h", RUN+="keymap $name 0xD9 bluetooth" -ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="TravelMate*4720*", RUN+="keymap $name 0xB2 www 0xEE screenlock" -ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="TravelMate 6593|Aspire 1640", RUN+="keymap $name 0xB2 www 0xEE screenlock" -ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="Aspire 6920", RUN+="keymap $name acer-aspire_6920" -ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="Aspire 5920G", RUN+="keymap $name acer-aspire_5920g" -ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="Aspire 5720*", RUN+="keymap $name acer-aspire_5720" -ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="Aspire 8930", RUN+="keymap $name acer-aspire_8930" -ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_serial}=="ZG8*", RUN+="keymap $name acer-aspire_5720" - -ENV{DMI_VENDOR}=="*BenQ*", ATTR{[dmi/id]product_name}=="*Joybook R22*", RUN+="keymap $name 0x6E wlan" - -ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*AMILO Pro V3205*", RUN+="keymap $name fujitsu-amilo_pro_v3205" -ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*AMILO Pa 2548*", RUN+="keymap $name fujitsu-amilo_pa_2548" -ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*ESPRIMO Mobile V5*", RUN+="keymap $name fujitsu-esprimo_mobile_v5" -ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*ESPRIMO Mobile V6*", RUN+="keymap $name fujitsu-esprimo_mobile_v6" -ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*AMILO Pro Edition V3505*", RUN+="keymap $name fujitsu-amilo_pro_edition_v3505" -ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*Amilo Si 1520*", RUN+="keymap $name fujitsu-amilo_si_1520" -ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="AMILO*M*", RUN+="keymap $name 0x97 prog2 0x9F prog1" -ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="Amilo Li 1718", RUN+="keymap $name 0xD6 wlan" -ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="AMILO Li 2732", RUN+="keymap $name fujitsu-amilo_li_2732" - -ENV{DMI_VENDOR}=="LG*", ATTR{[dmi/id]product_name}=="*X110*", RUN+="keymap $name lg-x110" - -ENV{DMI_VENDOR}=="MEDION*", ATTR{[dmi/id]product_name}=="*FID2060*", RUN+="keymap $name medion-fid2060" -ENV{DMI_VENDOR}=="MEDIONNB", ATTR{[dmi/id]product_name}=="A555*", RUN+="keymap $name medionnb-a555" - -ENV{DMI_VENDOR}=="MICRO-STAR*|Micro-Star*", RUN+="keymap $name micro-star" -ENV{DMI_VENDOR}=="MICRO-STAR*|Micro-Star*", ATTR{[dmi/id]product_name}=="GE60*|GE70*", RUN+="keymap $name 0xC2 ejectcd" - -# some MSI models generate ACPI/input events on the LNXVIDEO input devices, -# plus some extra synthesized ones on atkbd as an echo of actually changing the -# brightness; so ignore those atkbd ones, to avoid loops -ENV{DMI_VENDOR}=="MICRO-STAR*", ATTR{[dmi/id]product_name}=="*U-100*|*U100*|*N033", RUN+="keymap $name 0xF7 reserved 0xF8 reserved" - -# MSI Wind U90/U100 generates separate touchpad on/off keycodes so ignore touchpad toggle keycode -ENV{DMI_VENDOR}=="MICRO-STAR*", ATTR{[dmi/id]product_name}=="U90/U100", RUN+="keymap $name 0xE4 reserved" - -ENV{DMI_VENDOR}=="INVENTEC", ATTR{[dmi/id]product_name}=="SYMPHONY 6.0/7.0", RUN+="keymap $name inventec-symphony_6.0_7.0" - -ENV{DMI_VENDOR}=="MAXDATA", ATTR{[dmi/id]product_name}=="Pro 7000*", RUN+="keymap $name maxdata-pro_7000" - -ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", RUN+="keymap $name samsung-other" -ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*SX20S*", RUN+="keymap $name samsung-sx20s" -ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="SQ1US", RUN+="keymap $name samsung-sq1us" -ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*700Z*", RUN+="keymap $name 0xBA ejectcd 0x96 keyboardbrightnessup 0x97 keyboardbrightnessdown" -ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*700T*", RUN+="keymap $name 0xAD leftmeta" -ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*90X3A*|*900X3*|*900X4*", RUN+="keymap $name samsung-series-9" -ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*300E5*|*300E4*|*300E7*|*270E5*|*270E4*", RUN+="keymap $name samsung-series-3" - -ENV{DMI_VENDOR}=="TOSHIBA", ATTR{[dmi/id]product_name}=="SATELLITE A100", RUN+="keymap $name toshiba-satellite_a100" -ENV{DMI_VENDOR}=="TOSHIBA", ATTR{[dmi/id]product_name}=="Satellite A110", RUN+="keymap $name toshiba-satellite_a110" -ENV{DMI_VENDOR}=="TOSHIBA", ATTR{[dmi/id]product_name}=="Satellite M30X", RUN+="keymap $name toshiba-satellite_m30x" - -ENV{DMI_VENDOR}=="OQO Inc.*", ATTR{[dmi/id]product_name}=="OQO Model 2*", RUN+="keymap $name oqo-model2" - -ENV{DMI_VENDOR}=="ONKYO CORPORATION", ATTR{[dmi/id]product_name}=="ONKYOPC", RUN+="keymap $name onkyo" - -ENV{DMI_VENDOR}=="ASUS", RUN+="keymap $name asus" - -ENV{DMI_VENDOR}=="VIA", ATTR{[dmi/id]product_name}=="K8N800", ATTR{[dmi/id]product_version}=="VT8204B", RUN+="keymap $name 0x81 prog1" - -ENV{DMI_VENDOR}=="Zepto", ATTR{[dmi/id]product_name}=="Znote", ATTR{[dmi/id]product_version}=="62*|63*", RUN+="keymap $name zepto-znote" - -ENV{DMI_VENDOR}=="Everex", ATTR{[dmi/id]product_name}=="XT5000*", RUN+="keymap $name everex-xt5000" - -ENV{DMI_VENDOR}=="COMPAL", ATTR{[dmi/id]product_name}=="HEL80I", RUN+="keymap $name 0x84 wlan" - -ENV{DMI_VENDOR}=="OLPC", ATTR{[dmi/id]product_name}=="XO", RUN+="keymap $name olpc-xo" - -ENV{DMI_VENDOR}=="Alienware*", ATTR{[dmi/id]product_name}=="M14xR1", RUN+="keymap $name 0x8A ejectcd" - -LABEL="keyboard_end" diff --git a/src/udev/keymap/README.keymap.txt b/src/udev/keymap/README.keymap.txt deleted file mode 100644 index 2cf2a4e88c..0000000000 --- a/src/udev/keymap/README.keymap.txt +++ /dev/null @@ -1,97 +0,0 @@ -= The udev keymap tool = - -== Introduction == - -This udev extension configures computer model specific key mappings. This is -particularly necessary for the non-standard extra keys found on many laptops, -such as "brightness up", "next song", "www browser", or "suspend". Often these -are accessed with the Fn key. - -Every key produces a "scan code", which is highly vendor/model specific for the -nonstandard keys. This tool maintains mappings for these scan codes to standard -"key codes", which denote the "meaning" of the key. The key codes are defined -in /usr/include/linux/input.h. - -If some of your keys on your keyboard are not working at all, or produce the -wrong effect, then a very likely cause of this is that the scan code -> key -code mapping is incorrect on your computer. - -== Structure == - -udev-keymap consists of the following parts: - - keymaps/*:: mappings of scan codes to key code names - - 95-keymap.rules:: udev rules for mapping system vendor/product names and - input module names to one of the keymaps above - - keymap:: manipulate an evdev input device: - * write a key map file into a device (used by udev rules) - * dump current scan → key code mapping - * interactively display scan and key codes of pressed keys - - findkeyboards:: display evdev input devices which belong to actual keyboards, - i. e. those suitable for the keymap program - -== Fixing broken keys == - -In order to make a broken key work on your system and send it back to upstream -for inclusion you need to do the following steps: - - 1. Find the keyboard device. - - Run /usr/lib/udev/findkeyboards. This should always give you an "AT - keyboard" and possibly a "module". Some laptops (notably Thinkpads, Sonys, and - Acers) have multimedia/function keys on a separate input device instead of the - primary keyboard. The keyboard device should have a name like "input/event3". - In the following commands, the name will be written as "input/eventX" (replace - X with the appropriate number). - - 2. Find broken scan codes: - - sudo /usr/lib/udev/keymap -i input/eventX - - Press all multimedia/function keys and check if the key name that gets printed - out is plausible. If it is unknown or wrong, write down the scan code (looks - like "0x1E") and the intended functionality of this key. Look in - /usr/include/linux/input.h for an available KEY_XXXXX constant which most - closely approximates this functionality and write it down as the new key code. - - For example, you might press a key labeled "web browser" which currently - produces "unknown". Note down this: - - 0x1E www # Fn+F2 web browser - - Repeat that for all other keys. Write the resulting list into a file. Look at - /usr/lib/udev/keymaps/ for existing key map files and make sure that you use the - same structure. - - If the key only ever works once and then your keyboard (or the entire desktop) - gets stuck for a long time, then it is likely that the BIOS fails to send a - corresponding "key release" event after the key press event. Please note down - this case as well, as it can be worked around in - /usr/lib/udev/keymaps/95-keyboard-force-release.rules . - - 3. Find out your system vendor and product: - - cat /sys/class/dmi/id/sys_vendor - cat /sys/class/dmi/id/product_name - - 4. Generate a device dump with "udevadm info --export-db > /tmp/udev-db.txt". - - 6. Send the system vendor/product names, the key mapping from step 2, - and /tmp/udev-db.txt from step 4 to the linux-hotplug@vger.kernel.org mailing - list, so that they can be included in the next release. - -For local testing, copy your map file to /usr/lib/udev/keymaps/ with an appropriate -name, and add an appropriate udev rule to /usr/lib/udev/rules.d/95-keymap.rules: - - * If you selected an "AT keyboard", add the rule to the section after - 'LABEL="keyboard_vendorcheck"'. - - * If you selected a "module", add the rule to the top section where the - "ThinkPad Extra Buttons" are. - -== Author == - -keymap is written and maintained by Martin Pitt . diff --git a/src/udev/keymap/check-keymaps.sh b/src/udev/keymap/check-keymaps.sh deleted file mode 100755 index c4572745e0..0000000000 --- a/src/udev/keymap/check-keymaps.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash - -# check that all key names in keymaps/* are known in -# and that all key maps listed in the rules are valid and present in -# Makefile.am -SRCDIR=${1:-.} -KEYLIST=${2:-src/udev/keymap/keys.txt} -KEYMAPS_DIR=$SRCDIR/keymaps -RULES=$SRCDIR/src/udev/keymap/95-keymap.rules - -[ -e "$KEYLIST" ] || { - echo "need $KEYLIST please build first" >&2 - exit 1 -} - -missing=$(join -v 2 <(awk '{print tolower(substr($1,5))}' $KEYLIST | sort -u) \ - <(grep -hv '^#' ${KEYMAPS_DIR}/*| awk '{print $2}' | sort -u)) -[ -z "$missing" ] || { - echo "ERROR: unknown key names in keymaps/*:" >&2 - echo "$missing" >&2 - exit 1 -} - -# check that all maps referred to in $RULES exist -maps=$(sed -rn '/keymap \$name/ { s/^.*\$name ([^"[:space:]]+).*$/\1/; p }' $RULES) -for m in $maps; do - # ignore inline mappings - [ "$m" = "${m#0x}" ] || continue - - [ -e ${KEYMAPS_DIR}/$m ] || { - echo "ERROR: unknown map name in $RULES: $m" >&2 - exit 1 - } - grep -q "keymaps/$m\>" $SRCDIR/Makefile.am || { - echo "ERROR: map file $m is not added to Makefile.am" >&2 - exit 1 - } -done diff --git a/src/udev/keymap/findkeyboards b/src/udev/keymap/findkeyboards deleted file mode 100755 index c6b50d12d0..0000000000 --- a/src/udev/keymap/findkeyboards +++ /dev/null @@ -1,68 +0,0 @@ -#!/bin/sh -e -# Find "real" keyboard devices and print their device path. -# Author: Martin Pitt -# -# Copyright (C) 2009, Canonical Ltd. -# -# 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. - -# returns OK if $1 contains $2 -strstr() { - [ "${1#*$2*}" != "$1" ] -} - -# returns OK if $1 contains $2 at the beginning -str_starts() { - [ "${1#$2*}" != "$1" ] -} - -str_line_starts() { - while read a; do str_starts "$a" "$1" && return 0;done - return 1; -} - -# print a list of input devices which are keyboard-like -keyboard_devices() { - # standard AT keyboard - for dev in `udevadm trigger --dry-run --verbose --property-match=ID_INPUT_KEYBOARD=1`; do - env=`udevadm info --query=env --path=$dev` - # filter out non-event devices, such as the parent input devices which have no devnode - if ! echo "$env" | str_line_starts 'DEVNAME='; then - continue - fi - walk=`udevadm info --attribute-walk --path=$dev` - if strstr "$walk" 'DRIVERS=="atkbd"'; then - echo -n 'AT keyboard: ' - elif echo "$env" | str_line_starts 'ID_USB_DRIVER=usbhid'; then - echo -n 'USB keyboard: ' - else - echo -n 'Unknown type: ' - fi - udevadm info --query=name --path=$dev - done - - # modules - module=$(udevadm trigger --verbose --dry-run --subsystem-match=input --attr-match=name='*Extra Buttons') - module="$module - $(udevadm trigger --verbose --dry-run --subsystem-match=input --attr-match=name='*extra buttons')" - module="$module - $(udevadm trigger --verbose --dry-run --subsystem-match=input --attr-match=name='Sony Vaio Keys')" - for m in $module; do - for evdev in $m/event*/dev; do - if [ -e "$evdev" ]; then - echo -n 'module: ' - udevadm info --query=name --path=${evdev%%/dev} - fi - done - done -} - -keyboard_devices diff --git a/src/udev/keymap/keyboard-force-release.sh.in b/src/udev/keymap/keyboard-force-release.sh.in deleted file mode 100755 index b82674840f..0000000000 --- a/src/udev/keymap/keyboard-force-release.sh.in +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh -e -# read list of scancodes, convert hex to decimal and -# append to the atkbd force_release sysfs attribute -# $1 sysfs devpath for serioX -# $2 file with scancode list (hex or dec) - -case "$2" in - /*) scf="$2" ;; - *) scf="@udevlibexecdir@/keymaps/force-release/$2" ;; -esac - -read attr <"/sys/$1/force_release" -while read scancode dummy; do - case "$scancode" in - \#*) ;; - *) - scancode=$(($scancode)) - attr="$attr${attr:+,}$scancode" - ;; - esac -done <"$scf" -echo "$attr" >"/sys/$1/force_release" diff --git a/src/udev/keymap/keymap.c b/src/udev/keymap/keymap.c deleted file mode 100644 index ae0a19d3a3..0000000000 --- a/src/udev/keymap/keymap.c +++ /dev/null @@ -1,453 +0,0 @@ -/* - * keymap - dump keymap of an evdev device or set a new keymap from a file - * - * Based on keyfuzz by Lennart Poettering - * Adapted for udev-extras by Martin Pitt - * - * Copyright (C) 2006, Lennart Poettering - * Copyright (C) 2009, Canonical Ltd. - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static const struct key* lookup_key (const char *str, unsigned int len); - -#include "keys-from-name.h" -#include "keys-to-name.h" -#include "macro.h" -#include "util.h" - -#define MAX_SCANCODES 1024 - -static int evdev_open(const char *dev) -{ - int fd; - char fn[PATH_MAX]; - - if (!startswith(dev, "/dev")) { - snprintf(fn, sizeof(fn), "/dev/%s", dev); - dev = fn; - } - - if ((fd = open(dev, O_RDWR)) < 0) { - fprintf(stderr, "error open('%s'): %m\n", dev); - return -1; - } - return fd; -} - -static int evdev_get_keycode(int fd, unsigned scancode, int e) -{ - unsigned codes[2]; - - codes[0] = scancode; - if (ioctl(fd, EVIOCGKEYCODE, codes) < 0) { - if (e && errno == EINVAL) { - return -2; - } else { - fprintf(stderr, "EVIOCGKEYCODE for scan code 0x%x: %m\n", scancode); - return -1; - } - } - return codes[1]; -} - -static int evdev_set_keycode(int fd, unsigned scancode, int keycode) -{ - unsigned codes[2]; - - codes[0] = scancode; - codes[1] = (unsigned) keycode; - - if (ioctl(fd, EVIOCSKEYCODE, codes) < 0) { - fprintf(stderr, "EVIOCSKEYCODE: %m\n"); - return -1; - } - return 0; -} - -static int evdev_driver_version(int fd, char *v, size_t l) -{ - int version; - - if (ioctl(fd, EVIOCGVERSION, &version)) { - fprintf(stderr, "EVIOCGVERSION: %m\n"); - return -1; - } - - snprintf(v, l, "%i.%i.%i.", version >> 16, (version >> 8) & 0xff, version & 0xff); - return 0; -} - -static int evdev_device_name(int fd, char *n, size_t l) -{ - if (ioctl(fd, EVIOCGNAME(l), n) < 0) { - fprintf(stderr, "EVIOCGNAME: %m\n"); - return -1; - } - return 0; -} - -/* Return a lower-case string with KEY_ prefix removed */ -static const char* format_keyname(const char* key) { - static char result[101]; - const char* s; - int len; - - for (s = key+4, len = 0; *s && len < 100; ++len, ++s) - result[len] = tolower(*s); - result[len] = '\0'; - return result; -} - -static int dump_table(int fd) { - char version[256], name[256]; - unsigned scancode; - int r = -1; - - if (evdev_driver_version(fd, version, sizeof(version)) < 0) - goto fail; - - if (evdev_device_name(fd, name, sizeof(name)) < 0) - goto fail; - - printf("### evdev %s, driver '%s'\n", version, name); - - r = 0; - for (scancode = 0; scancode < MAX_SCANCODES; scancode++) { - int keycode; - - if ((keycode = evdev_get_keycode(fd, scancode, 1)) < 0) { - if (keycode == -2) - continue; - r = -1; - break; - } - - if (keycode < KEY_MAX && key_names[keycode]) - printf("0x%03x %s\n", scancode, format_keyname(key_names[keycode])); - else - printf("0x%03x 0x%03x\n", scancode, keycode); - } -fail: - return r; -} - -static void set_key(int fd, const char* scancode_str, const char* keyname) -{ - unsigned scancode; - char *endptr; - char t[105] = "KEY_UNKNOWN"; - const struct key *k; - - scancode = (unsigned) strtol(scancode_str, &endptr, 0); - if (*endptr != '\0') { - fprintf(stderr, "ERROR: Invalid scancode\n"); - exit(1); - } - - snprintf(t, sizeof(t), "KEY_%s", keyname); - - if (!(k = lookup_key(t, strlen(t)))) { - fprintf(stderr, "ERROR: Unknown key name '%s'\n", keyname); - exit(1); - } - - if (evdev_set_keycode(fd, scancode, k->id) < 0) - fprintf(stderr, "setting scancode 0x%2X to key code %i failed\n", - scancode, k->id); - else - printf("setting scancode 0x%2X to key code %i\n", - scancode, k->id); -} - -static int merge_table(int fd, FILE *f) { - int r = 0; - int line = 0; - - while (!feof(f)) { - char s[256], *p; - unsigned scancode; - int new_keycode, old_keycode; - - if (!fgets(s, sizeof(s), f)) - break; - - line++; - p = s+strspn(s, "\t "); - if (*p == '#' || *p == '\n') - continue; - - if (sscanf(p, "%i %i", &scancode, &new_keycode) != 2) { - char t[105] = "KEY_UNKNOWN"; - const struct key *k; - - if (sscanf(p, "%i %100s", &scancode, t+4) != 2) { - fprintf(stderr, "WARNING: Parse failure at line %i, ignoring.\n", line); - r = -1; - continue; - } - - if (!(k = lookup_key(t, strlen(t)))) { - fprintf(stderr, "WARNING: Unknown key '%s' at line %i, ignoring.\n", t, line); - r = -1; - continue; - } - - new_keycode = k->id; - } - - - if ((old_keycode = evdev_get_keycode(fd, scancode, 0)) < 0) { - r = -1; - continue; - } - - if (evdev_set_keycode(fd, scancode, new_keycode) < 0) { - r = -1; - continue; - } - - if (new_keycode != old_keycode) - fprintf(stderr, "Remapped scancode 0x%02x to 0x%02x (prior: 0x%02x)\n", - scancode, new_keycode, old_keycode); - } - - fclose(f); - return r; -} - - -/* read one event; return 1 if valid */ -static int read_event(int fd, struct input_event* ev) -{ - int ret; - ret = read(fd, ev, sizeof(struct input_event)); - - if (ret < 0) { - perror("read"); - return 0; - } - if (ret != sizeof(struct input_event)) { - fprintf(stderr, "did not get enough data for event struct, aborting\n"); - return 0; - } - - return 1; -} - -static void print_key(unsigned scancode, uint16_t keycode, int has_scan, int has_key) -{ - const char *keyname; - - /* ignore key release events */ - if (has_key == 1) - return; - - if (has_key == 0 && has_scan != 0) { - fprintf(stderr, "got scan code event 0x%02X without a key code event\n", - scancode); - return; - } - - if (has_scan != 0) - printf("scan code: 0x%02X ", scancode); - else - printf("(no scan code received) "); - - keyname = key_names[keycode]; - if (keyname != NULL) - printf("key code: %s\n", format_keyname(keyname)); - else - printf("key code: %03X\n", keycode); -} - -static void interactive(int fd) -{ - struct input_event ev; - unsigned last_scan = 0; - uint16_t last_key = 0; - int has_scan; /* boolean */ - int has_key; /* 0: none, 1: release, 2: press */ - - /* grab input device */ - ioctl(fd, EVIOCGRAB, 1); - puts("Press ESC to finish, or Control-C if this device is not your primary keyboard"); - - has_scan = has_key = 0; - while (read_event(fd, &ev)) { - /* Drivers usually send the scan code first, then the key code, - * then a SYN. Some drivers (like thinkpad_acpi) send the key - * code first, and some drivers might not send SYN events, so - * keep a robust state machine which can deal with any of those - */ - - if (ev.type == EV_MSC && ev.code == MSC_SCAN) { - if (has_scan) { - fputs("driver did not send SYN event in between key events; previous event:\n", - stderr); - print_key(last_scan, last_key, has_scan, has_key); - has_key = 0; - } - - last_scan = ev.value; - has_scan = 1; - /*printf("--- got scan %u; has scan %i key %i\n", last_scan, has_scan, has_key); */ - } - else if (ev.type == EV_KEY) { - if (has_key) { - fputs("driver did not send SYN event in between key events; previous event:\n", - stderr); - print_key(last_scan, last_key, has_scan, has_key); - has_scan = 0; - } - - last_key = ev.code; - has_key = 1 + ev.value; - /*printf("--- got key %hu; has scan %i key %i\n", last_key, has_scan, has_key);*/ - - /* Stop on ESC */ - if (ev.code == KEY_ESC && ev.value == 0) - break; - } - else if (ev.type == EV_SYN) { - /*printf("--- got SYN; has scan %i key %i\n", has_scan, has_key);*/ - print_key(last_scan, last_key, has_scan, has_key); - - has_scan = has_key = 0; - } - - } - - /* release input device */ - ioctl(fd, EVIOCGRAB, 0); -} - -_noreturn_ static void help(int error) -{ - const char* h = "Usage: keymap []\n" - " keymap scancode keyname [...]\n" - " keymap -i \n"; - if (error) { - fputs(h, stderr); - exit(2); - } else { - fputs(h, stdout); - exit(0); - } -} - -int main(int argc, char **argv) -{ - static const struct option options[] = { - { "help", no_argument, NULL, 'h' }, - { "interactive", no_argument, NULL, 'i' }, - {} - }; - int fd = -1; - int opt_interactive = 0; - int i; - - while (1) { - int option; - - option = getopt_long(argc, argv, "hi", options, NULL); - if (option == -1) - break; - - switch (option) { - case 'h': - help(0); - - case 'i': - opt_interactive = 1; - break; - default: - return 1; - } - } - - if (argc < optind+1) - help (1); - - if ((fd = evdev_open(argv[optind])) < 0) - return 3; - - /* one argument (device): dump or interactive */ - if (argc == optind+1) { - if (opt_interactive) - interactive(fd); - else - dump_table(fd); - return 0; - } - - /* two arguments (device, mapfile): set map file */ - if (argc == optind+2) { - const char *filearg = argv[optind+1]; - if (strchr(filearg, '/')) { - /* Keymap file argument is a path */ - FILE *f = fopen(filearg, "re"); - if (f) - merge_table(fd, f); - else - perror(filearg); - } else { - /* Keymap file argument is a filename */ - /* Open override file if present, otherwise default file */ - char keymap_path[PATH_MAX]; - FILE *f; - - snprintf(keymap_path, sizeof(keymap_path), "/etc/udev/keymaps/%s", filearg); - f = fopen(keymap_path, "re"); - if (f) { - merge_table(fd, f); - } else { - snprintf(keymap_path, sizeof(keymap_path), UDEVLIBEXECDIR "/keymaps/%s", filearg); - f = fopen(keymap_path, "re"); - if (f) - merge_table(fd, f); - else - perror(keymap_path); - } - } - return 0; - } - - /* more arguments (device, scancode/keyname pairs): set keys directly */ - if ((argc - optind - 1) % 2 == 0) { - for (i = optind+1; i < argc; i += 2) - set_key(fd, argv[i], argv[i+1]); - return 0; - } - - /* invalid number of arguments */ - help(1); - return 1; /* not reached */ -} -- cgit v1.2.1 From 0c3815773331b263713f4f7b9d80bc1ca159338e Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 16 Jul 2013 16:26:49 +0200 Subject: also remove keymaps-force-release directory --- keymaps-force-release/common-volume-keys | 3 --- keymaps-force-release/dell-touchpad | 1 - keymaps-force-release/dell-xps | 1 - keymaps-force-release/hp-other | 3 --- keymaps-force-release/samsung-other | 10 ---------- keymaps-force-release/samsung-series-3 | 2 -- keymaps-force-release/samsung-series-9 | 6 ------ 7 files changed, 26 deletions(-) delete mode 100644 keymaps-force-release/common-volume-keys delete mode 100644 keymaps-force-release/dell-touchpad delete mode 100644 keymaps-force-release/dell-xps delete mode 100644 keymaps-force-release/hp-other delete mode 100644 keymaps-force-release/samsung-other delete mode 100644 keymaps-force-release/samsung-series-3 delete mode 100644 keymaps-force-release/samsung-series-9 diff --git a/keymaps-force-release/common-volume-keys b/keymaps-force-release/common-volume-keys deleted file mode 100644 index e384a3b8f2..0000000000 --- a/keymaps-force-release/common-volume-keys +++ /dev/null @@ -1,3 +0,0 @@ -0xa0 # mute -0xae # volume down -0xb0 # volume up diff --git a/keymaps-force-release/dell-touchpad b/keymaps-force-release/dell-touchpad deleted file mode 100644 index 18e9bdee66..0000000000 --- a/keymaps-force-release/dell-touchpad +++ /dev/null @@ -1 +0,0 @@ -0x9E diff --git a/keymaps-force-release/dell-xps b/keymaps-force-release/dell-xps deleted file mode 100644 index 69f7899ad7..0000000000 --- a/keymaps-force-release/dell-xps +++ /dev/null @@ -1 +0,0 @@ -0x8C diff --git a/keymaps-force-release/hp-other b/keymaps-force-release/hp-other deleted file mode 100644 index 6621370095..0000000000 --- a/keymaps-force-release/hp-other +++ /dev/null @@ -1,3 +0,0 @@ -# list of scancodes (hex or decimal), optional comment -0xd8 # Touchpad off -0xd9 # Touchpad on diff --git a/keymaps-force-release/samsung-other b/keymaps-force-release/samsung-other deleted file mode 100644 index e9627af882..0000000000 --- a/keymaps-force-release/samsung-other +++ /dev/null @@ -1,10 +0,0 @@ -# list of scancodes (hex or decimal), optional comment -0x82 # Fn+F4 CRT/LCD -0x83 # Fn+F2 battery -0x84 # Fn+F5 backlight on/off -0x86 # Fn+F9 WLAN -0x88 # Fn+Up brightness up -0x89 # Fn+Down brightness down -0xB3 # Fn+F8 switch power mode (battery/dynamic/performance) -0xF7 # Fn+F10 Touchpad on -0xF9 # Fn+F10 Touchpad off diff --git a/keymaps-force-release/samsung-series-3 b/keymaps-force-release/samsung-series-3 deleted file mode 100644 index 63707508aa..0000000000 --- a/keymaps-force-release/samsung-series-3 +++ /dev/null @@ -1,2 +0,0 @@ -0xCE # Fn+F1 launch control setting -0xD5 # Fn+F12 Wi-Fi toggle diff --git a/keymaps-force-release/samsung-series-9 b/keymaps-force-release/samsung-series-9 deleted file mode 100644 index fa6a0b1d18..0000000000 --- a/keymaps-force-release/samsung-series-9 +++ /dev/null @@ -1,6 +0,0 @@ -# list of scancodes (hex or decimal), optional comment -0xCE # Fn+F8 keyboard backlight up -0x8D # Fn+F7 keyboard backlight down -0x97 # Fn+F12 Wi-Fi toggle -0x96 # Fn+F1 performance mode (?) -0xD5 # Fn+F6 battery life extender -- cgit v1.2.1 From 1b6bce89b3383904d0dab619dd38bff673f7286e Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Tue, 16 Jul 2013 16:53:35 +0200 Subject: keymap: re-add Logitech USB corded/cordless models These add back are the remaining 3 udev keymap rules which used name based instead of ID based matching. --- hwdb/60-keyboard.hwdb | 53 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index 569b9c74fe..8199b300cd 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -567,8 +567,57 @@ keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad U300s*:pvr* # Logitech ########################################################### -# Logitech Cordless Wave Pro -keyboard:usb:v046DpC52[9b]* +# iTouch +keyboard:usb:v046DpC308* + KEYBOARD_KEY_90001=shop # Shopping + KEYBOARD_KEY_90002=config # iTouch + KEYBOARD_KEY_90003=finance # Finance + KEYBOARD_KEY_90004=prog1 # My Sites + KEYBOARD_KEY_90005=prog2 # Community + KEYBOARD_KEY_C0183=media # Media + +# Cordless Desktop S510 +keyboard:usb:v046DpC50C* + KEYBOARD_KEY_d4=zoomin + KEYBOARD_KEY_cc=zoomout + +# Wave cordless +keyboard:usb:v046DpC317* + KEYBOARD_KEY_9001c=scale #expo + KEYBOARD_KEY_9001f=zoomout + KEYBOARD_KEY_90020=zoomin + KEYBOARD_KEY_9003d=prog1 #gadget + KEYBOARD_KEY_90005=camera + KEYBOARD_KEY_90018=media + KEYBOARD_KEY_90041=wordprocessor + KEYBOARD_KEY_90042=spreadsheet + KEYBOARD_KEY_90043=calendar + KEYBOARD_KEY_90044=prog2 #fn+f4 (program a) + KEYBOARD_KEY_90045=prog3 #fn+f5 (program b) + KEYBOARD_KEY_90046=prog4 #fn+f6 (program c) + KEYBOARD_KEY_90048=messenger #fn+f8 (msn messenger) + KEYBOARD_KEY_9002d=search #fn+f10 (search www) + KEYBOARD_KEY_9004b=find #fn+f11 (search pc) + KEYBOARD_KEY_9004c=ejectclosecd + +# Wave cordless +keyboard:usb:v046DpC517* + KEYBOARD_KEY_c101f zoomout + KEYBOARD_KEY_c1020 zoomin + KEYBOARD_KEY_c1005 camera + KEYBOARD_KEY_c0183 media + KEYBOARD_KEY_c1041 wordprocessor + KEYBOARD_KEY_c1042 spreadsheet + KEYBOARD_KEY_c1043 calendar + KEYBOARD_KEY_c1044 prog2 #fn+f4 (program a) + KEYBOARD_KEY_c1045 prog3 #fn+f5 (program b) + KEYBOARD_KEY_c1046 prog4 #fn+f6 (program c) + KEYBOARD_KEY_c1048 messenger #fn+f8 (msn messenger) + KEYBOARD_KEY_c104a find #fn+f10 (search www) + KEYBOARD_KEY_c104c ejectclosecd + +# Cordless Wave Pro +keyboard:usb:v046DpC52[9B]* KEYBOARD_KEY_0c01b6=camera KEYBOARD_KEY_0c0183=media KEYBOARD_KEY_0c0184=wordprocessor -- cgit v1.2.1 From 18d4e7c26e7806ac363d19989df7144d5058ce41 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 16 Jul 2013 17:34:33 +0200 Subject: update TODO --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index 735f1a7901..10f2b74df2 100644 --- a/TODO +++ b/TODO @@ -56,6 +56,8 @@ CGroup Rework Completion: Features: +* add rpm macros for applying tmpfiles --create after package installation + * when parsing calendar timestamps support the UTC timezone (even if we won't support arbitrary timezone specs, support UTC itself certainly makes sense), also support syntaxes such as +0200 * journalctl: add an output mode that looks like classic /var/log/messages, but also outputs the cursor of the last entry so that people can write scripts that can run iteratively and always process data that has been added since the last time. -- cgit v1.2.1 From a331b5e6d4724365bad9edeb9420c7e26e7f50da Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Fri, 28 Jun 2013 17:26:30 +0200 Subject: journalctl: Add support for showing messages from a previous boot Hi, I redid the boot ID look up to use enumerate_unique. This is quite fast if the cache is warm but painfully slow if it isn't. It has a slight chance of returning the wrong order if realtime clock jumps around. This one has to do n searches for every boot ID there is plus a sort, so it depends heavily on cache hotness. This is in contrast to the other way of look-up through filtering by a MESSAGE_ID, which only needs about 1 seek + whatever amount of relative IDs you want to walk. I also have a linked-list + (in-place) mergesort version of this patch, which has pretty much the same runtime. But since this one is using libc sorting and armortized allocation, I prefer this one. To summarize: The MESSAGE_ID way is a *lot* faster but can be incomplete due to rotation, while the enumerate+sort will find every boot ID out there but will be painfully slow for large journals and cold caches. You choose :P Jan --- TODO | 1 - man/journalctl.xml | 54 ++++++++--- shell-completion/bash/journalctl | 11 ++- src/journal/journalctl.c | 196 ++++++++++++++++++++++++++++++++++++--- 4 files changed, 235 insertions(+), 27 deletions(-) diff --git a/TODO b/TODO index 10f2b74df2..f5da81f527 100644 --- a/TODO +++ b/TODO @@ -356,7 +356,6 @@ Features: - journal-send.c, log.c: when the log socket is clogged, and we drop, count this and write a message about this when it gets unclogged again. - journal: find a way to allow dropping history early, based on priority, other rules - journal: When used on NFS, check payload hashes - - Introduce journalctl -b to show journal messages of a previous boot - journald: check whether it is OK if the client can still modify delivered journal entries - journal live copy, based on libneon (client) and libmicrohttpd (server) - journald: add kernel cmdline option to disable ratelimiting for debug purposes diff --git a/man/journalctl.xml b/man/journalctl.xml index b8b29b4cb5..0e779b952c 100644 --- a/man/journalctl.xml +++ b/man/journalctl.xml @@ -327,23 +327,51 @@ - - - - Show data only from - current boot. This will add a match - for _BOOT_ID= for - the current boot ID of the - kernel. + + + + Show messages from the specified + boot ID or from + current boot if no ID + is given. This will add a match for + _BOOT_ID=. + + The argument is a 128 bit ID given in + short or UUID form and optionally followed by + :n which identifies the nth + boot relative to the boot ID given to the left + of :. Supplying a negative + value for n will look for a past boot and a + positive value for a future boot. The boot IDs + are searched for in chronological order. If no + number is provided after :, + -1 is assumed. A value of 0 + is valid and equivalent to omitting + :0. + + Alternatively, the argument may constist + only of :n. In this case, a + positive value will look up the nth boot + starting from the beginning of the jouranl, a + negative value will look up a previous boot + relative to the current boot. :0 + will look for the current boot ID. Thus, + :1 is the first boot found in + the journal, :2 the second + and so on; while :-1 is the + previous boot, :-2 the boot + before that and so on. Omitting a value after + : will look for the previous + boot. - Show kernel messages from - current boot. This implies - and adds the match _TRANSPORT=kernel. + Show only kernel messages. This + implies and adds the match + _TRANSPORT=kernel. @@ -721,6 +749,10 @@ journalctl /dev/sda + Show all kernel logs from last boot: + + journalctl -k -b : + diff --git a/shell-completion/bash/journalctl b/shell-completion/bash/journalctl index 5ab59c9940..29bf6bca3f 100644 --- a/shell-completion/bash/journalctl +++ b/shell-completion/bash/journalctl @@ -37,19 +37,22 @@ __journal_fields=(MESSAGE{,_ID} PRIORITY CODE_{FILE,LINE,FUNC} _journalctl() { local field_vals= cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} local -A OPTS=( - [STANDALONE]='-a --all --full - --system --user - -b --this-boot --disk-usage -f --follow --header + [STANDALONE]='-a --all --full --system --user + --disk-usage -f --follow --header -h --help -l --local --new-id128 -m --merge --no-pager --no-tail -q --quiet --setup-keys --this-boot --verify --version --list-catalog --update-catalog' - [ARG]='-D --directory -F --field -o --output -u --unit --user-unit' + [ARG]='-b --boot --this-boot -D --directory -F --field + -o --output -u --unit --user-unit' [ARGUNKNOWN]='-c --cursor --interval -n --lines -p --priority --since --until --verify-key' ) if __contains_word "$prev" ${OPTS[ARG]} ${OPTS[ARGUNKNOWN]}; then case $prev in + --boot|--this-boot|-b) + comps=$(journalctl -F '_BOOT_ID' 2>/dev/null) + ;; --directory|-D) comps=$(compgen -d -- "$cur") compopt -o filenames diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 5f44fce080..38b2cdd572 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -70,7 +70,8 @@ static int arg_lines = -1; static bool arg_no_tail = false; static bool arg_quiet = false; static bool arg_merge = false; -static bool arg_this_boot = false; +static bool arg_boot_id = false; +static char *arg_boot_id_descriptor = NULL; static bool arg_dmesg = false; static const char *arg_cursor = NULL; static const char *arg_directory = NULL; @@ -103,6 +104,11 @@ static enum { ACTION_UPDATE_CATALOG } arg_action = ACTION_SHOW; +typedef struct boot_id_t { + sd_id128_t id; + uint64_t timestamp; +} boot_id_t; + static int help(void) { printf("%s [OPTIONS...] [MATCHES...]\n\n" @@ -113,8 +119,8 @@ static int help(void) { " --since=DATE Start showing entries newer or of the specified date\n" " --until=DATE Stop showing entries older or of the specified date\n" " -c --cursor=CURSOR Start showing entries from specified cursor\n" - " -b --this-boot Show data only from current boot\n" - " -k --dmesg Show kmsg log from current boot\n" + " -b --boot[=ID] Show data only from ID or current boot if unspecified\n" + " -k --dmesg Show kernel message log from current boot\n" " -u --unit=UNIT Show data only from the specified unit\n" " --user-unit=UNIT Show data only from the specified user session unit\n" " -p --priority=RANGE Show only messages within the specified priority range\n" @@ -199,7 +205,8 @@ static int parse_argv(int argc, char *argv[]) { { "new-id128", no_argument, NULL, ARG_NEW_ID128 }, { "quiet", no_argument, NULL, 'q' }, { "merge", no_argument, NULL, 'm' }, - { "this-boot", no_argument, NULL, 'b' }, + { "boot", optional_argument, NULL, 'b' }, + { "this-boot", optional_argument, NULL, 'b' }, /* deprecated */ { "dmesg", no_argument, NULL, 'k' }, { "system", no_argument, NULL, ARG_SYSTEM }, { "user", no_argument, NULL, ARG_USER }, @@ -232,7 +239,7 @@ static int parse_argv(int argc, char *argv[]) { assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "hefo:aln::qmbkD:p:c:u:F:xr", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "hefo:aln::qmb::kD:p:c:u:F:xr", options, NULL)) >= 0) { switch (c) { @@ -331,11 +338,17 @@ static int parse_argv(int argc, char *argv[]) { break; case 'b': - arg_this_boot = true; + if (optarg) + arg_boot_id_descriptor = optarg; + else if (optind < argc && argv[optind][0] != '-') { + arg_boot_id_descriptor = argv[optind]; + optind++; + } + arg_boot_id = true; break; case 'k': - arg_this_boot = arg_dmesg = true; + arg_boot_id = arg_dmesg = true; break; case ARG_SYSTEM: @@ -630,11 +643,170 @@ static int add_matches(sd_journal *j, char **args) { return 0; } -static int add_this_boot(sd_journal *j) { - if (!arg_this_boot) +static int boot_id_cmp(const void *a, const void *b) { + uint64_t _a, _b; + + _a = ((const boot_id_t *)a)->timestamp; + _b = ((const boot_id_t *)b)->timestamp; + + return _a < _b ? -1 : (_a > _b ? 1 : 0); +} + +static int get_relative_boot_id(sd_journal *j, sd_id128_t *boot_id, int relative) { + int r; + const void *data; + unsigned int id_count = 0; + size_t length, allocated = 0; + boot_id_t ref_boot_id, *id; + _cleanup_free_ boot_id_t *all_ids = NULL; + bool find_first_boot = false, ref_boot_found = false; + + assert(j); + assert(boot_id); + + if (relative == 0) + return 0; + + if (sd_id128_equal(*boot_id, SD_ID128_NULL) && relative > 0) { + find_first_boot = true; + relative--; + } + + r = sd_journal_query_unique(j, "_BOOT_ID"); + if (r < 0) + return r; + + SD_JOURNAL_FOREACH_UNIQUE(j, data, length) { + if (length < strlen("_BOOT_ID=")) + continue; + + if (!GREEDY_REALLOC(all_ids, allocated, id_count + 1)) + return log_oom(); + + id = &all_ids[id_count]; + + r = sd_id128_from_string(((const char *)data) + strlen("_BOOT_ID="), &id->id); + if (r < 0) { + continue; + } + + sd_journal_flush_matches(j); + r = sd_journal_add_match(j, data, length); + if (r < 0) + continue; + + r = sd_journal_seek_head(j); + if (r < 0) + continue; + + r = sd_journal_next(j); + if (r <= 0) + continue; + + r = sd_journal_get_realtime_usec(j, &id->timestamp); + if (r < 0) + continue; + + if (!find_first_boot && sd_id128_equal(id->id, *boot_id)) { + ref_boot_id = *id; + ref_boot_found = true; + } + + id_count++; + } + + *boot_id = SD_ID128_NULL; + sd_journal_flush_matches(j); + + if (id_count == 0 || (!find_first_boot && !ref_boot_found)) + return 0; + + qsort(all_ids, id_count, sizeof(boot_id_t), boot_id_cmp); + if (find_first_boot) + id = all_ids; + else + id = bsearch(&ref_boot_id, all_ids, id_count, sizeof(boot_id_t), boot_id_cmp); + + if (!id || (relative < 0 && ((id - all_ids) + relative) < 0) || + (relative >= 0 && (unsigned long)((id - all_ids) + relative) >= id_count)) return 0; - return add_match_this_boot(j); + id += relative; + *boot_id = id->id; + return 0; +} + +static int add_boot(sd_journal *j) { + char match[9+32+1] = "_BOOT_ID="; + char *marker; + sd_id128_t boot_id; + int r, relative = 0; + + assert(j); + + if (!arg_boot_id) + return 0; + + if (arg_boot_id_descriptor) { + marker = strchr(arg_boot_id_descriptor, ':'); + if (marker) { + *marker = '\0'; + marker++; + + if (*marker == '\0') + relative = -1; + else { + r = safe_atoi(marker, &relative); + if (r < 0) { + log_error("Failed to parse relative boot ID number '%s'", marker); + return -EINVAL; + } + } + } + } + + if (isempty(arg_boot_id_descriptor)) { + if (relative > 0) { + /* We cannot look into the future. Instead, we look + * into the past (starting from first boot). The ID + * will be looked up later */ + boot_id = SD_ID128_NULL; + } else { + r = sd_id128_get_boot(&boot_id); + if (r < 0) { + log_error("Failed to get boot ID: %s", strerror(-r)); + return r; + } + } + } else { + r = sd_id128_from_string(arg_boot_id_descriptor, &boot_id); + if (r < 0) { + log_error("Failed to parse boot ID: %s", strerror(-r)); + return r; + } + } + + r = get_relative_boot_id(j, &boot_id, relative); + if (r < 0) { + log_error("Failed to look up boot ID: %s", strerror(-r)); + return r; + } else if (sd_id128_equal(boot_id, SD_ID128_NULL)) { + log_error("Failed to find boot ID"); + return -1; + } + + sd_id128_to_string(boot_id, match + 9); + r = sd_journal_add_match(j, match, strlen(match)); + if (r < 0) { + log_error("Failed to add match: %s", strerror(-r)); + return r; + } + + r = sd_journal_add_conjunction(j); + if (r < 0) + return r; + + return 0; } static int add_dmesg(sd_journal *j) { @@ -1195,7 +1367,9 @@ int main(int argc, char *argv[]) { return EXIT_SUCCESS; } - r = add_this_boot(j); + /* add_boot() must be called first! + * It may need to seek the journal to find parent boot IDs. */ + r = add_boot(j); if (r < 0) return EXIT_FAILURE; -- cgit v1.2.1 From 6ed80a4e346883b99263a1a13505ef6afcbc09c3 Mon Sep 17 00:00:00 2001 From: "Jason St. John" Date: Tue, 16 Jul 2013 10:19:00 +0200 Subject: man: use HTTPS links for links that support it --- man/binfmt.d.xml | 2 +- man/journald.conf.xml | 2 +- man/machine-id.xml | 2 +- man/os-release.xml | 2 +- man/sd-id128.xml | 2 +- man/systemd.cgroup.xml | 20 ++++++++++---------- man/systemd.exec.xml | 6 +++--- man/systemd.xml | 2 +- 8 files changed, 19 insertions(+), 19 deletions(-) diff --git a/man/binfmt.d.xml b/man/binfmt.d.xml index 7f31b76de9..f4f4195b04 100644 --- a/man/binfmt.d.xml +++ b/man/binfmt.d.xml @@ -67,7 +67,7 @@ Each file contains a list of binfmt_misc kernel binary format rules. Consult binfmt_misc.txt + url="https://www.kernel.org/doc/Documentation/binfmt_misc.txt">binfmt_misc.txt for more information on registration of additional binary formats and how to write rules. diff --git a/man/journald.conf.xml b/man/journald.conf.xml index 5986d61c45..487e8d618a 100644 --- a/man/journald.conf.xml +++ b/man/journald.conf.xml @@ -133,7 +133,7 @@ command), forward secure sealing (FSS) for all persistent journal files is enabled. FSS is based on Seekable + url="https://eprint.iacr.org/2013/397">Seekable Sequential Key Generators by G. A. Marson and B. Poettering and may be used to protect journal files diff --git a/man/machine-id.xml b/man/machine-id.xml index b037e47c01..4b4759e48d 100644 --- a/man/machine-id.xml +++ b/man/machine-id.xml @@ -93,7 +93,7 @@ Note that the machine ID historically is not an OSF UUID as defined by RFC + url="https://tools.ietf.org/html/rfc4122">RFC 4122, nor a Microsoft GUID; however, starting with systemd v30, newly generated machine IDs do qualify as v4 UUIDs. diff --git a/man/os-release.xml b/man/os-release.xml index d714b51fba..045dd08f1f 100644 --- a/man/os-release.xml +++ b/man/os-release.xml @@ -241,7 +241,7 @@ A CPE name for the operating system, following the Common + url="https://cpe.mitre.org/specification/">Common Platform Enumeration Specification as proposed by the MITRE Corporation. This field diff --git a/man/sd-id128.xml b/man/sd-id128.xml index 02fb76b56d..3a5e13306d 100644 --- a/man/sd-id128.xml +++ b/man/sd-id128.xml @@ -71,7 +71,7 @@ process and generate 128-bit ID values. The 128-bit ID values processed and generated by these APIs are a generalization of OSF UUIDs as defined by RFC + url="https://tools.ietf.org/html/rfc4122">RFC 4122 but use a simpler string format. These functions impose no structure on the used IDs, much unlike OSF UUIDs or Microsoft GUIDs, diff --git a/man/systemd.cgroup.xml b/man/systemd.cgroup.xml index e31faf522e..bb0cb1c2e3 100644 --- a/man/systemd.cgroup.xml +++ b/man/systemd.cgroup.xml @@ -127,7 +127,7 @@ along with systemd; If not, see . controls the cpu.shares control group attribute, which defaults to 1024. For details about this control group attribute, see sched-design-CFS.txt. + url="https://www.kernel.org/doc/Documentation/scheduler/sched-design-CFS.txt">sched-design-CFS.txt. Implies CPUAccounting=true. @@ -152,7 +152,7 @@ along with systemd; If not, see . memory.soft_limit_in_bytes control group attributes. For details about these control group attributes, see memory.txt. + url="https://www.kernel.org/doc/Documentation/cgroups/memory.txt">memory.txt. Implies MemoryAccounting=true. @@ -172,7 +172,7 @@ along with systemd; If not, see . defaults to 1000. For details about this control group attribute, see blkio-controller.txt. + url="https://www.kernel.org/doc/Documentation/cgroups/blkio-controller.txt">blkio-controller.txt. @@ -191,7 +191,7 @@ along with systemd; If not, see . attribute, which defaults to 1000. Use this option multiple times to set weights for multiple devices. For details about this control group attribute, see blkio-controller.txt. + url="https://www.kernel.org/doc/Documentation/cgroups/blkio-controller.txt">blkio-controller.txt. @@ -215,7 +215,7 @@ along with systemd; If not, see . attributes. Use this option multiple times to set bandwidth limits for multiple devices. For details about these control group attributes, see - blkio-controller.txt. + blkio-controller.txt. @@ -236,7 +236,7 @@ along with systemd; If not, see . devices.deny control group attributes. For details about these control group attributes, see devices.txt. + url="https://www.kernel.org/doc/Documentation/cgroups/devices.txt">devices.txt. @@ -299,10 +299,10 @@ along with systemd; If not, see . systemd.swap5, systemd.directives7, The documentation for control groups and specific controllers in the Linux kernel: - cgroups.txt, - cpuacct.txt, - memory.txt, - blkio-controller.txt. + cgroups.txt, + cpuacct.txt, + memory.txt, + blkio-controller.txt. diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index c9958340af..1169095978 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -167,7 +167,7 @@ for this process) and 1000 (to make killing of this process under memory pressure very likely). See proc.txt + url="https://www.kernel.org/doc/Documentation/filesystems/proc.txt">proc.txt for details. @@ -832,7 +832,7 @@ and doing this might result in undefined behaviour. For details about control groups see cgroups.txt. + url="https://www.kernel.org/doc/Documentation/cgroups/cgroups.txt">cgroups.txt. This option may appear more than once, in which case the list of @@ -923,7 +923,7 @@ service is not desirable. For details about control group attributes see cgroups.txt. This + url="https://www.kernel.org/doc/Documentation/cgroups/cgroups.txt">cgroups.txt. This option may appear more than once, in order to set multiple control group attributes. If this option is used diff --git a/man/systemd.xml b/man/systemd.xml index b4b4845305..c7aed3c6ff 100644 --- a/man/systemd.xml +++ b/man/systemd.xml @@ -425,7 +425,7 @@ individual Linux control groups named after the unit which they belong to in the private systemd hierarchy. (see cgroups.txt + url="https://www.kernel.org/doc/Documentation/cgroups/cgroups.txt">cgroups.txt for more information about control groups, or short "cgroups"). systemd uses this to effectively keep track of processes. Control group information is -- cgit v1.2.1 From 9c33d34fe4cd0bc58ea12e5258e595647c9e0b29 Mon Sep 17 00:00:00 2001 From: "Jason St. John" Date: Tue, 16 Jul 2013 10:20:03 +0200 Subject: man: improve readability of --output options in journalctl(1) The list and descriptions of valid output options was difficult to read, so break up the long block of text into discrete man page list items to improve readability. --- man/journalctl.xml | 166 ++++++++++++++++++++++++++++++++++++-------------- man/systemd.scope.xml | 2 +- 2 files changed, 120 insertions(+), 48 deletions(-) diff --git a/man/journalctl.xml b/man/journalctl.xml index 0e779b952c..027f22d259 100644 --- a/man/journalctl.xml +++ b/man/journalctl.xml @@ -233,53 +233,125 @@ Controls the formatting of the journal entries that - are shown. Takes one of - short, - short-monotonic, - verbose, - export, - json, - json-pretty, - json-sse, - cat. short - is the default and generates an output - that is mostly identical to the - formatting of classic syslog - files, showing one line per journal - entry. short-monotonic - is very similar but shows monotonic - timestamps instead of wallclock - timestamps. verbose - shows the full structured entry items - with all - fields. export - serializes the journal into a binary - (but mostly text-based) stream - suitable for backups and network - transfer (see Journal - Export Format for more - information). json - formats entries as JSON data - structures, one per - line (see Journal - JSON Format for more - information). json-pretty - also formats entries as JSON data - structures, but formats them in - multiple lines in order to make them - more readable for - humans. json-sse - also formats entries as JSON data - structures, but wraps them in a format - suitable for Server-Sent - Events. cat - generates a very terse output only - showing the actual message of each - journal entry with no meta data, not - even a timestamp. + are shown. Takes one of the following options: + + + + + + + + is the default + and generates an output + that is mostly identical + to the formatting of + classic syslog files, + showing one line per + journal entry. + + + + + + + + + is very similar + but shows monotonic + timestamps instead of + wallclock timestamps. + + + + + + + + + + shows the + full-structured entry + items with all fields. + + + + + + + + + + serializes the + journal into a binary + (but mostly text-based) + stream suitable for + backups and network + transfer (see Journal + Export Format + for more + information). + + + + + + + + + formats entries + as JSON data structures, + one per line (see Journal + JSON Format for + more information). + + + + + + + + + formats entries as + JSON data structures, + but formats them in + multiple lines in order + to make them more + readable for humans. + + + + + + + + + formats entries as + JSON data structures, + but wraps them in a + format suitable for Server-Sent + Events. + + + + + + + + + generates a very + terse output only + showing the actual + message of each journal + entry with no meta data, + not even a timestamp. + + + + + diff --git a/man/systemd.scope.xml b/man/systemd.scope.xml index 6cd8c8845a..126440a15f 100644 --- a/man/systemd.scope.xml +++ b/man/systemd.scope.xml @@ -59,7 +59,7 @@ along with systemd; If not, see . by systemd to encapsulate processes not launched by systemd itself. This management is performed by creating a node in the control group tree. Processes are moved into the scope by means - of the DBus API. + of the D-Bus API. systemd-run can be used to easily launch a command in a new scope unit. -- cgit v1.2.1 From 21c72713ae89cfc2c4096c383af9bb482665e0a6 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Thu, 27 Jun 2013 11:26:35 +0200 Subject: Do not set LANG=C in every child environment. LANG does not have to be set and setting it to default to the default does not add any value. --- src/core/locale-setup.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/core/locale-setup.c b/src/core/locale-setup.c index d7113b9795..daf81d080e 100644 --- a/src/core/locale-setup.c +++ b/src/core/locale-setup.c @@ -117,14 +117,6 @@ int locale_setup(void) { log_warning("Failed to read /etc/locale.conf: %s", strerror(-r)); } - if (!variables[VARIABLE_LANG]) { - variables[VARIABLE_LANG] = strdup("C"); - if (!variables[VARIABLE_LANG]) { - r = -ENOMEM; - goto finish; - } - } - for (i = 0; i < _VARIABLE_MAX; i++) { if (variables[i]) { if (setenv(variable_names[i], variables[i], 1) < 0) { -- cgit v1.2.1 From daabe5491ee0c78b735336c9e69b7f6ea57464e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 16 Jul 2013 12:01:01 -0400 Subject: test-tables: allow sparse tables and check mapping for -1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Jan: test-tables fails on my system. The one it's failing on is: syscall: 222 → (null) → -1 ... and indeed, our own tables should not have holes, but syscall tables certainly might. --- src/shared/test-tables.h | 11 +++++++---- src/test/test-tables.c | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/shared/test-tables.h b/src/shared/test-tables.h index deebec2ed2..3261302077 100644 --- a/src/shared/test-tables.h +++ b/src/shared/test-tables.h @@ -26,10 +26,11 @@ typedef int (*reverse_t)(const char*); static inline void _test_table(const char *name, lookup_t lookup, reverse_t reverse, - int size) { + int size, + bool sparse) { int i; - for (i = 0; i < size + 1; i++) { + for (i = -1; i < size + 1; i++) { const char* val = lookup(i); int rev; @@ -39,10 +40,12 @@ static inline void _test_table(const char *name, rev = reverse("--no-such--value----"); printf("%s: %d → %s → %d\n", name, i, val, rev); - if (i < size ? val == NULL || rev != i : val != NULL || rev != -1) + if (i >= 0 && i < size ? + sparse ? rev != i && rev != -1 : val == NULL || rev != i : + val != NULL || rev != -1) exit(EXIT_FAILURE); } } #define test_table(lower, upper) \ - _test_table(STRINGIFY(lower), lower##_to_string, lower##_from_string, _##upper##_MAX) + _test_table(STRINGIFY(lower), lower##_to_string, lower##_from_string, _##upper##_MAX, false) diff --git a/src/test/test-tables.c b/src/test/test-tables.c index 9a3d3e8e74..3b7800cf37 100644 --- a/src/test/test-tables.c +++ b/src/test/test-tables.c @@ -99,7 +99,7 @@ int main(int argc, char **argv) { test_table(unit_load_state, UNIT_LOAD_STATE); test_table(unit_type, UNIT_TYPE); - _test_table("syscall", syscall_to_name, syscall_from_name, syscall_max()); + _test_table("syscall", syscall_to_name, syscall_from_name, syscall_max(), true); return EXIT_SUCCESS; } -- cgit v1.2.1 From a65f06bb27688a6738f2f94b7f055f4c66768d63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 26 Jun 2013 19:55:48 -0400 Subject: journal: return -ECHILD after a fork A few asserts are replaced with 'return -EINVAL'. I think that assert should not be used to check argument in public functions. Fields in struct sd_journal are rearranged to make it less swiss-cheesy. --- TODO | 5 +-- man/sd_journal_open.xml | 7 ++++ src/journal/journal-internal.h | 18 +++++----- src/journal/sd-journal.c | 80 +++++++++++++++++++++++++++++++++++++++--- 4 files changed, 93 insertions(+), 17 deletions(-) diff --git a/TODO b/TODO index f5da81f527..4be6249419 100644 --- a/TODO +++ b/TODO @@ -126,7 +126,7 @@ Features: * document systemd-journal-flush.service properly -* chane systemd-journal-flush into a service that stays around during +* change systemd-journal-flush into a service that stays around during boot, and causes the journal to be moved back to /run on shutdown, so that we don't keep /var busy. This needs to happen synchronously, hence doing this via signals is not going to work. @@ -134,9 +134,6 @@ Features: * allow implementation of InaccessibleDirectories=/ plus ReadOnlyDirectories=... for whitelisting files for a service. -* libsystemd-journal: - - return ECHILD as soon as somebody tries to reuse a journal object across a fork() - * libsystemd-bus: - default policy (allow uid == 0 and our own uid) - enforce alignment of pointers passed in diff --git a/man/sd_journal_open.xml b/man/sd_journal_open.xml index eae851e731..28d164add7 100644 --- a/man/sd_journal_open.xml +++ b/man/sd_journal_open.xml @@ -131,6 +131,13 @@ can be rotated at any moment, and the opening of specific files is inherently racy. + sd_journal objects cannot be + used in the child after a fork. Functions which take a + journal object as an argument + (sd_journal_next() and others) + will return -ECHILD after a fork. + + sd_journal_close() will close the journal context allocated with sd_journal_open() or diff --git a/src/journal/journal-internal.h b/src/journal/journal-internal.h index 5b717f86f7..5bc653537c 100644 --- a/src/journal/journal-internal.h +++ b/src/journal/journal-internal.h @@ -97,8 +97,6 @@ struct Directory { }; struct sd_journal { - int flags; - char *path; Hashmap *files; @@ -109,27 +107,29 @@ struct sd_journal { JournalFile *current_file; uint64_t current_field; - Hashmap *directories_by_path; - Hashmap *directories_by_wd; - - int inotify_fd; - Match *level0, *level1, *level2; + pid_t original_pid; + + int inotify_fd; unsigned current_invalidate_counter, last_invalidate_counter; + usec_t last_process_usec; char *unique_field; JournalFile *unique_file; uint64_t unique_offset; + int flags; + bool on_network; bool no_new_files; size_t data_threshold; - Set *errors; + Hashmap *directories_by_path; + Hashmap *directories_by_wd; - usec_t last_process_usec; + Set *errors; }; char *journal_make_match_string(sd_journal *j); diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index 1e70739295..81b0c136f5 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -50,6 +50,15 @@ #define DEFAULT_DATA_THRESHOLD (64*1024) +static bool journal_pid_changed(sd_journal *j) { + assert(j); + + /* We don't support people creating a journal object and + * keeping it around over a fork(). Let's complain. */ + + return j->original_pid != getpid(); +} + /* We return an error here only if we didn't manage to memorize the real error. */ static int set_put_error(sd_journal *j, int r) { @@ -209,6 +218,8 @@ _public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size) if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!data) return -EINVAL; @@ -303,7 +314,10 @@ fail: } _public_ int sd_journal_add_conjunction(sd_journal *j) { - assert(j); + if (!j) + return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!j->level0) return 0; @@ -321,7 +335,10 @@ _public_ int sd_journal_add_conjunction(sd_journal *j) { } _public_ int sd_journal_add_disjunction(sd_journal *j) { - assert(j); + if (!j) + return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!j->level0) return 0; @@ -391,7 +408,6 @@ char *journal_make_match_string(sd_journal *j) { } _public_ void sd_journal_flush_matches(sd_journal *j) { - if (!j) return; @@ -870,6 +886,8 @@ static int real_journal_next(sd_journal *j, direction_t direction) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; HASHMAP_FOREACH(f, j->files, i) { bool found; @@ -922,6 +940,8 @@ static int real_journal_next_skip(sd_journal *j, direction_t direction, uint64_t if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (skip == 0) { /* If this is not a discrete skip, then at least @@ -962,6 +982,8 @@ _public_ int sd_journal_get_cursor(sd_journal *j, char **cursor) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!cursor) return -EINVAL; @@ -1001,6 +1023,8 @@ _public_ int sd_journal_seek_cursor(sd_journal *j, const char *cursor) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (isempty(cursor)) return -EINVAL; @@ -1100,6 +1124,8 @@ _public_ int sd_journal_test_cursor(sd_journal *j, const char *cursor) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (isempty(cursor)) return -EINVAL; @@ -1178,6 +1204,8 @@ _public_ int sd_journal_test_cursor(sd_journal *j, const char *cursor) { _public_ int sd_journal_seek_monotonic_usec(sd_journal *j, sd_id128_t boot_id, uint64_t usec) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; reset_location(j); j->current_location.type = LOCATION_SEEK; @@ -1191,6 +1219,8 @@ _public_ int sd_journal_seek_monotonic_usec(sd_journal *j, sd_id128_t boot_id, u _public_ int sd_journal_seek_realtime_usec(sd_journal *j, uint64_t usec) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; reset_location(j); j->current_location.type = LOCATION_SEEK; @@ -1203,6 +1233,8 @@ _public_ int sd_journal_seek_realtime_usec(sd_journal *j, uint64_t usec) { _public_ int sd_journal_seek_head(sd_journal *j) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; reset_location(j); j->current_location.type = LOCATION_HEAD; @@ -1213,6 +1245,8 @@ _public_ int sd_journal_seek_head(sd_journal *j) { _public_ int sd_journal_seek_tail(sd_journal *j) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; reset_location(j); j->current_location.type = LOCATION_TAIL; @@ -1651,6 +1685,7 @@ static sd_journal *journal_new(int flags, const char *path) { if (!j) return NULL; + j->original_pid = getpid(); j->inotify_fd = -1; j->flags = flags; j->data_threshold = DEFAULT_DATA_THRESHOLD; @@ -1812,6 +1847,8 @@ _public_ int sd_journal_get_realtime_usec(sd_journal *j, uint64_t *ret) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!ret) return -EINVAL; @@ -1838,6 +1875,8 @@ _public_ int sd_journal_get_monotonic_usec(sd_journal *j, uint64_t *ret, sd_id12 if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; f = j->current_file; if (!f) @@ -1904,6 +1943,8 @@ _public_ int sd_journal_get_data(sd_journal *j, const char *field, const void ** if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!field) return -EINVAL; if (!data) @@ -2030,6 +2071,8 @@ _public_ int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!data) return -EINVAL; if (!size) @@ -2080,6 +2123,8 @@ _public_ int sd_journal_get_fd(sd_journal *j) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (j->inotify_fd >= 0) return j->inotify_fd; @@ -2107,6 +2152,8 @@ _public_ int sd_journal_get_events(sd_journal *j) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; fd = sd_journal_get_fd(j); if (fd < 0) @@ -2120,6 +2167,8 @@ _public_ int sd_journal_get_timeout(sd_journal *j, uint64_t *timeout_usec) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!timeout_usec) return -EINVAL; @@ -2220,6 +2269,8 @@ _public_ int sd_journal_process(sd_journal *j) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; j->last_process_usec = now(CLOCK_MONOTONIC); @@ -2258,7 +2309,10 @@ _public_ int sd_journal_wait(sd_journal *j, uint64_t timeout_usec) { int r; uint64_t t; - assert(j); + if (!j) + return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (j->inotify_fd < 0) { @@ -2307,6 +2361,8 @@ _public_ int sd_journal_get_cutoff_realtime_usec(sd_journal *j, uint64_t *from, if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!from && !to) return -EINVAL; if (from == to) @@ -2348,6 +2404,8 @@ _public_ int sd_journal_get_cutoff_monotonic_usec(sd_journal *j, sd_id128_t boot if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!from && !to) return -EINVAL; if (from == to) @@ -2405,6 +2463,8 @@ _public_ int sd_journal_get_usage(sd_journal *j, uint64_t *bytes) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!bytes) return -EINVAL; @@ -2426,6 +2486,8 @@ _public_ int sd_journal_query_unique(sd_journal *j, const char *field) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (isempty(field)) return -EINVAL; if (!field_is_valid(field)) @@ -2450,6 +2512,8 @@ _public_ int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_ if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!data) return -EINVAL; if (!l) @@ -2562,6 +2626,8 @@ _public_ void sd_journal_restart_unique(sd_journal *j) { _public_ int sd_journal_reliable_fd(sd_journal *j) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; return !j->on_network; } @@ -2595,6 +2661,8 @@ _public_ int sd_journal_get_catalog(sd_journal *j, char **ret) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!ret) return -EINVAL; @@ -2632,6 +2700,8 @@ _public_ int sd_journal_get_catalog_for_message_id(sd_id128_t id, char **ret) { _public_ int sd_journal_set_data_threshold(sd_journal *j, size_t sz) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; j->data_threshold = sz; return 0; @@ -2640,6 +2710,8 @@ _public_ int sd_journal_set_data_threshold(sd_journal *j, size_t sz) { _public_ int sd_journal_get_data_threshold(sd_journal *j, size_t *sz) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!sz) return -EINVAL; -- cgit v1.2.1 From bf89b99c5a39115112c2eda4c2103e2db54988d2 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Tue, 16 Jul 2013 18:44:30 +0200 Subject: 60-keyboard.hwdb: Fix syntax error Add missing '='. --- hwdb/60-keyboard.hwdb | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index 8199b300cd..5470588f1e 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -602,19 +602,19 @@ keyboard:usb:v046DpC317* # Wave cordless keyboard:usb:v046DpC517* - KEYBOARD_KEY_c101f zoomout - KEYBOARD_KEY_c1020 zoomin - KEYBOARD_KEY_c1005 camera - KEYBOARD_KEY_c0183 media - KEYBOARD_KEY_c1041 wordprocessor - KEYBOARD_KEY_c1042 spreadsheet - KEYBOARD_KEY_c1043 calendar - KEYBOARD_KEY_c1044 prog2 #fn+f4 (program a) - KEYBOARD_KEY_c1045 prog3 #fn+f5 (program b) - KEYBOARD_KEY_c1046 prog4 #fn+f6 (program c) - KEYBOARD_KEY_c1048 messenger #fn+f8 (msn messenger) - KEYBOARD_KEY_c104a find #fn+f10 (search www) - KEYBOARD_KEY_c104c ejectclosecd + KEYBOARD_KEY_c101f=zoomout + KEYBOARD_KEY_c1020=zoomin + KEYBOARD_KEY_c1005=camera + KEYBOARD_KEY_c0183=media + KEYBOARD_KEY_c1041=wordprocessor + KEYBOARD_KEY_c1042=spreadsheet + KEYBOARD_KEY_c1043=calendar + KEYBOARD_KEY_c1044=prog2 #fn+f4 (program a) + KEYBOARD_KEY_c1045=prog3 #fn+f5 (program b) + KEYBOARD_KEY_c1046=prog4 #fn+f6 (program c) + KEYBOARD_KEY_c1048=messenger #fn+f8 (msn messenger) + KEYBOARD_KEY_c104a=find #fn+f10 (search www) + KEYBOARD_KEY_c104c=ejectclosecd # Cordless Wave Pro keyboard:usb:v046DpC52[9B]* -- cgit v1.2.1 From 042e33ae3a7feb08c8105f1345fd244315109405 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 16 Jul 2013 18:15:48 +0200 Subject: rpm: add RPM macro for creating tmpfiles entries after package installation --- TODO | 2 ++ src/core/macros.systemd.in | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/TODO b/TODO index 4be6249419..7401a5781e 100644 --- a/TODO +++ b/TODO @@ -56,6 +56,8 @@ CGroup Rework Completion: Features: +* Fedora: post FPC ticket to move add %tmpfiles_create to the packaging guidelines + * add rpm macros for applying tmpfiles --create after package installation * when parsing calendar timestamps support the UTC timezone (even if we won't support arbitrary timezone specs, support UTC itself certainly makes sense), also support syntaxes such as +0200 diff --git a/src/core/macros.systemd.in b/src/core/macros.systemd.in index 4ad8186fae..89b48259ad 100644 --- a/src/core/macros.systemd.in +++ b/src/core/macros.systemd.in @@ -72,3 +72,7 @@ fi \ %journal_catalog_update() \ @rootbindir@/journalctl --update-catalog >/dev/null 2>&1 || : \ %{nil} + +%tmpfiles_create() \ +@rootbindir@/systemd-tmpfiles --create %{?*} >/dev/null 2>&1 || : \ +%{nil} -- cgit v1.2.1 From e7256c5c137e58fb3dc1ebca8e5845733a5f733c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 16 Jul 2013 18:25:52 +0200 Subject: update --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index 7401a5781e..2e97356a24 100644 --- a/TODO +++ b/TODO @@ -56,6 +56,8 @@ CGroup Rework Completion: Features: +* Fedora: add an rpmlint check that verifies that all unit files in the RPM are listed in %systemd_post macros. + * Fedora: post FPC ticket to move add %tmpfiles_create to the packaging guidelines * add rpm macros for applying tmpfiles --create after package installation -- cgit v1.2.1 From 6cf2f1d94dc7749bcdff5385838bdc8eba9c3001 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Thu, 27 Jun 2013 11:26:36 +0200 Subject: util.c:is_locale_utf8(): check, if "C" was set on purpose If you have a ASCII only terminal, there is no way to set the charmap to ANSI_X3.4-1968, other than using LC_CTYPE=C. We don't want to assume a UTF-8 capable terminal in this case and only do so, if LANG, LC_ALL and LC_CTYPE are unset. --- src/shared/util.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/shared/util.c b/src/shared/util.c index 19ca8ad135..15abd5046d 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -5420,20 +5420,24 @@ bool is_locale_utf8(void) { goto out; } - /* For LC_CTYPE=="C" return true, - * because CTYPE is effectly unset and - * everything defaults to UTF-8 nowadays. */ - + /* For LC_CTYPE=="C" return true, because CTYPE is effectly + * unset and everything can do to UTF-8 nowadays. */ set = setlocale(LC_CTYPE, NULL); if (!set) { cached_answer = true; goto out; } - cached_answer = streq(set, "C"); + /* Check result, but ignore the result if C was set + * explicitly. */ + cached_answer = + streq(set, "C") && + !getenv("LC_ALL") && + !getenv("LC_CTYPE") && + !getenv("LANG"); out: - return (bool)cached_answer; + return (bool) cached_answer; } const char *draw_special_char(DrawSpecialChar ch) { -- cgit v1.2.1 From 84b6ad702e64db534f67ce32d4dd2fec00a16784 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Sun, 7 Jul 2013 18:32:34 +0200 Subject: udev: export tags of "dead" device nodes to /run/udev/static_node-tags/ Based on a patch by Kay Sievers. A tag is exported at boot as a symlinks to the device node in the folder /run/udev/static_node-tags//, if the device node exists. These tags are cleaned up by udevadm info --cleanup-db, but are otherwise never removed. --- man/udev.xml | 10 ++++-- src/login/70-uaccess.rules | 3 +- src/udev/udev-rules.c | 82 ++++++++++++++++++++++++++++++++++++++-------- src/udev/udev.h | 2 +- src/udev/udevadm-info.c | 6 ++++ src/udev/udevd.c | 4 ++- 6 files changed, 88 insertions(+), 19 deletions(-) diff --git a/man/udev.xml b/man/udev.xml index 553bbfd056..ca8444c12c 100644 --- a/man/udev.xml +++ b/man/udev.xml @@ -521,9 +521,13 @@ Apply the permissions specified in this rule to the static device node with - the specified name. Static device node creation can be requested by kernel modules. - These nodes might not have a corresponding kernel device at the time systemd-udevd is - started; they can trigger automatic kernel module loading. + the specified name. Also, for every tag specified in this rule, create a symlink + in the directory + /run/udev/static_node-tags/tag + pointing at the static device node with the specified name. Static device node + creation is performed by systemd-tmpfiles before systemd-udevd is started. The + static nodes might not have a corresponding kernel device; they are used to + trigger automatic kernel module loading when they are accessed. diff --git a/src/login/70-uaccess.rules b/src/login/70-uaccess.rules index a118f8e887..01484c95f1 100644 --- a/src/login/70-uaccess.rules +++ b/src/login/70-uaccess.rules @@ -25,7 +25,8 @@ SUBSYSTEM=="block", ENV{ID_CDROM}=="1", TAG+="uaccess" SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="4|5", TAG+="uaccess" # Sound devices -SUBSYSTEM=="sound", TAG+="uaccess" +SUBSYSTEM=="sound", TAG+="uaccess" \ + OPTIONS+="static_node=snd/timer", OPTIONS+="static_node=snd/seq" # ffado is an userspace driver for firewire sound cards SUBSYSTEM=="firewire", ENV{ID_FFADO}=="1", TAG+="uaccess" diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index fe65e2dd85..8ace7050db 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -33,6 +33,7 @@ #include "path-util.h" #include "conf-files.h" #include "strbuf.h" +#include "strv.h" #define PREALLOC_TOKEN 2048 @@ -152,9 +153,9 @@ enum token_type { TK_A_OWNER_ID, /* uid_t */ TK_A_GROUP_ID, /* gid_t */ TK_A_MODE_ID, /* mode_t */ + TK_A_TAG, /* val */ TK_A_STATIC_NODE, /* val */ TK_A_ENV, /* val, attr */ - TK_A_TAG, /* val */ TK_A_NAME, /* val */ TK_A_DEVLINK, /* val */ TK_A_ATTR, /* val, attr */ @@ -2496,16 +2497,21 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event } } -void udev_rules_apply_static_dev_perms(struct udev_rules *rules) +int udev_rules_apply_static_dev_perms(struct udev_rules *rules) { struct token *cur; struct token *rule; uid_t uid = 0; gid_t gid = 0; mode_t mode = 0; + _cleanup_strv_free_ char **tags = NULL; + char **t; + FILE *f = NULL; + _cleanup_free_ char *path = NULL; + int r = 0; if (rules->tokens == NULL) - return; + return 0; cur = &rules->tokens[0]; rule = cur; @@ -2522,6 +2528,8 @@ void udev_rules_apply_static_dev_perms(struct udev_rules *rules) uid = 0; gid = 0; mode = 0; + strv_free(tags); + tags = NULL; break; case TK_A_OWNER_ID: uid = cur->key.uid; @@ -2531,19 +2539,53 @@ void udev_rules_apply_static_dev_perms(struct udev_rules *rules) break; case TK_A_MODE_ID: mode = cur->key.mode; + break; + case TK_A_TAG: + r = strv_extend(&tags, rules_str(rules, cur->key.value_off)); + if (r < 0) + goto finish; + break; case TK_A_STATIC_NODE: { - char filename[UTIL_PATH_SIZE]; + char device_node[UTIL_PATH_SIZE]; + char tags_dir[UTIL_PATH_SIZE]; + char tag_symlink[UTIL_PATH_SIZE]; struct stat stats; /* we assure, that the permissions tokens are sorted before the static token */ - if (mode == 0 && uid == 0 && gid == 0) + if (mode == 0 && uid == 0 && gid == 0 && tags == NULL) goto next; - strscpyl(filename, sizeof(filename), "/dev/", rules_str(rules, cur->key.value_off), NULL); - if (stat(filename, &stats) != 0) + strscpyl(device_node, sizeof(device_node), "/dev/", rules_str(rules, cur->key.value_off), NULL); + if (stat(device_node, &stats) != 0) goto next; if (!S_ISBLK(stats.st_mode) && !S_ISCHR(stats.st_mode)) goto next; + + if (tags) { + /* Export the tags to a directory as symlinks, allowing otherwise dead nodes to be tagged */ + + STRV_FOREACH(t, tags) { + _cleanup_free_ char *unescaped_filename = NULL; + + strscpyl(tags_dir, sizeof(tags_dir), "/run/udev/static_node-tags/", *t, "/", NULL); + r = mkdir_p(tags_dir, 0755); + if (r < 0) { + log_error("failed to create %s: %s\n", tags_dir, strerror(-r)); + return r; + } + + unescaped_filename = xescape(rules_str(rules, cur->key.value_off), "/."); + + strscpyl(tag_symlink, sizeof(tag_symlink), tags_dir, unescaped_filename, NULL); + r = symlink(device_node, tag_symlink); + if (r < 0 && errno != EEXIST) { + log_error("failed to create symlink %s -> %s: %s\n", tag_symlink, device_node, strerror(errno)); + return -errno; + } else + r = 0; + } + } + if (mode == 0) { if (gid > 0) mode = 0660; @@ -2551,20 +2593,20 @@ void udev_rules_apply_static_dev_perms(struct udev_rules *rules) mode = 0600; } if (mode != (stats.st_mode & 01777)) { - chmod(filename, mode); - log_debug("chmod '%s' %#o\n", filename, mode); + chmod(device_node, mode); + log_debug("chmod '%s' %#o\n", device_node, mode); } if ((uid != 0 && uid != stats.st_uid) || (gid != 0 && gid != stats.st_gid)) { - chown(filename, uid, gid); - log_debug("chown '%s' %u %u\n", filename, uid, gid); + chown(device_node, uid, gid); + log_debug("chown '%s' %u %u\n", device_node, uid, gid); } - utimensat(AT_FDCWD, filename, NULL, 0); + utimensat(AT_FDCWD, device_node, NULL, 0); break; } case TK_END: - return; + goto finish; } cur++; @@ -2574,4 +2616,18 @@ next: cur = rule + rule->rule.token_count; continue; } + +finish: + if (f) { + fflush(f); + fchmod(fileno(f), 0644); + if (ferror(f) || rename(path, "/run/udev/static_node-tags") < 0) { + r = -errno; + unlink("/run/udev/static_node-tags"); + unlink(path); + } + fclose(f); + } + + return r; } diff --git a/src/udev/udev.h b/src/udev/udev.h index c9408f2d46..839592680b 100644 --- a/src/udev/udev.h +++ b/src/udev/udev.h @@ -72,7 +72,7 @@ struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names); struct udev_rules *udev_rules_unref(struct udev_rules *rules); bool udev_rules_check_timestamp(struct udev_rules *rules); int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event, const sigset_t *sigmask); -void udev_rules_apply_static_dev_perms(struct udev_rules *rules); +int udev_rules_apply_static_dev_perms(struct udev_rules *rules); /* udev-event.c */ struct udev_event *udev_event_new(struct udev_device *dev); diff --git a/src/udev/udevadm-info.c b/src/udev/udevadm-info.c index 002876594f..2ee59fe075 100644 --- a/src/udev/udevadm-info.c +++ b/src/udev/udevadm-info.c @@ -251,6 +251,12 @@ static void cleanup_db(struct udev *udev) closedir(dir); } + dir = opendir("/run/udev/static_node-tags"); + if (dir != NULL) { + cleanup_dir(dir, 0, 2); + closedir(dir); + } + dir = opendir("/run/udev/watch"); if (dir != NULL) { cleanup_dir(dir, 0, 1); diff --git a/src/udev/udevd.c b/src/udev/udevd.c index c4127cd03b..45ec3d681f 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -1197,7 +1197,9 @@ int main(int argc, char *argv[]) } log_debug("set children_max to %u\n", children_max); - udev_rules_apply_static_dev_perms(rules); + rc = udev_rules_apply_static_dev_perms(rules); + if (rc < 0) + log_error("failed to apply permissions on static device nodes - %s\n", strerror(-rc)); udev_list_node_init(&event_list); udev_list_node_init(&worker_list); -- cgit v1.2.1 From 6b78df0a6ec75f25705a0f78ef895b95ab75a7ea Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Sun, 7 Jul 2013 21:29:12 +0200 Subject: logind: apply ACL's to "dead" device nodes Based on a patch by Kay Sievers. When a dead device nodes is tagged with "uaccess" using the static_node mechanism, it's ACL's are managed by logind in the same way as "live" device nodes. This allows in particular /dev/snd/{seq,timer} to cause modules to be loaded on-demand when accessed by a non-privileged user. --- src/login/logind-acl.c | 75 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 64 insertions(+), 11 deletions(-) diff --git a/src/login/logind-acl.c b/src/login/logind-acl.c index cb045a9928..c0ff509377 100644 --- a/src/login/logind-acl.c +++ b/src/login/logind-acl.c @@ -28,6 +28,7 @@ #include "logind-acl.h" #include "util.h" #include "acl-util.h" +#include "set.h" static int flush_acl(acl_t acl) { acl_entry_t i; @@ -179,23 +180,34 @@ int devnode_acl_all(struct udev *udev, struct udev_list_entry *item = NULL, *first = NULL; struct udev_enumerate *e; + Set *nodes; + Iterator i; + char *n; + DIR *dir; + struct dirent *dent; int r; assert(udev); - if (isempty(seat)) - seat = "seat0"; + nodes = set_new(string_hash_func, string_compare_func); + if (!nodes) { + return -ENOMEM; + } e = udev_enumerate_new(udev); - if (!e) - return -ENOMEM; + if (!e) { + r = -ENOMEM; + goto finish; + } + + if (isempty(seat)) + seat = "seat0"; /* We can only match by one tag in libudev. We choose * "uaccess" for that. If we could match for two tags here we * could add the seat name as second match tag, but this would * be hardly optimizable in libudev, and hence checking the * second tag manually in our loop is a good solution. */ - r = udev_enumerate_add_match_tag(e, "uaccess"); if (r < 0) goto finish; @@ -231,18 +243,59 @@ int devnode_acl_all(struct udev *udev, continue; } - log_debug("Fixing up %s for seat %s...", node, sn); - - r = devnode_acl(node, flush, del, old_uid, add, new_uid); + n = strdup(node); udev_device_unref(d); + if (!n) + goto finish; + log_debug("Found udev node %s for seat %s", n, seat); + r = set_put(nodes, n); if (r < 0) goto finish; } -finish: - if (e) - udev_enumerate_unref(e); + /* udev exports "dead" device nodes to allow module on-demand loading, + * these devices are not known to the kernel at this moment */ + dir = opendir("/run/udev/static_node-tags/uaccess"); + if (dir) { + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + _cleanup_free_ char *unescaped_devname = NULL; + if (dent->d_name[0] == '.') + continue; + + unescaped_devname = cunescape(dent->d_name); + if (unescaped_devname == NULL) { + r = -ENOMEM; + closedir(dir); + goto finish; + } + + n = strappend("/dev/", unescaped_devname); + if (!n) { + r = -ENOMEM; + closedir(dir); + goto finish; + } + + log_debug("Found static node %s for seat %s", n, seat); + r = set_put(nodes, n); + if (0 && r < 0 && r != -EEXIST) { + closedir(dir); + goto finish; + } else + r = 0; + } + closedir(dir); + } + + SET_FOREACH(n, nodes, i) { + log_debug("Fixing up ACLs at %s for seat %s", n, seat); + r = devnode_acl(n, flush, del, old_uid, add, new_uid); + } + +finish: + udev_enumerate_unref(e); + set_free_free(nodes); return r; } -- cgit v1.2.1 From db0c1e3bd39c9151ba4ac8e029ec77a4ec923bd1 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Tue, 16 Jul 2013 23:05:02 +0200 Subject: logind-acl: use macros Simplify by using FOREACH_DIRENT and _cleanup_closedir_ macros. --- src/login/logind-acl.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/login/logind-acl.c b/src/login/logind-acl.c index c0ff509377..390b4b2885 100644 --- a/src/login/logind-acl.c +++ b/src/login/logind-acl.c @@ -183,7 +183,7 @@ int devnode_acl_all(struct udev *udev, Set *nodes; Iterator i; char *n; - DIR *dir; + _cleanup_closedir_ DIR *dir = NULL; struct dirent *dent; int r; @@ -258,35 +258,28 @@ int devnode_acl_all(struct udev *udev, * these devices are not known to the kernel at this moment */ dir = opendir("/run/udev/static_node-tags/uaccess"); if (dir) { - for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + FOREACH_DIRENT(dent, dir, r = -errno; goto finish) { _cleanup_free_ char *unescaped_devname = NULL; - if (dent->d_name[0] == '.') - continue; - unescaped_devname = cunescape(dent->d_name); if (unescaped_devname == NULL) { r = -ENOMEM; - closedir(dir); goto finish; } n = strappend("/dev/", unescaped_devname); if (!n) { r = -ENOMEM; - closedir(dir); goto finish; } log_debug("Found static node %s for seat %s", n, seat); r = set_put(nodes, n); if (0 && r < 0 && r != -EEXIST) { - closedir(dir); goto finish; } else r = 0; } - closedir(dir); } SET_FOREACH(n, nodes, i) { -- cgit v1.2.1 From 83a05f2c89d228a9a92b998b1cbd4a51f3693711 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 17 Jul 2013 01:49:26 +0200 Subject: logind: remove "if (0)" left-over --- src/login/logind-acl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/login/logind-acl.c b/src/login/logind-acl.c index 390b4b2885..25abcbcf80 100644 --- a/src/login/logind-acl.c +++ b/src/login/logind-acl.c @@ -275,9 +275,9 @@ int devnode_acl_all(struct udev *udev, log_debug("Found static node %s for seat %s", n, seat); r = set_put(nodes, n); - if (0 && r < 0 && r != -EEXIST) { + if (r < 0 && r != -EEXIST) goto finish; - } else + else r = 0; } } -- cgit v1.2.1 From c5757cc8dbcddb3e8b13ebba4ea4b36589bfd3db Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 17 Jul 2013 02:29:19 +0200 Subject: update TODO --- TODO | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/TODO b/TODO index 2e97356a24..902fbc695e 100644 --- a/TODO +++ b/TODO @@ -68,6 +68,14 @@ Features: * when a kernel driver logs in a tight loop we should ratelimit that too. +* man: document in the journalctl man page what the colors mean + +* "systemctl disable" of a unit instance removes all symlinks, should + only remove the instance symlink (systemct disable of a template + unit however should remove them all). + +* journald: optionally, log debug messages to /run but everything else to /var + * journald: optionally, when messages with a high log prioerity are logged, sync() immeidately. * introduce %v resolving to the string returned by "uname -r" -- cgit v1.2.1 From 32b2634edf218e250b84615bbf106b2baf42d69b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 17 Jul 2013 02:48:53 +0200 Subject: util: make some gcc versions shut up regarding unintialized variable access --- src/shared/util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shared/util.c b/src/shared/util.c index 15abd5046d..f56d2a2d33 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -367,7 +367,7 @@ int safe_atolli(const char *s, long long int *ret_lli) { int safe_atod(const char *s, double *ret_d) { char *x = NULL; - double d; + double d = 0; assert(s); assert(ret_d); @@ -5752,7 +5752,7 @@ int search_and_fopen_nulstr(const char *path, const char *mode, const char *sear int create_tmp_dir(char template[], char** dir_name) { int r = 0; - char *d, *dt; + char *d = NULL, *dt; assert(dir_name); -- cgit v1.2.1 From dd94c17e7da89fa612952119ac825116dc5a8deb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 17 Jul 2013 02:52:41 +0200 Subject: util: make gcc shut up by passing a 0 mode param to open() If we pass a variable to open()'s flags parameter it really wants a mode parameter too, otherwise some gcc version whine. Hence, pass 0 in that case. --- src/shared/util.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/shared/util.c b/src/shared/util.c index f56d2a2d33..5b602ea46d 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -1875,8 +1875,10 @@ int open_terminal(const char *name, int mode) { * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245 */ + assert(!(mode & O_CREAT)); + for (;;) { - fd = open(name, mode); + fd = open(name, mode, 0); if (fd >= 0) break; @@ -3520,7 +3522,9 @@ DIR *xopendirat(int fd, const char *name, int flags) { int nfd; DIR *d; - nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags); + assert(!(flags & O_CREAT)); + + nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags, 0); if (nfd < 0) return NULL; -- cgit v1.2.1 From 248fc619b5e3e24d78f171f95b85916eee7987bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 16 Jul 2013 10:21:18 -0400 Subject: journalctl: augment short mode with a cursor at the end Two options are added: --show-cursor to print the cursor at the end, and --after-cursor to resume logs on the next line after the previous one. --- TODO | 2 - man/journalctl.xml | 10 +++ src/journal/journalctl.c | 207 +++++++++++++++++++++++++++-------------------- 3 files changed, 129 insertions(+), 90 deletions(-) diff --git a/TODO b/TODO index 902fbc695e..06771d5bf5 100644 --- a/TODO +++ b/TODO @@ -64,8 +64,6 @@ Features: * when parsing calendar timestamps support the UTC timezone (even if we won't support arbitrary timezone specs, support UTC itself certainly makes sense), also support syntaxes such as +0200 -* journalctl: add an output mode that looks like classic /var/log/messages, but also outputs the cursor of the last entry so that people can write scripts that can run iteratively and always process data that has been added since the last time. - * when a kernel driver logs in a tight loop we should ratelimit that too. * man: document in the journalctl man page what the colors mean diff --git a/man/journalctl.xml b/man/journalctl.xml index 027f22d259..3e03c45f13 100644 --- a/man/journalctl.xml +++ b/man/journalctl.xml @@ -522,6 +522,16 @@ cursor. + + + + Start showing entries from the + location in the journal + after the location + specified by the this cursor. + + + diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 38b2cdd572..7415abc74f 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -74,6 +74,8 @@ static bool arg_boot_id = false; static char *arg_boot_id_descriptor = NULL; static bool arg_dmesg = false; static const char *arg_cursor = NULL; +static const char *arg_after_cursor = NULL; +static bool arg_show_cursor = false; static const char *arg_directory = NULL; static char **arg_file = NULL; static int arg_priorities = 0xFF; @@ -114,50 +116,52 @@ static int help(void) { printf("%s [OPTIONS...] [MATCHES...]\n\n" "Query the journal.\n\n" "Flags:\n" - " --system Show only the system journal\n" - " --user Show only the user journal for current user\n" - " --since=DATE Start showing entries newer or of the specified date\n" - " --until=DATE Stop showing entries older or of the specified date\n" - " -c --cursor=CURSOR Start showing entries from specified cursor\n" - " -b --boot[=ID] Show data only from ID or current boot if unspecified\n" - " -k --dmesg Show kernel message log from current boot\n" - " -u --unit=UNIT Show data only from the specified unit\n" - " --user-unit=UNIT Show data only from the specified user session unit\n" - " -p --priority=RANGE Show only messages within the specified priority range\n" - " -e --pager-end Immediately jump to end of the journal in the pager\n" - " -f --follow Follow journal\n" - " -n --lines[=INTEGER] Number of journal entries to show\n" - " --no-tail Show all lines, even in follow mode\n" - " -r --reverse Show the newest entries first\n" - " -o --output=STRING Change journal output mode (short, short-monotonic,\n" - " verbose, export, json, json-pretty, json-sse, cat)\n" - " -x --catalog Add message explanations where available\n" - " -l --full Do not ellipsize fields\n" - " -a --all Show all fields, including long and unprintable\n" - " -q --quiet Don't show privilege warning\n" - " --no-pager Do not pipe output into a pager\n" - " -m --merge Show entries from all available journals\n" - " -D --directory=PATH Show journal files from directory\n" - " --file=PATH Show journal file\n" - " --root=ROOT Operate on catalog files underneath the root ROOT\n" + " --system Show only the system journal\n" + " --user Show only the user journal for current user\n" + " --since=DATE Start showing entries newer or of the specified date\n" + " --until=DATE Stop showing entries older or of the specified date\n" + " -c --cursor=CURSOR Start showing entries from specified cursor\n" + " --after-cursor=CURSOR Start showing entries from specified cursor\n" + " --show-cursor Print the cursor after all the entries\n" + " -b --boot[=ID] Show data only from ID or current boot if unspecified\n" + " -k --dmesg Show kernel message log from current boot\n" + " -u --unit=UNIT Show data only from the specified unit\n" + " --user-unit=UNIT Show data only from the specified user session unit\n" + " -p --priority=RANGE Show only messages within the specified priority range\n" + " -e --pager-end Immediately jump to end of the journal in the pager\n" + " -f --follow Follow journal\n" + " -n --lines[=INTEGER] Number of journal entries to show\n" + " --no-tail Show all lines, even in follow mode\n" + " -r --reverse Show the newest entries first\n" + " -o --output=STRING Change journal output mode (short, short-monotonic,\n" + " verbose, export, json, json-pretty, json-sse, cat)\n" + " -x --catalog Add message explanations where available\n" + " -l --full Do not ellipsize fields\n" + " -a --all Show all fields, including long and unprintable\n" + " -q --quiet Don't show privilege warning\n" + " --no-pager Do not pipe output into a pager\n" + " -m --merge Show entries from all available journals\n" + " -D --directory=PATH Show journal files from directory\n" + " --file=PATH Show journal file\n" + " --root=ROOT Operate on catalog files underneath the root ROOT\n" #ifdef HAVE_GCRYPT - " --interval=TIME Time interval for changing the FSS sealing key\n" - " --verify-key=KEY Specify FSS verification key\n" + " --interval=TIME Time interval for changing the FSS sealing key\n" + " --verify-key=KEY Specify FSS verification key\n" + " --force Force overriding new FSS key pair with --setup-keys\n" #endif "\nCommands:\n" - " -h --help Show this help\n" - " --version Show package version\n" - " --new-id128 Generate a new 128 Bit ID\n" - " --header Show journal header information\n" - " --disk-usage Show total disk usage\n" - " -F --field=FIELD List all values a certain field takes\n" - " --list-catalog Show message IDs of all entries in the message catalog\n" - " --dump-catalog Show entries in the message catalog\n" - " --update-catalog Update the message catalog database\n" + " -h --help Show this help\n" + " --version Show package version\n" + " --new-id128 Generate a new 128 Bit ID\n" + " --header Show journal header information\n" + " --disk-usage Show total disk usage\n" + " -F --field=FIELD List all values a certain field takes\n" + " --list-catalog Show message IDs of all entries in the message catalog\n" + " --dump-catalog Show entries in the message catalog\n" + " --update-catalog Update the message catalog database\n" #ifdef HAVE_GCRYPT - " --setup-keys Generate new FSS key pair\n" - " --force Force overriding new FSS key pair with --setup-keys\n" - " --verify Verify journal file consistency\n" + " --setup-keys Generate new FSS key pair\n" + " --verify Verify journal file consistency\n" #endif , program_invocation_short_name); @@ -183,6 +187,8 @@ static int parse_argv(int argc, char *argv[]) { ARG_DISK_USAGE, ARG_SINCE, ARG_UNTIL, + ARG_AFTER_CURSOR, + ARG_SHOW_CURSOR, ARG_USER_UNIT, ARG_LIST_CATALOG, ARG_DUMP_CATALOG, @@ -191,47 +197,49 @@ static int parse_argv(int argc, char *argv[]) { }; static const struct option options[] = { - { "help", no_argument, NULL, 'h' }, - { "version" , no_argument, NULL, ARG_VERSION }, - { "no-pager", no_argument, NULL, ARG_NO_PAGER }, - { "pager-end", no_argument, NULL, 'e' }, - { "follow", no_argument, NULL, 'f' }, - { "force", no_argument, NULL, ARG_FORCE }, - { "output", required_argument, NULL, 'o' }, - { "all", no_argument, NULL, 'a' }, - { "full", no_argument, NULL, 'l' }, - { "lines", optional_argument, NULL, 'n' }, - { "no-tail", no_argument, NULL, ARG_NO_TAIL }, - { "new-id128", no_argument, NULL, ARG_NEW_ID128 }, - { "quiet", no_argument, NULL, 'q' }, - { "merge", no_argument, NULL, 'm' }, - { "boot", optional_argument, NULL, 'b' }, - { "this-boot", optional_argument, NULL, 'b' }, /* deprecated */ - { "dmesg", no_argument, NULL, 'k' }, - { "system", no_argument, NULL, ARG_SYSTEM }, - { "user", no_argument, NULL, ARG_USER }, - { "directory", required_argument, NULL, 'D' }, - { "file", required_argument, NULL, ARG_FILE }, - { "root", required_argument, NULL, ARG_ROOT }, - { "header", no_argument, NULL, ARG_HEADER }, - { "priority", required_argument, NULL, 'p' }, - { "setup-keys", no_argument, NULL, ARG_SETUP_KEYS }, - { "interval", required_argument, NULL, ARG_INTERVAL }, - { "verify", no_argument, NULL, ARG_VERIFY }, - { "verify-key", required_argument, NULL, ARG_VERIFY_KEY }, - { "disk-usage", no_argument, NULL, ARG_DISK_USAGE }, - { "cursor", required_argument, NULL, 'c' }, - { "since", required_argument, NULL, ARG_SINCE }, - { "until", required_argument, NULL, ARG_UNTIL }, - { "unit", required_argument, NULL, 'u' }, - { "user-unit", required_argument, NULL, ARG_USER_UNIT }, - { "field", required_argument, NULL, 'F' }, - { "catalog", no_argument, NULL, 'x' }, - { "list-catalog", no_argument, NULL, ARG_LIST_CATALOG }, - { "dump-catalog", no_argument, NULL, ARG_DUMP_CATALOG }, - { "update-catalog",no_argument, NULL, ARG_UPDATE_CATALOG }, - { "reverse", no_argument, NULL, 'r' }, - { NULL, 0, NULL, 0 } + { "help", no_argument, NULL, 'h' }, + { "version" , no_argument, NULL, ARG_VERSION }, + { "no-pager", no_argument, NULL, ARG_NO_PAGER }, + { "pager-end", no_argument, NULL, 'e' }, + { "follow", no_argument, NULL, 'f' }, + { "force", no_argument, NULL, ARG_FORCE }, + { "output", required_argument, NULL, 'o' }, + { "all", no_argument, NULL, 'a' }, + { "full", no_argument, NULL, 'l' }, + { "lines", optional_argument, NULL, 'n' }, + { "no-tail", no_argument, NULL, ARG_NO_TAIL }, + { "new-id128", no_argument, NULL, ARG_NEW_ID128 }, + { "quiet", no_argument, NULL, 'q' }, + { "merge", no_argument, NULL, 'm' }, + { "boot", optional_argument, NULL, 'b' }, + { "this-boot", optional_argument, NULL, 'b' }, /* deprecated */ + { "dmesg", no_argument, NULL, 'k' }, + { "system", no_argument, NULL, ARG_SYSTEM }, + { "user", no_argument, NULL, ARG_USER }, + { "directory", required_argument, NULL, 'D' }, + { "file", required_argument, NULL, ARG_FILE }, + { "root", required_argument, NULL, ARG_ROOT }, + { "header", no_argument, NULL, ARG_HEADER }, + { "priority", required_argument, NULL, 'p' }, + { "setup-keys", no_argument, NULL, ARG_SETUP_KEYS }, + { "interval", required_argument, NULL, ARG_INTERVAL }, + { "verify", no_argument, NULL, ARG_VERIFY }, + { "verify-key", required_argument, NULL, ARG_VERIFY_KEY }, + { "disk-usage", no_argument, NULL, ARG_DISK_USAGE }, + { "cursor", required_argument, NULL, 'c' }, + { "after-cursor", required_argument, NULL, ARG_AFTER_CURSOR }, + { "show-cursor", no_argument, NULL, ARG_SHOW_CURSOR }, + { "since", required_argument, NULL, ARG_SINCE }, + { "until", required_argument, NULL, ARG_UNTIL }, + { "unit", required_argument, NULL, 'u' }, + { "user-unit", required_argument, NULL, ARG_USER_UNIT }, + { "field", required_argument, NULL, 'F' }, + { "catalog", no_argument, NULL, 'x' }, + { "list-catalog", no_argument, NULL, ARG_LIST_CATALOG }, + { "dump-catalog", no_argument, NULL, ARG_DUMP_CATALOG }, + { "update-catalog", no_argument, NULL, ARG_UPDATE_CATALOG }, + { "reverse", no_argument, NULL, 'r' }, + { NULL, 0, NULL, 0 } }; int c, r; @@ -379,6 +387,14 @@ static int parse_argv(int argc, char *argv[]) { arg_cursor = optarg; break; + case ARG_AFTER_CURSOR: + arg_after_cursor = optarg; + break; + + case ARG_SHOW_CURSOR: + arg_show_cursor = true; + break; + case ARG_HEADER: arg_action = ACTION_PRINT_HEADER; break; @@ -549,8 +565,8 @@ static int parse_argv(int argc, char *argv[]) { return -EINVAL; } - if (arg_cursor && arg_since_set) { - log_error("Please specify either --since= or --cursor=, not both."); + if (!!arg_cursor + !!arg_after_cursor + !!arg_since_set > 1) { + log_error("Please specify only one of --since=, --cursor=, and --after-cursor."); return -EINVAL; } @@ -1435,16 +1451,20 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } - if (arg_cursor) { - r = sd_journal_seek_cursor(j, arg_cursor); + if (arg_cursor || arg_after_cursor) { + r = sd_journal_seek_cursor(j, arg_cursor ? arg_cursor : arg_after_cursor); if (r < 0) { log_error("Failed to seek to cursor: %s", strerror(-r)); return EXIT_FAILURE; } if (!arg_reverse) - r = sd_journal_next(j); + r = sd_journal_next_skip(j, 1 + !!arg_after_cursor); else - r = sd_journal_previous(j); + r = sd_journal_previous_skip(j, 1 + !!arg_after_cursor); + + if (arg_after_cursor && r < 2 && !arg_follow) + /* We couldn't find the next entry after the cursor. */ + arg_lines = 0; } else if (arg_since_set && !arg_reverse) { r = sd_journal_seek_realtime_usec(j, arg_since); @@ -1592,8 +1612,19 @@ int main(int argc, char *argv[]) { n_shown++; } - if (!arg_follow) + if (!arg_follow) { + if (arg_show_cursor) { + _cleanup_free_ char *cursor = NULL; + + r = sd_journal_get_cursor(j, &cursor); + if (r < 0 && r != -EADDRNOTAVAIL) + log_error("Failed to get cursor: %s", strerror(-r)); + else if (r >= 0) + printf("-- cursor: %s\n", cursor); + } + break; + } r = sd_journal_wait(j, (uint64_t) -1); if (r < 0) { -- cgit v1.2.1 From 4ad16808c02e3eb6c1ec8500b3d086cc28e9b75a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 16 Jul 2013 14:45:28 -0400 Subject: journalctl,systemctl: fix tiny memleak --- src/journal/journalctl.c | 7 ++++++- src/journal/sd-journal.c | 2 +- src/shared/logs-show.c | 7 ++++++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 7415abc74f..7099706696 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -1408,7 +1408,12 @@ int main(int argc, char *argv[]) { if (r < 0) return EXIT_FAILURE; - log_debug("Journal filter: %s", j->level0 ? journal_make_match_string(j) : "none"); + if (_unlikely_(log_get_max_level() >= LOG_PRI(LOG_DEBUG))) { + _cleanup_free_ char *filter; + + filter = journal_make_match_string(j); + log_debug("Journal filter: %s", filter); + } if (arg_field) { const void *data; diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index 81b0c136f5..a83c0c25bf 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -362,7 +362,7 @@ static char *match_make_string(Match *m) { bool enclose = false; if (!m) - return strdup(""); + return strdup("none"); if (m->type == MATCH_DISCRETE) return strndup(m->data, m->size); diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index 8dc11bb7fd..ea4746879b 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -1059,7 +1059,12 @@ int show_journal_by_unit( if (r < 0) return r; - log_debug("Journal filter: %s", journal_make_match_string(j)); + if (_unlikely_(log_get_max_level() >= LOG_PRI(LOG_DEBUG))) { + _cleanup_free_ char *filter; + + filter = journal_make_match_string(j); + log_debug("Journal filter: %s", filter); + } r = show_journal(f, j, mode, n_columns, not_before, how_many, flags); if (r < 0) -- cgit v1.2.1 From 69af45035913e7119cffd94c542bd3039600e45d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 16 Jul 2013 22:44:38 -0400 Subject: Update TODO This point was done in 77a9e8de6. --- TODO | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/TODO b/TODO index 06771d5bf5..ac5ae71fd1 100644 --- a/TODO +++ b/TODO @@ -66,15 +66,13 @@ Features: * when a kernel driver logs in a tight loop we should ratelimit that too. -* man: document in the journalctl man page what the colors mean - * "systemctl disable" of a unit instance removes all symlinks, should - only remove the instance symlink (systemct disable of a template + only remove the instance symlink (systemctl disable of a template unit however should remove them all). * journald: optionally, log debug messages to /run but everything else to /var -* journald: optionally, when messages with a high log prioerity are logged, sync() immeidately. +* journald: optionally, when messages with a high log priority are logged, sync() immediately. * introduce %v resolving to the string returned by "uname -r" @@ -117,7 +115,7 @@ Features: validity of session name before appending it to a path * gparted needs to disable auto-activation of mount units somehow, or - maybe we should stop doing auto-activiation of this after boot + maybe we should stop doing auto-activation of this after boot entirely. https://bugzilla.gnome.org/show_bug.cgi?id=701676 * when a service changes state make reflect that in the @@ -174,9 +172,9 @@ Features: * Introduce a way how we can kill the main process of a service with KillSignal, but all processes with SIGKILL later on https://bugzilla.redhat.com/show_bug.cgi?id=952634 -* maybe add a warning to the unit file parses whern the acces mode of unit files is non-sensical. +* maybe add a warning to the unit file parses where the access mode of unit files is nonsensical. -* investigate endianess issues of UUID vs. GUID +* investigate endianness issues of UUID vs. GUID * dbus: when a unit failed to load (i.e. is in UNIT_ERROR state), we should be able to safely try another attempt when the bus call LoadUnit() is invoked. @@ -251,7 +249,7 @@ Features: and we might want to requeue the mounts local-fs acquired through that automatically. -* rework specifier logic so that we can distuingish OOM errors from other errors +* rework specifier logic so that we can distinguish OOM errors from other errors * systemd-inhibit: make taking delay locks useful: support sending SIGINT or SIGTERM on PrepareForSleep() @@ -261,13 +259,13 @@ Features: * documentation: recommend to connect the timer units of a service to the service via Also= in [Install] -* add a tool that lists active timer units plus their next elapstion and the time the units ran last +* add a tool that lists active timer units plus their next elapse and the time the units ran last * man: document the very specific env the shutdown drop-in tools live in * shutdown logging: store to EFI var, and store to USB stick? -* man: extend runlevel(8) to mention that runlevels suck, and are dead. Maybe add runlevel(7) with a note about that too +* man: extend runlevel(8) to mention that runlevels suck, and are dead. Maybe add runlevel(7) with a note about that too * systemctl: maybe add "systemctl add-wants" or so... -- cgit v1.2.1 From 956eaf2b8d6c9999024705ddadc7393bc707de02 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Wed, 17 Jul 2013 11:19:39 +0200 Subject: remove /run/initramfs/root-fsck logic dracut uses systemd in the initramfs and does not write these files anymore. The state of the root fsck is serialized. --- src/core/mount-setup.c | 10 ---------- units/systemd-fsck-root.service.in | 2 -- 2 files changed, 12 deletions(-) diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c index 4629808a7a..4359f59908 100644 --- a/src/core/mount-setup.c +++ b/src/core/mount-setup.c @@ -350,14 +350,8 @@ static int nftw_cb( }; int mount_setup(bool loaded_policy) { - - static const char relabel[] = - "/run/initramfs/root-fsck\0" - "/run/initramfs/shutdown\0"; - int r; unsigned i; - const char *j; for (i = 0; i < ELEMENTSOF(mount_table); i ++) { r = mount_one(mount_table + i, true); @@ -379,10 +373,6 @@ int mount_setup(bool loaded_policy) { nftw("/dev", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL); nftw("/run", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL); - /* Explicitly relabel these */ - NULSTR_FOREACH(j, relabel) - label_fix(j, true, false); - after_relabel = now(CLOCK_MONOTONIC); log_info("Relabelled /dev and /run in %s.", diff --git a/units/systemd-fsck-root.service.in b/units/systemd-fsck-root.service.in index ef5123feb8..563129badb 100644 --- a/units/systemd-fsck-root.service.in +++ b/units/systemd-fsck-root.service.in @@ -12,8 +12,6 @@ DefaultDependencies=no After=systemd-readahead-collect.service systemd-readahead-replay.service Before=local-fs.target shutdown.target -# Dracut informs us with this flag file if the root fsck was already run -ConditionPathExists=!/run/initramfs/root-fsck ConditionPathIsReadWrite=!/ [Service] -- cgit v1.2.1 From c72aadd1851096ea979f68b4e32cca71746ccdc4 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Wed, 17 Jul 2013 11:27:32 +0200 Subject: remove RD_TIMESTAMP import If you want timing information from the initramfs, use systemd in the initramfs. --- src/core/main.c | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index 749397578a..77cdcfe872 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1145,25 +1145,6 @@ static int bump_rlimit_nofile(struct rlimit *saved_rlimit) { return 0; } -static struct dual_timestamp* parse_initrd_timestamp(struct dual_timestamp *t) { - const char *e; - unsigned long long a, b; - - assert(t); - - e = getenv("RD_TIMESTAMP"); - if (!e) - return NULL; - - if (sscanf(e, "%llu %llu", &a, &b) != 2) - return NULL; - - t->realtime = (usec_t) a; - t->monotonic = (usec_t) b; - - return t; -} - static void test_mtab(void) { char *p; @@ -1484,12 +1465,6 @@ int main(int argc, char *argv[]) { arg_running_as == SYSTEMD_SYSTEM); if (arg_running_as == SYSTEMD_SYSTEM) { - /* Parse the data passed to us. We leave this - * variables set, but the manager later on will not - * pass them on to our children. */ - if (!in_initrd()) - parse_initrd_timestamp(&initrd_timestamp); - /* Unset some environment variables passed in from the * kernel that don't really make sense for us. */ unsetenv("HOME"); -- cgit v1.2.1 From c961869ac580f5a3aea3737f9e45af71b0983662 Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Wed, 12 Jun 2013 08:41:16 +0200 Subject: service: don't enter a second SIGTERM/SIGKILL cycle if no ExecStopPost= process is defined It won't help if the main process is still there and there is no new process to kill. --- src/core/service.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/service.c b/src/core/service.c index 2bc0dc5877..b98f11aed8 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -1987,7 +1987,7 @@ static void service_enter_stop_post(Service *s, ServiceResult f) { service_set_state(s, SERVICE_STOP_POST); } else - service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_SUCCESS); + service_enter_dead(s, SERVICE_SUCCESS, true); return; -- cgit v1.2.1 From c3bb87dbab8b79bb9253407cb5b7f3e6fe8db395 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 18 Jul 2013 02:29:06 +0200 Subject: update TODO --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index ac5ae71fd1..4b75539f0a 100644 --- a/TODO +++ b/TODO @@ -56,6 +56,8 @@ CGroup Rework Completion: Features: +* btfs raid assembly: some .device jobs stay stuck in the queue + * Fedora: add an rpmlint check that verifies that all unit files in the RPM are listed in %systemd_post macros. * Fedora: post FPC ticket to move add %tmpfiles_create to the packaging guidelines -- cgit v1.2.1 From 20422497109aaba1d214f1597530de8b8788a526 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 18 Jul 2013 02:31:01 +0200 Subject: mount: also exclude /usr from unmount at shutdown --- src/core/mount.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/mount.c b/src/core/mount.c index 58a3f1160f..c7d29b0c88 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -1543,7 +1543,8 @@ static int mount_add_one( if (r < 0) goto fail; - if (!path_equal(where, "/")) { + if (!path_equal(where, "/") && + !path_equal(where, "/usr")) { r = unit_add_dependency_by_name(u, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true); if (r < 0) goto fail; -- cgit v1.2.1 From 2ce982f9b1a9f409b10fc4c0f3faa6b594b58df9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 18 Jul 2013 02:31:06 +0200 Subject: systemctl: also highlight a load state of "not-found" as red "not-found" is a recently added load state and was previously just a special case of "error". Since it also indicates a load error we should also highlight it red, the same way as "error" was treated before. --- src/systemctl/systemctl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 9574ff20bd..6fdbc417b6 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -381,7 +381,8 @@ static void output_units_list(const struct unit_info *unit_infos, unsigned c) { n_shown++; - if (streq(u->load_state, "error")) { + if (streq(u->load_state, "error") || + streq(u->load_state, "not-found")) { on_loaded = on = ansi_highlight_red(true); off_loaded = off = ansi_highlight_red(false); } else -- cgit v1.2.1 From ce39bb6909578017aa10031638e724e038f0b859 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 18 Jul 2013 03:05:51 +0200 Subject: hwdb: data update --- hwdb/20-OUI.hwdb | 81 +++++++++++++++++++++++++++++++++++++++++++ hwdb/20-pci-vendor-model.hwdb | 8 ++++- hwdb/60-keyboard.hwdb | 38 ++++++++++---------- 3 files changed, 107 insertions(+), 20 deletions(-) diff --git a/hwdb/20-OUI.hwdb b/hwdb/20-OUI.hwdb index fe751ed447..5ebd6413b9 100644 --- a/hwdb/20-OUI.hwdb +++ b/hwdb/20-OUI.hwdb @@ -13129,6 +13129,18 @@ OUI:40D855138* OUI:40D855139* ID_OUI_FROM_DATABASE=WOW System +OUI:40D85513A* + ID_OUI_FROM_DATABASE=Supplier Ind. e Com de Eletroeletrônicos + +OUI:40D85513B* + ID_OUI_FROM_DATABASE=Davin Technologies Co.,Ltd + +OUI:40D85513C* + ID_OUI_FROM_DATABASE=shanghai anjian Information technology co. , ltd. + +OUI:40D85513D* + ID_OUI_FROM_DATABASE=Perm Scientific-Industrial Instrument Making Company JSC + OUI:000000* ID_OUI_FROM_DATABASE=XEROX CORPORATION @@ -46123,6 +46135,9 @@ OUI:0075E1* OUI:00789E* ID_OUI_FROM_DATABASE=SAGEMCOM +OUI:007DFA* + ID_OUI_FROM_DATABASE=Volkswagen Group of America + OUI:007F28* ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc @@ -52657,6 +52672,9 @@ OUI:141BF0* OUI:1423D7* ID_OUI_FROM_DATABASE=EUTRONIX CO., LTD. +OUI:142BD2* + ID_OUI_FROM_DATABASE=Armtel Ltd. + OUI:142D8B* ID_OUI_FROM_DATABASE=Incipio Technologies, Inc @@ -53884,6 +53902,9 @@ OUI:284846* OUI:284C53* ID_OUI_FROM_DATABASE=Intune Networks +OUI:284D92* + ID_OUI_FROM_DATABASE=Luminator + OUI:284FCE* ID_OUI_FROM_DATABASE=Liaoning Wontel Science and Technology Development Co.,Ltd. @@ -56203,6 +56224,9 @@ OUI:50252B* OUI:502690* ID_OUI_FROM_DATABASE=Fujitsu Limited +OUI:5027C7* + ID_OUI_FROM_DATABASE=TECHNART Co.,Ltd + OUI:502A7E* ID_OUI_FROM_DATABASE=Smart electronic GmbH @@ -57109,6 +57133,9 @@ OUI:601E02* OUI:6021C0* ID_OUI_FROM_DATABASE=Murata Manufactuaring Co.,Ltd. +OUI:6024C1* + ID_OUI_FROM_DATABASE=Jiangsu Zhongxun Electronic Technology Co., Ltd + OUI:602A54* ID_OUI_FROM_DATABASE=CardioTek B.V. @@ -57229,6 +57256,9 @@ OUI:60A10A* OUI:60A44C* ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. +OUI:60A9B0* + ID_OUI_FROM_DATABASE=Merchandising Technologies, Inc + OUI:60B185* ID_OUI_FROM_DATABASE=ATH system @@ -57967,6 +57997,9 @@ OUI:6C5779* OUI:6C5A34* ID_OUI_FROM_DATABASE=Shenzhen Haitianxiong Electronic Co., Ltd. +OUI:6C5AB5* + ID_OUI_FROM_DATABASE=TCL Technoly Electronics (Huizhou) Co., Ltd. + OUI:6C5CDE* ID_OUI_FROM_DATABASE=SunReports, Inc. @@ -58759,6 +58792,9 @@ OUI:78593E* OUI:78595E* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +OUI:785968* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind.Co.,Ltd. + OUI:785C72* ID_OUI_FROM_DATABASE=Hioso Technology Co., Ltd. @@ -58912,6 +58948,9 @@ OUI:78D5B5* OUI:78D6F0* ID_OUI_FROM_DATABASE=Samsung Electro Mechanics +OUI:78D99F* + ID_OUI_FROM_DATABASE=NuCom HK Ltd. + OUI:78DAB3* ID_OUI_FROM_DATABASE=GBO Technology @@ -59491,6 +59530,9 @@ OUI:8400D2* OUI:840B2D* ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS CO., LTD +OUI:840F45* + ID_OUI_FROM_DATABASE=Shanghai GMT Digital Technologies Co., Ltd + OUI:841715* ID_OUI_FROM_DATABASE=GP Electronics (HK) Ltd. @@ -59806,6 +59848,9 @@ OUI:887398* OUI:887556* ID_OUI_FROM_DATABASE=Cisco +OUI:88789C* + ID_OUI_FROM_DATABASE=Game Technologies SA + OUI:8886A0* ID_OUI_FROM_DATABASE=Simton Technologies, Ltd. @@ -60643,6 +60688,9 @@ OUI:94DE0E* OUI:94DE80* ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD. +OUI:94DF4E* + ID_OUI_FROM_DATABASE=Wistron InfoComm(Kunshan)Co.,Ltd. + OUI:94DF58* ID_OUI_FROM_DATABASE=IJ Electron CO.,Ltd. @@ -61060,6 +61108,9 @@ OUI:9C9811* OUI:9C9C1D* ID_OUI_FROM_DATABASE=Starkey Labs Inc. +OUI:9CA10A* + ID_OUI_FROM_DATABASE=SCLE SFE + OUI:9CA134* ID_OUI_FROM_DATABASE=Nike, Inc. @@ -62572,6 +62623,9 @@ OUI:B4A4E3* OUI:B4A5A9* ID_OUI_FROM_DATABASE=MODI GmbH +OUI:B4A82B* + ID_OUI_FROM_DATABASE=Histar + OUI:B4A95A* ID_OUI_FROM_DATABASE=Avaya, Inc @@ -63121,6 +63175,9 @@ OUI:BC926B* OUI:BC9680* ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co.,Ltd +OUI:BC9889* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Tech.Co.,Ltd. + OUI:BC99BC* ID_OUI_FROM_DATABASE=FonSee Technology Inc. @@ -63391,6 +63448,9 @@ OUI:C0C3B6* OUI:C0C520* ID_OUI_FROM_DATABASE=Ruckus Wireless +OUI:C0C687* + ID_OUI_FROM_DATABASE=Cisco SPVTG + OUI:C0C946* ID_OUI_FROM_DATABASE=MITSUYA LABORATORIES INC. @@ -63598,6 +63658,9 @@ OUI:C49300* OUI:C49313* ID_OUI_FROM_DATABASE=100fio networks technology llc +OUI:C49380* + ID_OUI_FROM_DATABASE=Speedytel technology + OUI:C495A2* ID_OUI_FROM_DATABASE=SHENZHEN WEIJIU INDUSTRY AND TRADE DEVELOPMENT CO., LTD @@ -64261,6 +64324,9 @@ OUI:D023DB* OUI:D02788* ID_OUI_FROM_DATABASE=Hon Hai Precision Ind.Co.Ltd +OUI:D02C45* + ID_OUI_FROM_DATABASE=littleBits Electronics, Inc. + OUI:D02DB3* ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd @@ -64351,6 +64417,9 @@ OUI:D08CFF* OUI:D093F8* ID_OUI_FROM_DATABASE=Stonestreet One LLC +OUI:D095C7* + ID_OUI_FROM_DATABASE=Pantech Co., Ltd. + OUI:D09B05* ID_OUI_FROM_DATABASE=Emtronix @@ -64672,6 +64741,9 @@ OUI:D4AAFF* OUI:D4AC4E* ID_OUI_FROM_DATABASE=BODi rS, LLC +OUI:D4AD2D* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Tech.Co.,Ltd. + OUI:D4AE52* ID_OUI_FROM_DATABASE=Dell Inc @@ -65392,6 +65464,9 @@ OUI:E0ABFE* OUI:E0AE5E* ID_OUI_FROM_DATABASE=ALPS Co,. Ltd. +OUI:E0AEB2* + ID_OUI_FROM_DATABASE=Bender GmbH & Co.KG + OUI:E0AEED* ID_OUI_FROM_DATABASE=LOENK @@ -66739,6 +66814,9 @@ OUI:F80F84* OUI:F81037* ID_OUI_FROM_DATABASE=Atopia Systems, LP +OUI:F81547* + ID_OUI_FROM_DATABASE=Avaya, Inc + OUI:F81654* ID_OUI_FROM_DATABASE=Intel Corporate @@ -66787,6 +66865,9 @@ OUI:F83DFF* OUI:F842FB* ID_OUI_FROM_DATABASE=Yasuda Joho Co.,ltd. +OUI:F845AD* + ID_OUI_FROM_DATABASE=Konka Group Co., Ltd. + OUI:F8462D* ID_OUI_FROM_DATABASE=SYNTEC Incorporation diff --git a/hwdb/20-pci-vendor-model.hwdb b/hwdb/20-pci-vendor-model.hwdb index 45b25cdd4f..2436a29e9a 100644 --- a/hwdb/20-pci-vendor-model.hwdb +++ b/hwdb/20-pci-vendor-model.hwdb @@ -3923,6 +3923,9 @@ pci:v00001002d00005A20* pci:v00001002d00005A23* ID_MODEL_FROM_DATABASE=RD990 I/O Memory Management Unit (IOMMU) +pci:v00001002d00005A31* + ID_MODEL_FROM_DATABASE=RC410 Host Bridge + pci:v00001002d00005A33* ID_MODEL_FROM_DATABASE=Radeon Xpress 200 Host Bridge @@ -6186,7 +6189,7 @@ pci:v00001002d00006840sv000017AAsd00005103* ID_MODEL_FROM_DATABASE=Radeon HD 7670M pci:v00001002d00006841* - ID_MODEL_FROM_DATABASE=Thames [Radeon 7550M/7570M/7650M] + ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7550M/7570M/7650M] pci:v00001002d00006841sv00001028sd00000561* ID_MODEL_FROM_DATABASE=Radeon HD 7650M @@ -49064,6 +49067,9 @@ pci:v000018F7d00000025* pci:v000018F7d00000026* ID_MODEL_FROM_DATABASE=SuperFSCC-LVDS Serial PCI Adapter [Fastcom] +pci:v000018F7d00000027* + ID_MODEL_FROM_DATABASE=FSCC/4 Serial PCIe Adapter [Fastcom] + pci:v000018FB* ID_VENDOR_FROM_DATABASE=Resilience Corporation diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index 5470588f1e..0ee65d792a 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -569,12 +569,12 @@ keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad U300s*:pvr* # iTouch keyboard:usb:v046DpC308* - KEYBOARD_KEY_90001=shop # Shopping - KEYBOARD_KEY_90002=config # iTouch - KEYBOARD_KEY_90003=finance # Finance - KEYBOARD_KEY_90004=prog1 # My Sites - KEYBOARD_KEY_90005=prog2 # Community - KEYBOARD_KEY_C0183=media # Media + KEYBOARD_KEY_90001=shop # Shopping + KEYBOARD_KEY_90002=config # iTouch + KEYBOARD_KEY_90003=finance # Finance + KEYBOARD_KEY_90004=prog1 # My Sites + KEYBOARD_KEY_90005=prog2 # Community + KEYBOARD_KEY_C0183=media # Media # Cordless Desktop S510 keyboard:usb:v046DpC50C* @@ -583,21 +583,21 @@ keyboard:usb:v046DpC50C* # Wave cordless keyboard:usb:v046DpC317* - KEYBOARD_KEY_9001c=scale #expo + KEYBOARD_KEY_9001c=scale # expo KEYBOARD_KEY_9001f=zoomout KEYBOARD_KEY_90020=zoomin - KEYBOARD_KEY_9003d=prog1 #gadget + KEYBOARD_KEY_9003d=prog1 # gadget KEYBOARD_KEY_90005=camera KEYBOARD_KEY_90018=media KEYBOARD_KEY_90041=wordprocessor KEYBOARD_KEY_90042=spreadsheet KEYBOARD_KEY_90043=calendar - KEYBOARD_KEY_90044=prog2 #fn+f4 (program a) - KEYBOARD_KEY_90045=prog3 #fn+f5 (program b) - KEYBOARD_KEY_90046=prog4 #fn+f6 (program c) - KEYBOARD_KEY_90048=messenger #fn+f8 (msn messenger) - KEYBOARD_KEY_9002d=search #fn+f10 (search www) - KEYBOARD_KEY_9004b=find #fn+f11 (search pc) + KEYBOARD_KEY_90044=prog2 # fn+f4 (program a) + KEYBOARD_KEY_90045=prog3 # fn+f5 (program b) + KEYBOARD_KEY_90046=prog4 # fn+f6 (program c) + KEYBOARD_KEY_90048=messenger # fn+f8 (msn messenger) + KEYBOARD_KEY_9002d=search # fn+f10 (search www) + KEYBOARD_KEY_9004b=find # fn+f11 (search pc) KEYBOARD_KEY_9004c=ejectclosecd # Wave cordless @@ -609,11 +609,11 @@ keyboard:usb:v046DpC517* KEYBOARD_KEY_c1041=wordprocessor KEYBOARD_KEY_c1042=spreadsheet KEYBOARD_KEY_c1043=calendar - KEYBOARD_KEY_c1044=prog2 #fn+f4 (program a) - KEYBOARD_KEY_c1045=prog3 #fn+f5 (program b) - KEYBOARD_KEY_c1046=prog4 #fn+f6 (program c) - KEYBOARD_KEY_c1048=messenger #fn+f8 (msn messenger) - KEYBOARD_KEY_c104a=find #fn+f10 (search www) + KEYBOARD_KEY_c1044=prog2 # fn+f4 (program a) + KEYBOARD_KEY_c1045=prog3 # fn+f5 (program b) + KEYBOARD_KEY_c1046=prog4 # fn+f6 (program c) + KEYBOARD_KEY_c1048=messenger # fn+f8 (msn messenger) + KEYBOARD_KEY_c104a=find # fn+f10 (search www) KEYBOARD_KEY_c104c=ejectclosecd # Cordless Wave Pro -- cgit v1.2.1 From 1070f974f7a1b6ba012e352b9d635d3902eca244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 17 Jul 2013 12:50:43 -0400 Subject: systemd-python: fix iteration Back in 6a58bf4135 raising stop iteration was removed from the C code, but wasn't added in the Python counterpart. --- configure.ac | 1 - src/python-systemd/journal.py | 24 ++++++++++++------------ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/configure.ac b/configure.ac index 1cffbbb7e8..9095be7ca6 100644 --- a/configure.ac +++ b/configure.ac @@ -1005,7 +1005,6 @@ AC_MSG_RESULT([ nss-myhostname: ${have_myhostname} gudev: ${enable_gudev} gintrospection: ${enable_introspection} - keymap: ${enable_keymap} Python: ${have_python} Python Headers: ${have_python_devel} man pages: ${have_manpages} diff --git a/src/python-systemd/journal.py b/src/python-systemd/journal.py index 8fd1bb357c..adcc844f46 100644 --- a/src/python-systemd/journal.py +++ b/src/python-systemd/journal.py @@ -191,18 +191,18 @@ class Reader(_Reader): """ return self - if _sys.version_info >= (3,): - def __next__(self): - """Part of iterator protocol. - Returns self.get_next(). - """ - return self.get_next() - else: - def next(self): - """Part of iterator protocol. - Returns self.get_next(). - """ - return self.get_next() + def __next__(self): + """Part of iterator protocol. + Returns self.get_next() or raises StopIteration. + """ + ans = self.get_next() + if ans: + return ans + else: + raise StopIteration() + + if _sys.version_info < (3,): + next = __next__ def add_match(self, *args, **kwargs): """Add one or more matches to the filter journal log entries. -- cgit v1.2.1 From affba8e90243526be673ad9f9b306a740b8824a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 17 Jul 2013 12:50:13 -0400 Subject: systemd-python: add support for sd_j_open_files Also export missing flags. --- src/python-systemd/_daemon.c | 22 ------------ src/python-systemd/_reader.c | 84 ++++++++++++++++++++++++++++++++++++------- src/python-systemd/journal.py | 7 ++-- src/python-systemd/pyutil.c | 20 +++++++++++ src/python-systemd/pyutil.h | 4 +++ 5 files changed, 99 insertions(+), 38 deletions(-) diff --git a/src/python-systemd/_daemon.c b/src/python-systemd/_daemon.c index bd4e73e9be..6b84fb81c7 100644 --- a/src/python-systemd/_daemon.c +++ b/src/python-systemd/_daemon.c @@ -40,28 +40,6 @@ PyDoc_STRVAR(module__doc__, "running under systemd." ); - -#if PY_MAJOR_VERSION >=3 && PY_MINOR_VERSION >= 1 -static int Unicode_FSConverter(PyObject* obj, void *_result) { - PyObject **result = _result; - - assert(result); - - if (!obj) - /* cleanup: we don't return Py_CLEANUP_SUPPORTED, so - * we can assume that it was PyUnicode_FSConverter. */ - return PyUnicode_FSConverter(obj, result); - - if (obj == Py_None) { - *result = NULL; - return 1; - } - - return PyUnicode_FSConverter(obj, result); -} -#endif - - PyDoc_STRVAR(booted__doc__, "booted() -> bool\n\n" "Return True iff this system is running under systemd.\n" diff --git a/src/python-systemd/_reader.c b/src/python-systemd/_reader.c index 2c699630c2..6ac2f20491 100644 --- a/src/python-systemd/_reader.c +++ b/src/python-systemd/_reader.c @@ -30,6 +30,7 @@ #include "pyutil.h" #include "macro.h" #include "util.h" +#include "strv.h" #include "build.h" typedef struct { @@ -63,6 +64,57 @@ static PyStructSequence_Desc Monotonic_desc = { }; #endif +static int strv_converter(PyObject* obj, void *_result) { + char ***result = _result; + Py_ssize_t i, len; + + assert(result); + + if (!obj) + goto cleanup; + + if (!PySequence_Check(obj)) + return 0; + + len = PySequence_Length(obj); + *result = new0(char*, len + 1); + + for (i = 0; i < len; i++) { + PyObject *item; +#if PY_MAJOR_VERSION >=3 && PY_MINOR_VERSION >= 1 + int r; + PyObject *bytes; +#endif + char *s, *s2; + + item = PySequence_ITEM(obj, i); +#if PY_MAJOR_VERSION >=3 && PY_MINOR_VERSION >= 1 + r = PyUnicode_FSConverter(item, &bytes); + if (r == 0) + goto cleanup; + + s = PyBytes_AsString(bytes); +#else + s = PyString_AsString(item); +#endif + if (!s) + goto cleanup; + + s2 = strdup(s); + if (!s2) + log_oom(); + + (*result)[i] = s2; + } + + return 1; + +cleanup: + strv_free(*result); + *result = NULL; + + return 0; +} static void Reader_dealloc(Reader* self) { @@ -71,40 +123,45 @@ static void Reader_dealloc(Reader* self) } PyDoc_STRVAR(Reader__doc__, - "_Reader([flags | path]) -> ...\n\n" + "_Reader([flags | path | files]) -> ...\n\n" "_Reader allows filtering and retrieval of Journal entries.\n" "Note: this is a low-level interface, and probably not what you\n" "want, use systemd.journal.Reader instead.\n\n" "Argument `flags` sets open flags of the journal, which can be one\n" "of, or ORed combination of constants: LOCAL_ONLY (default) opens\n" "journal on local machine only; RUNTIME_ONLY opens only\n" - "volatile journal files; and SYSTEM_ONLY opens only\n" - "journal files of system services and the kernel.\n\n" - "Argument `path` is the directory of journal files. Note that\n" - "`flags` and `path` are exclusive.\n\n" + "volatile journal files; and SYSTEM opens journal files of\n" + "system services and the kernel, and CURRENT_USER opens files\n" + "of the current user.\n\n" + "Argument `path` is the directory of journal files.\n" + "Argument `files` is a list of files. Note that\n" + "`flags`, `path`, and `files` are exclusive.\n\n" "_Reader implements the context manager protocol: the journal\n" "will be closed when exiting the block."); static int Reader_init(Reader *self, PyObject *args, PyObject *keywds) { int flags = 0, r; char *path = NULL; + char **files = NULL; - static const char* const kwlist[] = {"flags", "path", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, keywds, "|iz", (char**) kwlist, - &flags, &path)) + static const char* const kwlist[] = {"flags", "path", "files", NULL}; + if (!PyArg_ParseTupleAndKeywords(args, keywds, "|izO&", (char**) kwlist, + &flags, &path, strv_converter, &files)) return -1; + if (!!flags + !!path + !!files > 1) { + PyErr_SetString(PyExc_ValueError, "cannot use more than one of flags, path, and files"); + return -1; + } + if (!flags) flags = SD_JOURNAL_LOCAL_ONLY; - else - if (path) { - PyErr_SetString(PyExc_ValueError, "cannot use both flags and path"); - return -1; - } Py_BEGIN_ALLOW_THREADS if (path) r = sd_journal_open_directory(&self->j, path, 0); + else if (files) + r = sd_journal_open_files(&self->j, (const char**) files, 0); else r = sd_journal_open(&self->j, flags); Py_END_ALLOW_THREADS @@ -1099,6 +1156,7 @@ init_reader(void) PyModule_AddIntConstant(m, "RUNTIME_ONLY", SD_JOURNAL_RUNTIME_ONLY) || PyModule_AddIntConstant(m, "SYSTEM", SD_JOURNAL_SYSTEM) || PyModule_AddIntConstant(m, "SYSTEM_ONLY", SD_JOURNAL_SYSTEM_ONLY) || + PyModule_AddIntConstant(m, "CURRENT_USER", SD_JOURNAL_CURRENT_USER) || PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION)) { #if PY_MAJOR_VERSION >= 3 Py_DECREF(m); diff --git a/src/python-systemd/journal.py b/src/python-systemd/journal.py index adcc844f46..d0bcd24d15 100644 --- a/src/python-systemd/journal.py +++ b/src/python-systemd/journal.py @@ -33,7 +33,8 @@ from syslog import (LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG) from ._journal import __version__, sendv, stream_fd from ._reader import (_Reader, NOP, APPEND, INVALIDATE, - LOCAL_ONLY, RUNTIME_ONLY, SYSTEM_ONLY, + LOCAL_ONLY, RUNTIME_ONLY, + SYSTEM, SYSTEM_ONLY, CURRENT_USER, _get_catalog) from . import id128 as _id128 @@ -123,7 +124,7 @@ class Reader(_Reader): See systemd.journal-fields(7) for more info on typical fields found in the journal. """ - def __init__(self, flags=0, path=None, converters=None): + def __init__(self, flags=0, path=None, files=None, converters=None): """Create an instance of Reader, which allows filtering and return of journal entries. @@ -149,7 +150,7 @@ class Reader(_Reader): Reader implements the context manager protocol: the journal will be closed when exiting the block. """ - super(Reader, self).__init__(flags, path) + super(Reader, self).__init__(flags, path, files) if _sys.version_info >= (3,3): self.converters = _ChainMap() if converters is not None: diff --git a/src/python-systemd/pyutil.c b/src/python-systemd/pyutil.c index 42e7ba72cf..722c4f5b5f 100644 --- a/src/python-systemd/pyutil.c +++ b/src/python-systemd/pyutil.c @@ -58,3 +58,23 @@ int set_error(int r, const char* path, const char* invalid_message) { } return -1; } + +#if PY_MAJOR_VERSION >=3 && PY_MINOR_VERSION >= 1 +int Unicode_FSConverter(PyObject* obj, void *_result) { + PyObject **result = _result; + + assert(result); + + if (!obj) + /* cleanup: we don't return Py_CLEANUP_SUPPORTED, so + * we can assume that it was PyUnicode_FSConverter. */ + return PyUnicode_FSConverter(obj, result); + + if (obj == Py_None) { + *result = NULL; + return 1; + } + + return PyUnicode_FSConverter(obj, result); +} +#endif diff --git a/src/python-systemd/pyutil.h b/src/python-systemd/pyutil.h index ea88840fa7..1477e7bf9c 100644 --- a/src/python-systemd/pyutil.h +++ b/src/python-systemd/pyutil.h @@ -30,6 +30,10 @@ void cleanup_Py_DECREFp(PyObject **p); PyObject* absolute_timeout(uint64_t t); int set_error(int r, const char* path, const char* invalid_message); +#if PY_MAJOR_VERSION >=3 && PY_MINOR_VERSION >= 1 +int Unicode_FSConverter(PyObject* obj, void *_result); +#endif + #define _cleanup_Py_DECREF_ __attribute__((cleanup(cleanup_Py_DECREFp))) #if PY_MAJOR_VERSION >=3 -- cgit v1.2.1 From d121b396ccb19dc33aacfc75a7f7a719914267c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 16 Jul 2013 15:56:22 -0400 Subject: journalctl: remove ":" from the --boot syntax Instead of :-0, :1, :5, etc., use -0, 1 or +1, 5, etc. For BOOT_ID+OFFSET, use BOOT_ID+offset or BOOT_ID-offset (either + or - is required). Also make error handling a bit more robust and verbose. Modify the man page to describe the most common case (-b) first, and the second most common case (-b -1) second. --- man/journalctl.xml | 74 +++++++++++---------- src/journal/journalctl.c | 164 +++++++++++++++++++++++------------------------ 2 files changed, 121 insertions(+), 117 deletions(-) diff --git a/man/journalctl.xml b/man/journalctl.xml index 3e03c45f13..65a59ea4e7 100644 --- a/man/journalctl.xml +++ b/man/journalctl.xml @@ -399,42 +399,50 @@ - - + + - Show messages from the specified - boot ID or from - current boot if no ID - is given. This will add a match for + Show messages from a specific + boot. This will add a match for _BOOT_ID=. - The argument is a 128 bit ID given in - short or UUID form and optionally followed by - :n which identifies the nth - boot relative to the boot ID given to the left - of :. Supplying a negative - value for n will look for a past boot and a - positive value for a future boot. The boot IDs - are searched for in chronological order. If no - number is provided after :, - -1 is assumed. A value of 0 - is valid and equivalent to omitting - :0. - - Alternatively, the argument may constist - only of :n. In this case, a - positive value will look up the nth boot - starting from the beginning of the jouranl, a - negative value will look up a previous boot - relative to the current boot. :0 - will look for the current boot ID. Thus, - :1 is the first boot found in - the journal, :2 the second - and so on; while :-1 is the - previous boot, :-2 the boot - before that and so on. Omitting a value after - : will look for the previous - boot. + The argument may be empty, in which case + logs for the current boot will be shown. + + If the boot ID is omitted, a positive + offset will look up + the boots starting from the beginning of the + journal, and a equal-or-less-than zero + offset will look up + boots starting from the end of the + journal. Thus, 1 means the + first boot found in the journal in the + chronological order, 2 the + second and so on; while -0 + is the last boot, -1 the + boot before that, and so on. An empty + offset is equivalent + to specifying -0, except + when the current boot is not the last boot + (e.g. because was + specified to look at logs from a different + machine). + + If the 32 character + ID is specified, it + may optionally be followed by + offset which + identifies the boot relative to the one given by + boot ID. Negative + values mean earlier boots and a positive values + mean later boots. If + offset is not + specified, a value of zero is assumed and the + logs for the boot given by + ID are shown. + + + diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 7099706696..9a40d69a75 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -70,8 +70,8 @@ static int arg_lines = -1; static bool arg_no_tail = false; static bool arg_quiet = false; static bool arg_merge = false; -static bool arg_boot_id = false; -static char *arg_boot_id_descriptor = NULL; +static bool arg_boot = false; +static char *arg_boot_descriptor = NULL; static bool arg_dmesg = false; static const char *arg_cursor = NULL; static const char *arg_after_cursor = NULL; @@ -346,17 +346,24 @@ static int parse_argv(int argc, char *argv[]) { break; case 'b': + arg_boot = true; + if (optarg) - arg_boot_id_descriptor = optarg; - else if (optind < argc && argv[optind][0] != '-') { - arg_boot_id_descriptor = argv[optind]; - optind++; + arg_boot_descriptor = optarg; + else if (optind < argc) { + int boot; + + if (argv[optind][0] != '-' || + safe_atoi(argv[optind], &boot) >= 0) { + arg_boot_descriptor = argv[optind]; + optind++; + } } - arg_boot_id = true; + break; case 'k': - arg_boot_id = arg_dmesg = true; + arg_boot = arg_dmesg = true; break; case ARG_SYSTEM: @@ -671,23 +678,17 @@ static int boot_id_cmp(const void *a, const void *b) { static int get_relative_boot_id(sd_journal *j, sd_id128_t *boot_id, int relative) { int r; const void *data; - unsigned int id_count = 0; + unsigned int count = 0; size_t length, allocated = 0; - boot_id_t ref_boot_id, *id; + boot_id_t ref_boot_id = {SD_ID128_NULL}, *id; _cleanup_free_ boot_id_t *all_ids = NULL; - bool find_first_boot = false, ref_boot_found = false; assert(j); assert(boot_id); - if (relative == 0) + if (relative == 0 && !sd_id128_equal(*boot_id, SD_ID128_NULL)) return 0; - if (sd_id128_equal(*boot_id, SD_ID128_NULL) && relative > 0) { - find_first_boot = true; - relative--; - } - r = sd_journal_query_unique(j, "_BOOT_ID"); if (r < 0) return r; @@ -696,123 +697,118 @@ static int get_relative_boot_id(sd_journal *j, sd_id128_t *boot_id, int relative if (length < strlen("_BOOT_ID=")) continue; - if (!GREEDY_REALLOC(all_ids, allocated, id_count + 1)) + if (!GREEDY_REALLOC(all_ids, allocated, count + 1)) return log_oom(); - id = &all_ids[id_count]; + id = &all_ids[count]; r = sd_id128_from_string(((const char *)data) + strlen("_BOOT_ID="), &id->id); - if (r < 0) { + if (r < 0) continue; - } - sd_journal_flush_matches(j); r = sd_journal_add_match(j, data, length); if (r < 0) - continue; + return r; r = sd_journal_seek_head(j); if (r < 0) - continue; + return r; r = sd_journal_next(j); - if (r <= 0) - continue; + if (r < 0) + return r; + else if (r == 0) + goto flush; r = sd_journal_get_realtime_usec(j, &id->timestamp); if (r < 0) - continue; + return r; - if (!find_first_boot && sd_id128_equal(id->id, *boot_id)) { + if (sd_id128_equal(id->id, *boot_id)) ref_boot_id = *id; - ref_boot_found = true; - } - id_count++; + count++; + flush: + sd_journal_flush_matches(j); } - *boot_id = SD_ID128_NULL; - sd_journal_flush_matches(j); + qsort(all_ids, count, sizeof(boot_id_t), boot_id_cmp); - if (id_count == 0 || (!find_first_boot && !ref_boot_found)) - return 0; + if (sd_id128_equal(*boot_id, SD_ID128_NULL)) { + if (relative > (int) count || relative <= -(int)count) + return -EADDRNOTAVAIL; - qsort(all_ids, id_count, sizeof(boot_id_t), boot_id_cmp); - if (find_first_boot) - id = all_ids; - else - id = bsearch(&ref_boot_id, all_ids, id_count, sizeof(boot_id_t), boot_id_cmp); + *boot_id = all_ids[(relative <= 0)*count + relative - 1].id; + } else { + id = bsearch(&ref_boot_id, all_ids, count, sizeof(boot_id_t), boot_id_cmp); - if (!id || (relative < 0 && ((id - all_ids) + relative) < 0) || - (relative >= 0 && (unsigned long)((id - all_ids) + relative) >= id_count)) - return 0; + if (!id || + relative <= 0 ? (id - all_ids) + relative < 0 : + (id - all_ids) + relative >= count) + return -EADDRNOTAVAIL; + + *boot_id = (id + relative)->id; + } - id += relative; - *boot_id = id->id; return 0; } static int add_boot(sd_journal *j) { char match[9+32+1] = "_BOOT_ID="; - char *marker; - sd_id128_t boot_id; + char *offset; + sd_id128_t boot_id = SD_ID128_NULL; int r, relative = 0; assert(j); - if (!arg_boot_id) + if (!arg_boot) return 0; - if (arg_boot_id_descriptor) { - marker = strchr(arg_boot_id_descriptor, ':'); - if (marker) { - *marker = '\0'; - marker++; + if (!arg_boot_descriptor) + return add_match_this_boot(j); - if (*marker == '\0') - relative = -1; - else { - r = safe_atoi(marker, &relative); - if (r < 0) { - log_error("Failed to parse relative boot ID number '%s'", marker); - return -EINVAL; - } - } + if (strlen(arg_boot_descriptor) >= 32) { + char tmp = arg_boot_descriptor[32]; + arg_boot_descriptor[32] = '\0'; + r = sd_id128_from_string(arg_boot_descriptor, &boot_id); + arg_boot_descriptor[32] = tmp; + + if (r < 0) { + log_error("Failed to parse boot ID '%.32s': %s", + arg_boot_descriptor, strerror(-r)); + return r; } - } - if (isempty(arg_boot_id_descriptor)) { - if (relative > 0) { - /* We cannot look into the future. Instead, we look - * into the past (starting from first boot). The ID - * will be looked up later */ - boot_id = SD_ID128_NULL; - } else { - r = sd_id128_get_boot(&boot_id); - if (r < 0) { - log_error("Failed to get boot ID: %s", strerror(-r)); - return r; - } + offset = arg_boot_descriptor + 32; + + if (*offset != '-' && *offset != '+') { + log_error("Relative boot ID offset must start with a '+' or a '-', found '%s' ", offset); + return -EINVAL; } - } else { - r = sd_id128_from_string(arg_boot_id_descriptor, &boot_id); + } else + offset = arg_boot_descriptor; + + if (*offset) { + r = safe_atoi(offset, &relative); if (r < 0) { - log_error("Failed to parse boot ID: %s", strerror(-r)); - return r; + log_error("Failed to parse relative boot ID number '%s'", offset); + return -EINVAL; } } r = get_relative_boot_id(j, &boot_id, relative); if (r < 0) { - log_error("Failed to look up boot ID: %s", strerror(-r)); + if (sd_id128_equal(boot_id, SD_ID128_NULL)) + log_error("Failed to look up boot %+d: %s", relative, strerror(-r)); + else + log_error("Failed to look up boot ID "SD_ID128_FORMAT_STR"%+d: %s", + SD_ID128_FORMAT_VAL(boot_id), relative, strerror(-r)); return r; - } else if (sd_id128_equal(boot_id, SD_ID128_NULL)) { - log_error("Failed to find boot ID"); - return -1; } sd_id128_to_string(boot_id, match + 9); - r = sd_journal_add_match(j, match, strlen(match)); + + r = sd_journal_add_match(j, match, sizeof(match) - 1); if (r < 0) { log_error("Failed to add match: %s", strerror(-r)); return r; -- cgit v1.2.1 From 4b744dfabebd10bf0f13b64060f44b1bd6c82704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 25 Jun 2013 12:15:07 -0400 Subject: systemd: log failed conditions ConditionPathExists=/tmp/nosuchpath failed for nosuchpath.service. --- src/core/condition.c | 12 +++++++++++- src/core/condition.h | 2 +- src/core/unit.c | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/core/condition.c b/src/core/condition.c index 427aa080ad..2fbc5ad0e6 100644 --- a/src/core/condition.c +++ b/src/core/condition.c @@ -37,6 +37,7 @@ #include "virt.h" #include "path-util.h" #include "fileio.h" +#include "unit.h" Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate) { Condition *c; @@ -333,7 +334,7 @@ bool condition_test(Condition *c) { } } -bool condition_test_list(Condition *first) { +bool condition_test_list(const char *unit, Condition *first) { Condition *c; int triggered = -1; @@ -348,6 +349,15 @@ bool condition_test_list(Condition *first) { bool b; b = condition_test(c); + if (unit) + log_debug_unit(unit, + "%s=%s%s%s %s for %s.", + condition_type_to_string(c->type), + c->trigger ? "|" : "", + c->negate ? "!" : "", + c->parameter, + b ? "succeeded" : "failed", + unit); if (!c->trigger && !b) return false; diff --git a/src/core/condition.h b/src/core/condition.h index 50ed955af9..2ad77876e4 100644 --- a/src/core/condition.h +++ b/src/core/condition.h @@ -61,7 +61,7 @@ void condition_free(Condition *c); void condition_free_list(Condition *c); bool condition_test(Condition *c); -bool condition_test_list(Condition *c); +bool condition_test_list(const char *unit, Condition *c); void condition_dump(Condition *c, FILE *f, const char *prefix); void condition_dump_list(Condition *c, FILE *f, const char *prefix); diff --git a/src/core/unit.c b/src/core/unit.c index f4f92f0fca..a201fa4041 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -996,7 +996,7 @@ bool unit_condition_test(Unit *u) { assert(u); dual_timestamp_get(&u->condition_timestamp); - u->condition_result = condition_test_list(u->conditions); + u->condition_result = condition_test_list(u->id, u->conditions); return u->condition_result; } -- cgit v1.2.1 From 52990c2e0eabd1c11280f553f858062d4165b92f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 25 Jun 2013 16:09:07 -0400 Subject: systemd,systemctl: export condition status and show failing condition $ systemctl --user status hoohoo hoohoo.service Loaded: loaded (/home/zbyszek/.config/systemd/user/hoohoo.service; static) Active: inactive (dead) start condition failed at Tue 2013-06-25 18:08:42 EDT; 1s ago ConditionPathExists=/tmp/hoo was not met Full information is exported over D-Bus: [(condition, trigger, negate, param, state),...] where state is one of "failed" (<0), "untested" (0), "OK" (>0). I've decided to use 0 for "untested", because it might be useful to differentiate different types of failure later on, without breaking compatibility. systemctl shows the failing condition, if there was a non-trigger failing condition, or says "none of the trigger conditions were met", because there're often many trigger conditions, and they must all fail for the condition to fail, so printing them all would consume a lot of space, and bring unnecessary attention to something that is quite low-level. --- TODO | 2 - src/core/condition.c | 8 ++- src/core/condition.h | 6 +- src/core/dbus-unit.c | 177 ++++++++++++++++++++++++++++++---------------- src/core/dbus-unit.h | 1 + src/core/unit.c | 3 +- src/systemctl/systemctl.c | 62 +++++++++++++--- 7 files changed, 180 insertions(+), 79 deletions(-) diff --git a/TODO b/TODO index 4b75539f0a..753d1ccdb1 100644 --- a/TODO +++ b/TODO @@ -532,8 +532,6 @@ Features: when done. That means clients don't get a successful method reply, but much rather a disconnect on success. -* remember which condition failed for services, not just the fact that something failed - * use opterr = 0 for all getopt tools * properly handle loop back mounts via fstab, especially regards to fsck/passno diff --git a/src/core/condition.c b/src/core/condition.c index 2fbc5ad0e6..6c387450af 100644 --- a/src/core/condition.c +++ b/src/core/condition.c @@ -250,7 +250,7 @@ static bool test_ac_power(const char *parameter) { return (on_ac_power() != 0) == !!r; } -bool condition_test(Condition *c) { +static bool condition_test(Condition *c) { assert(c); switch(c->type) { @@ -358,6 +358,7 @@ bool condition_test_list(const char *unit, Condition *first) { c->parameter, b ? "succeeded" : "failed", unit); + c->state = b ? 1 : -1; if (!c->trigger && !b) return false; @@ -377,12 +378,13 @@ void condition_dump(Condition *c, FILE *f, const char *prefix) { prefix = ""; fprintf(f, - "%s\t%s: %s%s%s\n", + "%s\t%s: %s%s%s %s\n", prefix, condition_type_to_string(c->type), c->trigger ? "|" : "", c->negate ? "!" : "", - c->parameter); + c->parameter, + c->state < 0 ? "failed" : c->state > 0 ? "succeeded" : "untested"); } void condition_dump_list(Condition *first, FILE *f, const char *prefix) { diff --git a/src/core/condition.h b/src/core/condition.h index 2ad77876e4..1813b735a5 100644 --- a/src/core/condition.h +++ b/src/core/condition.h @@ -48,11 +48,14 @@ typedef enum ConditionType { typedef struct Condition { ConditionType type; - char *parameter; bool trigger:1; bool negate:1; + char *parameter; + + int state; + LIST_FIELDS(struct Condition, conditions); } Condition; @@ -60,7 +63,6 @@ Condition* condition_new(ConditionType type, const char *parameter, bool trigger void condition_free(Condition *c); void condition_free_list(Condition *c); -bool condition_test(Condition *c); bool condition_test_list(const char *unit, Condition *c); void condition_dump(Condition *c, FILE *f, const char *prefix); diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index ba4d42652e..4cd3a13fd2 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -311,6 +311,58 @@ static int bus_unit_append_need_daemon_reload(DBusMessageIter *i, const char *pr return 0; } +static int bus_property_append_condition(DBusMessageIter *i, const char *property, void *data) { + Condition **cp = data; + Condition *c; + const char *name, *param; + dbus_bool_t trigger, negate; + dbus_int32_t state; + DBusMessageIter sub; + + assert(i); + assert(property); + assert(cp); + + c = *cp; + assert(c); + + name = condition_type_to_string(c->type); + param = c->parameter; + trigger = c->trigger; + negate = c->negate; + state = c->state; + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &name) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_BOOLEAN, &trigger) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_BOOLEAN, &negate) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, ¶m) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_INT32, &state) || + !dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_property_append_condition_list(DBusMessageIter *i, const char *property, void *data) { + Condition **first = data, *c; + DBusMessageIter sub; + + assert(i); + assert(data); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(sbbsi)", &sub)) + return -ENOMEM; + + LIST_FOREACH(conditions, c, *first) + bus_property_append_condition(&sub, property, &c); + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + static int bus_unit_append_load_error(DBusMessageIter *i, const char *property, void *data) { Unit *u = data; const char *name, *message; @@ -975,68 +1027,69 @@ int bus_unit_set_properties( } const BusProperty bus_unit_properties[] = { - { "Id", bus_property_append_string, "s", offsetof(Unit, id), true }, - { "Names", bus_unit_append_names, "as", 0 }, - { "Following", bus_unit_append_following, "s", 0 }, - { "Requires", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRES]), true }, - { "RequiresOverridable", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRES_OVERRIDABLE]), true }, - { "Requisite", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUISITE]), true }, - { "RequisiteOverridable", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUISITE_OVERRIDABLE]), true }, - { "Wants", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_WANTS]), true }, - { "BindsTo", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_BINDS_TO]), true }, - { "PartOf", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_PART_OF]), true }, - { "RequiredBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRED_BY]), true }, - { "RequiredByOverridable",bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRED_BY_OVERRIDABLE]), true }, - { "WantedBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_WANTED_BY]), true }, - { "BoundBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_BOUND_BY]), true }, - { "ConsistsOf", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_CONSISTS_OF]), true }, - { "Conflicts", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_CONFLICTS]), true }, - { "ConflictedBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_CONFLICTED_BY]), true }, - { "Before", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_BEFORE]), true }, - { "After", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_AFTER]), true }, - { "OnFailure", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_ON_FAILURE]), true }, - { "Triggers", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_TRIGGERS]), true }, - { "TriggeredBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_TRIGGERED_BY]), true }, - { "PropagatesReloadTo", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_PROPAGATES_RELOAD_TO]), true }, - { "ReloadPropagatedFrom", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_RELOAD_PROPAGATED_FROM]), true }, - { "RequiresMountsFor", bus_property_append_strv, "as", offsetof(Unit, requires_mounts_for), true }, - { "Documentation", bus_property_append_strv, "as", offsetof(Unit, documentation), true }, - { "Description", bus_unit_append_description, "s", 0 }, - { "LoadState", bus_unit_append_load_state, "s", offsetof(Unit, load_state) }, - { "ActiveState", bus_unit_append_active_state, "s", 0 }, - { "SubState", bus_unit_append_sub_state, "s", 0 }, - { "FragmentPath", bus_property_append_string, "s", offsetof(Unit, fragment_path), true }, - { "SourcePath", bus_property_append_string, "s", offsetof(Unit, source_path), true }, - { "DropInPaths", bus_property_append_strv, "as", offsetof(Unit, dropin_paths), true }, - { "UnitFileState", bus_unit_append_file_state, "s", 0 }, - { "InactiveExitTimestamp",bus_property_append_usec, "t", offsetof(Unit, inactive_exit_timestamp.realtime) }, - { "InactiveExitTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, inactive_exit_timestamp.monotonic) }, - { "ActiveEnterTimestamp", bus_property_append_usec, "t", offsetof(Unit, active_enter_timestamp.realtime) }, - { "ActiveEnterTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, active_enter_timestamp.monotonic) }, - { "ActiveExitTimestamp", bus_property_append_usec, "t", offsetof(Unit, active_exit_timestamp.realtime) }, - { "ActiveExitTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, active_exit_timestamp.monotonic) }, - { "InactiveEnterTimestamp", bus_property_append_usec, "t", offsetof(Unit, inactive_enter_timestamp.realtime) }, - { "InactiveEnterTimestampMonotonic",bus_property_append_usec, "t", offsetof(Unit, inactive_enter_timestamp.monotonic) }, - { "CanStart", bus_unit_append_can_start, "b", 0 }, - { "CanStop", bus_unit_append_can_stop, "b", 0 }, - { "CanReload", bus_unit_append_can_reload, "b", 0 }, - { "CanIsolate", bus_unit_append_can_isolate, "b", 0 }, - { "Job", bus_unit_append_job, "(uo)", 0 }, - { "StopWhenUnneeded", bus_property_append_bool, "b", offsetof(Unit, stop_when_unneeded) }, - { "RefuseManualStart", bus_property_append_bool, "b", offsetof(Unit, refuse_manual_start) }, - { "RefuseManualStop", bus_property_append_bool, "b", offsetof(Unit, refuse_manual_stop) }, - { "AllowIsolate", bus_property_append_bool, "b", offsetof(Unit, allow_isolate) }, - { "DefaultDependencies", bus_property_append_bool, "b", offsetof(Unit, default_dependencies) }, - { "OnFailureIsolate", bus_property_append_bool, "b", offsetof(Unit, on_failure_isolate) }, - { "IgnoreOnIsolate", bus_property_append_bool, "b", offsetof(Unit, ignore_on_isolate) }, - { "IgnoreOnSnapshot", bus_property_append_bool, "b", offsetof(Unit, ignore_on_snapshot) }, - { "NeedDaemonReload", bus_unit_append_need_daemon_reload, "b", 0 }, - { "JobTimeoutUSec", bus_property_append_usec, "t", offsetof(Unit, job_timeout) }, - { "ConditionTimestamp", bus_property_append_usec, "t", offsetof(Unit, condition_timestamp.realtime) }, - { "ConditionTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, condition_timestamp.monotonic) }, - { "ConditionResult", bus_property_append_bool, "b", offsetof(Unit, condition_result) }, - { "LoadError", bus_unit_append_load_error, "(ss)", 0 }, - { "Transient", bus_property_append_bool, "b", offsetof(Unit, transient) }, + { "Id", bus_property_append_string, "s", offsetof(Unit, id), true }, + { "Names", bus_unit_append_names, "as", 0 }, + { "Following", bus_unit_append_following, "s", 0 }, + { "Requires", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRES]), true }, + { "RequiresOverridable", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRES_OVERRIDABLE]), true }, + { "Requisite", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUISITE]), true }, + { "RequisiteOverridable", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUISITE_OVERRIDABLE]), true }, + { "Wants", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_WANTS]), true }, + { "BindsTo", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_BINDS_TO]), true }, + { "PartOf", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_PART_OF]), true }, + { "RequiredBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRED_BY]), true }, + { "RequiredByOverridable", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRED_BY_OVERRIDABLE]), true }, + { "WantedBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_WANTED_BY]), true }, + { "BoundBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_BOUND_BY]), true }, + { "ConsistsOf", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_CONSISTS_OF]), true }, + { "Conflicts", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_CONFLICTS]), true }, + { "ConflictedBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_CONFLICTED_BY]), true }, + { "Before", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_BEFORE]), true }, + { "After", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_AFTER]), true }, + { "OnFailure", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_ON_FAILURE]), true }, + { "Triggers", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_TRIGGERS]), true }, + { "TriggeredBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_TRIGGERED_BY]), true }, + { "PropagatesReloadTo", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_PROPAGATES_RELOAD_TO]), true }, + { "ReloadPropagatedFrom", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_RELOAD_PROPAGATED_FROM]), true }, + { "RequiresMountsFor", bus_property_append_strv, "as", offsetof(Unit, requires_mounts_for), true }, + { "Documentation", bus_property_append_strv, "as", offsetof(Unit, documentation), true }, + { "Description", bus_unit_append_description, "s", 0 }, + { "LoadState", bus_unit_append_load_state, "s", offsetof(Unit, load_state) }, + { "ActiveState", bus_unit_append_active_state, "s", 0 }, + { "SubState", bus_unit_append_sub_state, "s", 0 }, + { "FragmentPath", bus_property_append_string, "s", offsetof(Unit, fragment_path), true }, + { "SourcePath", bus_property_append_string, "s", offsetof(Unit, source_path), true }, + { "DropInPaths", bus_property_append_strv, "as", offsetof(Unit, dropin_paths), true }, + { "UnitFileState", bus_unit_append_file_state, "s", 0 }, + { "InactiveExitTimestamp", bus_property_append_usec, "t", offsetof(Unit, inactive_exit_timestamp.realtime) }, + { "InactiveExitTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, inactive_exit_timestamp.monotonic) }, + { "ActiveEnterTimestamp", bus_property_append_usec, "t", offsetof(Unit, active_enter_timestamp.realtime) }, + { "ActiveEnterTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, active_enter_timestamp.monotonic) }, + { "ActiveExitTimestamp", bus_property_append_usec, "t", offsetof(Unit, active_exit_timestamp.realtime) }, + { "ActiveExitTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, active_exit_timestamp.monotonic) }, + { "InactiveEnterTimestamp", bus_property_append_usec, "t", offsetof(Unit, inactive_enter_timestamp.realtime) }, + { "InactiveEnterTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, inactive_enter_timestamp.monotonic) }, + { "CanStart", bus_unit_append_can_start, "b", 0 }, + { "CanStop", bus_unit_append_can_stop, "b", 0 }, + { "CanReload", bus_unit_append_can_reload, "b", 0 }, + { "CanIsolate", bus_unit_append_can_isolate, "b", 0 }, + { "Job", bus_unit_append_job, "(uo)", 0 }, + { "StopWhenUnneeded", bus_property_append_bool, "b", offsetof(Unit, stop_when_unneeded) }, + { "RefuseManualStart", bus_property_append_bool, "b", offsetof(Unit, refuse_manual_start) }, + { "RefuseManualStop", bus_property_append_bool, "b", offsetof(Unit, refuse_manual_stop) }, + { "AllowIsolate", bus_property_append_bool, "b", offsetof(Unit, allow_isolate) }, + { "DefaultDependencies", bus_property_append_bool, "b", offsetof(Unit, default_dependencies) }, + { "OnFailureIsolate", bus_property_append_bool, "b", offsetof(Unit, on_failure_isolate) }, + { "IgnoreOnIsolate", bus_property_append_bool, "b", offsetof(Unit, ignore_on_isolate) }, + { "IgnoreOnSnapshot", bus_property_append_bool, "b", offsetof(Unit, ignore_on_snapshot) }, + { "NeedDaemonReload", bus_unit_append_need_daemon_reload, "b", 0 }, + { "JobTimeoutUSec", bus_property_append_usec, "t", offsetof(Unit, job_timeout) }, + { "ConditionTimestamp", bus_property_append_usec, "t", offsetof(Unit, condition_timestamp.realtime) }, + { "ConditionTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, condition_timestamp.monotonic) }, + { "ConditionResult", bus_property_append_bool, "b", offsetof(Unit, condition_result) }, + { "Conditions", bus_property_append_condition_list, "a(sbbsi)", offsetof(Unit, conditions) }, + { "LoadError", bus_unit_append_load_error, "(ss)", 0 }, + { "Transient", bus_property_append_bool, "b", offsetof(Unit, transient) }, {} }; diff --git a/src/core/dbus-unit.h b/src/core/dbus-unit.h index d3f7ec621e..3064cd552a 100644 --- a/src/core/dbus-unit.h +++ b/src/core/dbus-unit.h @@ -125,6 +125,7 @@ " \n" \ " \n" \ " \n" \ + " \n" \ " \n" \ " \n" \ " \n" diff --git a/src/core/unit.c b/src/core/unit.c index a201fa4041..0e9329f8c9 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -1125,7 +1125,8 @@ int unit_start(Unit *u) { } /* Forward to the main object, if we aren't it. */ - if ((following = unit_following(u))) { + following = unit_following(u); + if (following) { log_debug_unit(u->id, "Redirecting start request from %s to %s.", u->id, following->id); return unit_start(following); diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 6fdbc417b6..b3b679e0af 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -2534,6 +2534,10 @@ typedef struct UnitStatusInfo { usec_t condition_timestamp; bool condition_result; + bool failed_condition_trigger; + bool failed_condition_negate; + const char *failed_condition; + const char *failed_condition_param; /* Socket */ unsigned n_accepted; @@ -2676,10 +2680,15 @@ static void print_status_info(UnitStatusInfo *i) { s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp); s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp); - if (s1) - printf(" start condition failed at %s; %s\n", s2, s1); - else if (s2) - printf(" start condition failed at %s\n", s2); + printf(" start condition failed at %s%s%s\n", + s2, s1 ? "; " : "", s1 ? s1 : ""); + if (i->failed_condition_trigger) + printf(" none of the trigger conditions were met\n"); + else if (i->failed_condition) + printf(" %s=%s%s was not met\n", + i->failed_condition, + i->failed_condition_negate ? "!" : "", + i->failed_condition_param); } if (i->sysfs_path) @@ -3038,15 +3047,18 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn ExecStatusInfo *info; int r; - if (!(info = new0(ExecStatusInfo, 1))) + info = new0(ExecStatusInfo, 1); + if (!info) return -ENOMEM; - if (!(info->name = strdup(name))) { + info->name = strdup(name); + if (!info->name) { free(info); return -ENOMEM; } - if ((r = exec_status_info_deserialize(&sub, info)) < 0) { + r = exec_status_info_deserialize(&sub, info); + if (r < 0) { free(info); return r; } @@ -3056,7 +3068,8 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn dbus_message_iter_next(&sub); } - } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Listen")) { + } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && + streq(name, "Listen")) { DBusMessageIter sub, sub2; dbus_message_iter_recurse(iter, &sub); @@ -3082,7 +3095,8 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn return 0; - } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRING && streq(name, "DropInPaths")) { + } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRING && + streq(name, "DropInPaths")) { int r = bus_parse_strv_iter(iter, &i->dropin_paths); if (r < 0) return r; @@ -3105,6 +3119,36 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn dbus_message_iter_next(&sub); } + + } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && + streq(name, "Conditions")) { + DBusMessageIter sub, sub2; + + dbus_message_iter_recurse(iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { + const char *cond, *param; + dbus_bool_t trigger, negate; + dbus_int32_t state; + + dbus_message_iter_recurse(&sub, &sub2); + log_debug("here"); + + if(bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &cond, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_BOOLEAN, &trigger, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_BOOLEAN, &negate, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, ¶m, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_INT32, &state, false) >= 0) { + log_debug("%s %d %d %s %d", cond, trigger, negate, param, state); + if (state < 0 && (!trigger || !i->failed_condition)) { + i->failed_condition = cond; + i->failed_condition_trigger = trigger; + i->failed_condition_negate = negate; + i->failed_condition_param = param; + } + } + + dbus_message_iter_next(&sub); + } } break; -- cgit v1.2.1 From 059b7a9aad6c2e60957761b8f63267861c859be8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 18 Jul 2013 00:03:09 -0400 Subject: systemd-python: also update the documentation sphinx, oh sphinx, why do you require manual ficksups all the time? --- src/python-systemd/docs/journal.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/python-systemd/docs/journal.rst b/src/python-systemd/docs/journal.rst index e6c42061f3..ea74cf85c4 100644 --- a/src/python-systemd/docs/journal.rst +++ b/src/python-systemd/docs/journal.rst @@ -53,7 +53,8 @@ Journal access types .. autoattribute:: systemd.journal.LOCAL_ONLY .. autoattribute:: systemd.journal.RUNTIME_ONLY -.. autoattribute:: systemd.journal.SYSTEM_ONLY +.. autoattribute:: systemd.journal.SYSTEM +.. autoattribute:: systemd.journal.CURRENT_USER Journal event types ~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.1 From c2654883624885696edccd2a202873998ec208f1 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 17 Jul 2013 16:29:55 +0200 Subject: test: Keep the test-suite.log around in case of a test failure The addition of .DELETE_ON_ERROR will lead to the removal of the test-suite.log in case of a test failure. Mark the rule as PRECIOUS to keep that file around. --- Makefile.am | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile.am b/Makefile.am index 7e6361c2e8..c4b9b1ad2f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -31,6 +31,9 @@ SUBDIRS = . po # keep intermediate files .SECONDARY: +# Keep the test-suite.log +.PRECIOUS: $(TEST_SUITE_LOG) + LIBUDEV_CURRENT=4 LIBUDEV_REVISION=6 LIBUDEV_AGE=3 -- cgit v1.2.1 From a54e3b3d6a4fe28a39729f4c5ad11cd26706110c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 18 Jul 2013 08:07:01 -0400 Subject: journalctl: fix signedness warning and boot-id syntax check --- src/journal/journalctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 9a40d69a75..2f043a48d5 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -744,7 +744,7 @@ static int get_relative_boot_id(sd_journal *j, sd_id128_t *boot_id, int relative if (!id || relative <= 0 ? (id - all_ids) + relative < 0 : - (id - all_ids) + relative >= count) + (id - all_ids) + relative >= (int) count) return -EADDRNOTAVAIL; *boot_id = (id + relative)->id; @@ -781,7 +781,7 @@ static int add_boot(sd_journal *j) { offset = arg_boot_descriptor + 32; - if (*offset != '-' && *offset != '+') { + if (*offset && *offset != '-' && *offset != '+') { log_error("Relative boot ID offset must start with a '+' or a '-', found '%s' ", offset); return -EINVAL; } -- cgit v1.2.1 From 884c86812c51479496edd50b278383d7bb67baf0 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 18 Jul 2013 14:40:42 +0200 Subject: rules: keyboard - use builtin command --- rules/60-keyboard.rules | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rules/60-keyboard.rules b/rules/60-keyboard.rules index b925853c3e..4e0f3663f6 100644 --- a/rules/60-keyboard.rules +++ b/rules/60-keyboard.rules @@ -9,14 +9,14 @@ SUBSYSTEMS=="bluetooth", GOTO="keyboard_end" # import key mapping for USB device SUBSYSTEMS=="usb", IMPORT{builtin}="hwdb --subsystem=usb --lookup-prefix=keyboard:", \ - RUN{program}+="keyboard", GOTO="keyboard_end" + RUN{builtin}+="keyboard", GOTO="keyboard_end" # import key mapping for AT keyboard from DMI data DRIVERS=="atkbd", IMPORT{builtin}="hwdb 'keyboard:$attr{[dmi/id]modalias}'", \ - RUN{program}+="keyboard", GOTO="keyboard_end" + RUN{builtin}+="keyboard", GOTO="keyboard_end" # import key mapping for platform input device KERNELS=="input*", IMPORT{builtin}="hwdb 'keyboard:name:$attr{name}:$attr{[dmi/id]modalias}'", \ - RUN{program}+="keyboard", GOTO="keyboard_end" + RUN{builtin}+="keyboard", GOTO="keyboard_end" LABEL="keyboard_end" -- cgit v1.2.1 From 44bc6e1fe0171af19451b5586f7fdd08853ccf5b Mon Sep 17 00:00:00 2001 From: Tomasz Torcz Date: Thu, 18 Jul 2013 10:21:45 +0200 Subject: =?UTF-8?q?journalctl:=20add=20=E2=80=9Dshort-iso=E2=80=9D=20outpu?= =?UTF-8?q?t=20format=20with=20verbose=20ISO8601=20timestamps?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Example: 2013-07-18T10:10:01+0200 sandworm CROND[20957]: (root) CMD (/usr/lib64/sa/sa1 1 1) --- man/journalctl.xml | 12 ++++++++++++ src/journal/journalctl.c | 2 +- src/shared/logs-show.c | 11 +++++++++-- src/shared/output-mode.h | 1 + 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/man/journalctl.xml b/man/journalctl.xml index 65a59ea4e7..da43bf2879 100644 --- a/man/journalctl.xml +++ b/man/journalctl.xml @@ -264,6 +264,18 @@ + + + + + + is very similar + but shows ISO 8601 + wallclock timestamps. + + + + diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 2f043a48d5..083a597116 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -133,7 +133,7 @@ static int help(void) { " -n --lines[=INTEGER] Number of journal entries to show\n" " --no-tail Show all lines, even in follow mode\n" " -r --reverse Show the newest entries first\n" - " -o --output=STRING Change journal output mode (short, short-monotonic,\n" + " -o --output=STRING Change journal output mode (short, short-monotonic, short-iso\n" " verbose, export, json, json-pretty, json-sse, cat)\n" " -x --catalog Add message explanations where available\n" " -l --full Do not ellipsize fields\n" diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index ea4746879b..bd7363aa82 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -273,9 +273,14 @@ static int output_short( } t = (time_t) (x / USEC_PER_SEC); - if (strftime(buf, sizeof(buf), "%b %d %H:%M:%S", localtime_r(&t, &tm)) <= 0) { + if (mode == OUTPUT_SHORT_ISO) + r = strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S%z", localtime_r(&t, &tm)); + else + r = strftime(buf, sizeof(buf), "%b %d %H:%M:%S", localtime_r(&t, &tm)); + + if (r <= 0) { log_error("Failed to format time."); - return r; + return -EINVAL; } fputs(buf, f); @@ -798,6 +803,7 @@ static int (*output_funcs[_OUTPUT_MODE_MAX])( [OUTPUT_SHORT] = output_short, [OUTPUT_SHORT_MONOTONIC] = output_short, + [OUTPUT_SHORT_ISO] = output_short, [OUTPUT_VERBOSE] = output_verbose, [OUTPUT_EXPORT] = output_export, [OUTPUT_JSON] = output_json, @@ -1076,6 +1082,7 @@ int show_journal_by_unit( static const char *const output_mode_table[_OUTPUT_MODE_MAX] = { [OUTPUT_SHORT] = "short", [OUTPUT_SHORT_MONOTONIC] = "short-monotonic", + [OUTPUT_SHORT_ISO] = "short-iso", [OUTPUT_VERBOSE] = "verbose", [OUTPUT_EXPORT] = "export", [OUTPUT_JSON] = "json", diff --git a/src/shared/output-mode.h b/src/shared/output-mode.h index 0efd430c5d..4012889b65 100644 --- a/src/shared/output-mode.h +++ b/src/shared/output-mode.h @@ -24,6 +24,7 @@ typedef enum OutputMode { OUTPUT_SHORT, OUTPUT_SHORT_MONOTONIC, + OUTPUT_SHORT_ISO, OUTPUT_VERBOSE, OUTPUT_EXPORT, OUTPUT_JSON, -- cgit v1.2.1 From 9b9b3d36b8ffe5b41c1455bffd44a9d11efc8aee Mon Sep 17 00:00:00 2001 From: Maciej Wereski Date: Thu, 18 Jul 2013 13:24:12 +0200 Subject: systemctl: option to list units by state This allows to show only units with specified LOAD or SUB or ACTIVE state. --- man/systemctl.xml | 29 +++++++++++-------------- src/systemctl/systemctl.c | 54 +++++++++++++++++++++++++++++++---------------- 2 files changed, 48 insertions(+), 35 deletions(-) diff --git a/man/systemctl.xml b/man/systemctl.xml index f5502153ad..982051778e 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -94,25 +94,29 @@ along with systemd; If not, see . The argument should be a comma-separated list of unit types such as and - , or unit load states such as - and - (types and states can be mixed). + . + If one of the arguments is a unit type, when listing units, limit display to certain unit types. Otherwise, units of all types will be shown. - If one of the arguments is a unit load state, when - listing units, limit display to certain unit - types. Otherwise, units of in all load states will be - shown. - As a special case, if one of the arguments is , a list of allowed values will be printed and the program will exit. + + + + + Argument should be a comma-separated list of unit LOAD + or SUB or ACTIVE states. When listing units show only those + with specified LOAD or SUB or ACTIVE state. + + + @@ -165,15 +169,6 @@ along with systemd; If not, see . - - - - - When listing units, show only failed units. Do not - confuse with . - - - diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index b3b679e0af..c9f9981f9c 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -69,7 +69,7 @@ #include "fileio.h" static char **arg_types = NULL; -static char **arg_load_states = NULL; +static char **arg_states = NULL; static char **arg_properties = NULL; static bool arg_all = false; static enum dependency { @@ -93,7 +93,6 @@ static bool arg_quiet = false; static bool arg_full = false; static int arg_force = 0; static bool arg_ask_password = true; -static bool arg_failed = false; static bool arg_runtime = false; static char **arg_wall = NULL; static const char *arg_kill_who = NULL; @@ -301,12 +300,11 @@ static int compare_unit_info(const void *a, const void *b) { static bool output_show_unit(const struct unit_info *u) { const char *dot; - if (arg_failed) - return streq(u->active_state, "failed"); + if (!strv_isempty(arg_states)) + return strv_contains(arg_states, u->load_state) || strv_contains(arg_states, u->sub_state) || strv_contains(arg_states, u->active_state); return (!arg_types || ((dot = strrchr(u->id, '.')) && strv_find(arg_types, dot+1))) && - (!arg_load_states || strv_find(arg_load_states, u->load_state)) && (arg_all || !(streq(u->active_state, "inactive") || u->following[0]) || u->job_id > 0); } @@ -4705,12 +4703,12 @@ static int systemctl_help(void) { " -h --help Show this help\n" " --version Show package version\n" " -t --type=TYPE List only units of a particular type\n" + " --state=STATE Show only units with particular LOAD or SUB or ACTIVE state\n" " -p --property=NAME Show only properties by this name\n" " -a --all Show all loaded units/properties, including dead/empty\n" " ones. To list all units installed on the system, use\n" " the 'list-unit-files' command instead.\n" " --reverse Show reverse dependencies with 'list-dependencies'\n" - " --failed Show only failed units\n" " -l --full Don't ellipsize unit names on output\n" " --fail When queueing a new job, fail if conflicting jobs are\n" " pending\n" @@ -4896,13 +4894,6 @@ static int help_types(void) { puts(t); } - puts("\nAvailable unit load states: "); - for(i = 0; i < _UNIT_LOAD_STATE_MAX; i++) { - t = unit_load_state_to_string(i); - if (t) - puts(t); - } - return 0; } @@ -4931,7 +4922,8 @@ static int systemctl_parse_argv(int argc, char *argv[]) { ARG_FAILED, ARG_RUNTIME, ARG_FORCE, - ARG_PLAIN + ARG_PLAIN, + ARG_STATE }; static const struct option options[] = { @@ -4970,6 +4962,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { { "lines", required_argument, NULL, 'n' }, { "output", required_argument, NULL, 'o' }, { "plain", no_argument, NULL, ARG_PLAIN }, + { "state", required_argument, NULL, ARG_STATE }, { NULL, 0, NULL, 0 } }; @@ -5014,8 +5007,12 @@ static int systemctl_parse_argv(int argc, char *argv[]) { continue; } + /* It's much nicer to use --state= for + * load states, but let's support this + * in --types= too for compatibility + * with old versions */ if (unit_load_state_from_string(optarg) >= 0) { - if (strv_push(&arg_load_states, type)) + if (strv_push(&arg_states, type) < 0) return log_oom(); type = NULL; continue; @@ -5047,7 +5044,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { if (!prop) return log_oom(); - if (strv_push(&arg_properties, prop)) { + if (strv_push(&arg_properties, prop) < 0) { free(prop); return log_oom(); } @@ -5131,7 +5128,9 @@ static int systemctl_parse_argv(int argc, char *argv[]) { break; case ARG_FAILED: - arg_failed = true; + if (strv_extend(&arg_states, "failed") < 0) + return log_oom(); + break; case 'q': @@ -5201,6 +5200,25 @@ static int systemctl_parse_argv(int argc, char *argv[]) { arg_plain = true; break; + case ARG_STATE: { + char *word, *state; + size_t size; + + FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) { + char *s; + + s = strndup(word, size); + if (!s) + return log_oom(); + + if (strv_push(&arg_states, s) < 0) { + free(s); + return log_oom(); + } + } + break; + } + case '?': return -EINVAL; @@ -6257,7 +6275,7 @@ finish: dbus_shutdown(); strv_free(arg_types); - strv_free(arg_load_states); + strv_free(arg_states); strv_free(arg_properties); pager_close(); -- cgit v1.2.1 From 2f5df74a5ec135ab2baebf26af6f088e5b4b8205 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Thu, 18 Jul 2013 14:45:12 +0200 Subject: journal: Leave server_dispatch_message early when Storage is none When using Storage=none there is no point in collecting all the information just to throw them away. After this change journald consumes a lot less CPU time when only forwarding messages. --- src/journal/journald-server.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 332ba41363..81de959666 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -845,6 +845,11 @@ void server_dispatch_message( if (LOG_PRI(priority) > s->max_level_store) return; + /* Stop early in case the information will not be stored + * in a journal. */ + if (s->storage == STORAGE_NONE) + return; + if (!ucred) goto finish; -- cgit v1.2.1 From d4ac85c6f6d8547f8b835009ae431438de72df28 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 18 Jul 2013 20:22:29 +0200 Subject: util: add split_pair() for splitting foo=bar strings --- src/shared/util.c | 31 +++++++++++++++++++++++++++++++ src/shared/util.h | 2 ++ src/test/test-util.c | 23 +++++++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/src/shared/util.c b/src/shared/util.c index 5b602ea46d..c8ed53c8b6 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -5946,3 +5946,34 @@ void parse_user_at_host(char *arg, char **user, char **host) { *user = arg; } } + +int split_pair(const char *s, const char *sep, char **l, char **r) { + char *x, *a, *b; + + assert(s); + assert(sep); + assert(l); + assert(r); + + if (isempty(sep)) + return -EINVAL; + + x = strstr(s, sep); + if (!x) + return -EINVAL; + + a = strndup(s, x - s); + if (!a) + return -ENOMEM; + + b = strdup(x + strlen(sep)); + if (!b) { + free(a); + return -ENOMEM; + } + + *l = a; + *r = b; + + return 0; +} diff --git a/src/shared/util.h b/src/shared/util.h index fac08ca43c..ac999c624c 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -735,3 +735,5 @@ static inline void _reset_locale_(struct _locale_struct_ *s) { bool id128_is_valid(const char *s) _pure_; void parse_user_at_host(char *arg, char **user, char **host); + +int split_pair(const char *s, const char *sep, char **l, char **r); diff --git a/src/test/test-util.c b/src/test/test-util.c index 4768310fbe..315bc419c2 100644 --- a/src/test/test-util.c +++ b/src/test/test-util.c @@ -521,6 +521,28 @@ static void test_parse_user_at_host(void) { assert_se(streq(host, "mikescomputer")); } +static void test_split_pair(void) { + _cleanup_free_ char *a = NULL, *b = NULL; + + assert_se(split_pair("", "", &a, &b) == -EINVAL); + assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL); + assert_se(split_pair("", "=", &a, &b) == -EINVAL); + assert_se(split_pair("foo=bar", "=", &a, &b) >= 0); + assert_se(streq(a, "foo")); + assert_se(streq(b, "bar")); + free(a); + free(b); + assert_se(split_pair("==", "==", &a, &b) >= 0); + assert_se(streq(a, "")); + assert_se(streq(b, "")); + free(a); + free(b); + + assert_se(split_pair("===", "==", &a, &b) >= 0); + assert_se(streq(a, "")); + assert_se(streq(b, "=")); +} + int main(int argc, char *argv[]) { test_streq_ptr(); test_first_word(); @@ -555,6 +577,7 @@ int main(int argc, char *argv[]) { test_strextend(); test_strrep(); test_parse_user_at_host(); + test_split_pair(); return 0; } -- cgit v1.2.1 From f04ca8c214e02e58877e994e5d1fa29a6abe5157 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 18 Jul 2013 23:05:29 +0200 Subject: tests: skip tests when executed without privileges but which require them --- src/test/test-sched-prio.c | 2 +- src/test/test-unit-name.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/test-sched-prio.c b/src/test/test-sched-prio.c index 509c75f42d..1bbe867317 100644 --- a/src/test/test-sched-prio.c +++ b/src/test/test-sched-prio.c @@ -35,7 +35,7 @@ int main(int argc, char *argv[]) { /* prepare the test */ assert_se(set_unit_path(TEST_DIR) >= 0); r = manager_new(SYSTEMD_USER, false, &m); - if (r == -EPERM) { + if (r == -EPERM || r == -EACCES) { puts("manager_new: Permission denied. Skipping test."); return EXIT_TEST_SKIP; } diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c index 2fa0294882..6776ef0857 100644 --- a/src/test/test-unit-name.c +++ b/src/test/test-unit-name.c @@ -124,7 +124,7 @@ static int test_unit_printf(void) { assert_se(asprintf(&root_uid, "%d", (int) root->pw_uid) > 0); r = manager_new(SYSTEMD_USER, false, &m); - if (r == -EPERM) { + if (r == -EPERM || r == -EACCES) { puts("manager_new: Permission denied. Skipping test."); return EXIT_TEST_SKIP; } -- cgit v1.2.1 From 466784c8710e5cb0e0b86a16506d992d7ec5b619 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 18 Jul 2013 23:07:37 +0200 Subject: TODO: update --- TODO | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/TODO b/TODO index 753d1ccdb1..5ac8d81640 100644 --- a/TODO +++ b/TODO @@ -19,7 +19,7 @@ Bugfixes: $ cat /proc/252/environ initrd=\6a9857a393724b7a981ebb5b8495b9ea\3.10.0-2.fc20.x86_64\initrd -Fedora 19: +Fedora 20: * external: maybe it is time to patch procps so that "ps" links to libsystemd-logind to print a pretty service name, seat name, session @@ -33,6 +33,7 @@ Fedora 19: - localectl: support new converted x11→console keymaps * when installing fedora with yum --installroot /var/run is a directory, not a symlink + https://bugzilla.redhat.com/show_bug.cgi?id=975864 CGroup Rework Completion: @@ -80,9 +81,6 @@ Features: * systemctl list-unit-files should list generated files (and probably with a new state "generated" for them, or so) -* Get rid of systemd-sysv: - https://fedoraproject.org/wiki/User:Toshio/Systemd_Convert_draft - * do we really need both hasprefix() and startswith()? * when a kernel driver logs in a tight loop we should ratelimit that too. @@ -119,6 +117,8 @@ Features: * gparted needs to disable auto-activation of mount units somehow, or maybe we should stop doing auto-activation of this after boot entirely. https://bugzilla.gnome.org/show_bug.cgi?id=701676 + Maybe take a BSD lock at the disk device node and teach udev to + check for that and suppress event handling. * when a service changes state make reflect that in the RUNNING/LISTENING states of its socket @@ -205,8 +205,6 @@ Features: - make stuff in test/ work with separate output dir - remove all the duplicated code in test/ -* suppress log output on shutdown when "quiet" is used - * systemctl delete x.snapshot leaves no trace in logs (at least at default level). * make the coredump collector tool move itself into the user's cgroup @@ -223,10 +221,6 @@ Features: * when isolating, try to figure out a way how we implicitly can order all units we stop before the isolating unit... -* teach udev + logind's uaccess to somehow handle the "dead" device nodes from: - /lib/modules/$(uname -r)/modules.devname - and apply ACLs to them if they have TAG=="uaccess" in udev rules. - * add ConditionArchitecture= or so * teach ConditionKernelCommandLine= globs or regexes (in order to match foobar={no,0,off}) @@ -305,7 +299,7 @@ Features: - write man page for efi boot generator - honor language efi variables for default language selection (if there are any?) - honor timezone efi variables for default timezone selection (if there are any?) - - introduce bootctl (backed by systemd-bootd) to control temporary and persistent default boot goal plus efi variables + - change bootctl to be backed by systemd-bootd to control temporary and persistent default boot goal plus efi variables * maybe do not install getty@tty1.service symlink in /etc but in /usr? @@ -422,10 +416,6 @@ Features: mode, it will never touch the RTC if the no reliable time source is active or the user did not request anything like it. -* hwdb: - - implement conditional properties (dmi matches) - - hwdb --filter=ID_DRIVE_* - * if booted in "quiet" mode, and an error happens, turn on status output again, so that the emergency mode isn't totally surprising. Also, terminate plymouth. -- cgit v1.2.1 From 98653cfb5005d0f505c48287d233d270ae6e75d6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 19 Jul 2013 02:46:27 +0200 Subject: man: add reference to new machined bus API documentation in the wiki --- man/systemd-machined.service.xml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/man/systemd-machined.service.xml b/man/systemd-machined.service.xml index a9205d018e..525944b1bc 100644 --- a/man/systemd-machined.service.xml +++ b/man/systemd-machined.service.xml @@ -61,8 +61,16 @@ and containers, and processes belonging to them. - See systemd-nspawn1 for some examples how to - start a container the systemd way. + See + systemd-nspawn1 + for some examples how to start a container the systemd + way. + + See the + machined D-Bus API Documentation for information about + the APIs systemd-machined + provides. -- cgit v1.2.1 From 5d48cd27270e74f878f6ed3fe119e4cf3ef7f84e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 19 Jul 2013 02:47:05 +0200 Subject: machined: correct how some properties are exported on the bus --- src/login/logind-session-dbus.c | 1 - src/machine/machine-dbus.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c index 7aba3477aa..62b9ffd52a 100644 --- a/src/login/logind-session-dbus.c +++ b/src/login/logind-session-dbus.c @@ -62,7 +62,6 @@ " \n" \ " \n" \ " \n" \ - " \n" \ " \n" \ " \n" \ " \n" \ diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c index 243b8604cd..6e1b8f8186 100644 --- a/src/machine/machine-dbus.c +++ b/src/machine/machine-dbus.c @@ -130,6 +130,7 @@ static const BusProperty bus_machine_machine_properties[] = { { "TimestampMonotonic", bus_property_append_usec, "t", offsetof(Machine, timestamp.monotonic) }, { "Service", bus_property_append_string, "s", offsetof(Machine, service), true }, { "Scope", bus_property_append_string, "s", offsetof(Machine, scope), true }, + { "Leader", bus_property_append_pid, "u", offsetof(Machine, leader) }, { "Class", bus_machine_append_class, "s", offsetof(Machine, class) }, { "State", bus_machine_append_state, "s", 0 }, { "RootDirectory", bus_property_append_string, "s", offsetof(Machine, root_directory), true }, -- cgit v1.2.1 From e1b7e7ec9b34ae6ae54a4c8084395cbf2bfe9960 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 19 Jul 2013 03:48:23 +0200 Subject: update TODO --- TODO | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index 5ac8d81640..a8a97bb5af 100644 --- a/TODO +++ b/TODO @@ -57,13 +57,16 @@ CGroup Rework Completion: Features: +* given that logind/machined now let PID 1 do all nasty work we can + probably reduce the capability set they retain substantially. + * btfs raid assembly: some .device jobs stay stuck in the queue * Fedora: add an rpmlint check that verifies that all unit files in the RPM are listed in %systemd_post macros. * Fedora: post FPC ticket to move add %tmpfiles_create to the packaging guidelines -* add rpm macros for applying tmpfiles --create after package installation +* make sure gdm doesn't use multi-user-x but the new default X configuration file, and then remove multi-user-x from systemd * when parsing calendar timestamps support the UTC timezone (even if we won't support arbitrary timezone specs, support UTC itself certainly makes sense), also support syntaxes such as +0200 @@ -83,8 +86,6 @@ Features: * do we really need both hasprefix() and startswith()? -* when a kernel driver logs in a tight loop we should ratelimit that too. - * journald: when we drop syslog messages because the syslog socket is full, make sure to write how many messages are lost as first thing to syslog when it works again. -- cgit v1.2.1 From 085b90af43fefd9ed195902c4b55f1da3c568554 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 19 Jul 2013 03:49:07 +0200 Subject: units: add references to bus API documentation to logind+machined --- units/systemd-logind.service.in | 1 + units/systemd-machined.service.in | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/units/systemd-logind.service.in b/units/systemd-logind.service.in index c4611e8492..6b687171ca 100644 --- a/units/systemd-logind.service.in +++ b/units/systemd-logind.service.in @@ -8,6 +8,7 @@ [Unit] Description=Login Service Documentation=man:systemd-logind.service(8) man:logind.conf(5) +Documentation=http://www.freedesktop.org/wiki/Software/systemd/logind Documentation=http://www.freedesktop.org/wiki/Software/systemd/multiseat Wants=user.slice After=nss-user-lookup.target user.slice diff --git a/units/systemd-machined.service.in b/units/systemd-machined.service.in index 334c622a17..87a81b9c85 100644 --- a/units/systemd-machined.service.in +++ b/units/systemd-machined.service.in @@ -8,7 +8,7 @@ [Unit] Description=Virtual Machine and Container Registration Service Documentation=man:systemd-machined.service(8) -Documentation=http://www.freedesktop.org/wiki/Software/systemd/machines +Documentation=http://www.freedesktop.org/wiki/Software/systemd/machined Wants=machine.slice After=machine.slice -- cgit v1.2.1 From bc5cb1d525461c75e69ce1f82a52e223309cca7c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 19 Jul 2013 03:49:24 +0200 Subject: machined: run machined at minimal capabilities --- units/systemd-machined.service.in | 1 + 1 file changed, 1 insertion(+) diff --git a/units/systemd-machined.service.in b/units/systemd-machined.service.in index 87a81b9c85..26bfe03537 100644 --- a/units/systemd-machined.service.in +++ b/units/systemd-machined.service.in @@ -17,3 +17,4 @@ ExecStart=@rootlibexecdir@/systemd-machined Restart=always RestartSec=0 BusName=org.freedesktop.machine1 +CapabilityBoundingSet=CAP_KILL -- cgit v1.2.1 From 61ad59b1314060958c6e1b1b480074e230b6ed3e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 19 Jul 2013 04:10:06 +0200 Subject: man: document Slice= setting (and other fixes) --- TODO | 2 +- man/systemd.cgroup.xml | 82 ++++++++++++++++++++++++++++++++++++------------- man/systemd.special.xml | 28 +++++++++-------- 3 files changed, 77 insertions(+), 35 deletions(-) diff --git a/TODO b/TODO index a8a97bb5af..5de106e122 100644 --- a/TODO +++ b/TODO @@ -51,7 +51,7 @@ CGroup Rework Completion: * introduce high-level settings for RT budget, swappiness -* man: document new bus apis +* wiki: document new bus APIs of PID 1 * Send SIGHUP and SIGTERM in session scopes diff --git a/man/systemd.cgroup.xml b/man/systemd.cgroup.xml index bb0cb1c2e3..b93b52ff6d 100644 --- a/man/systemd.cgroup.xml +++ b/man/systemd.cgroup.xml @@ -90,34 +90,19 @@ along with systemd; If not, see . for cgroup configuration: - - CPUAccounting= - - - Turn on CPU usage accounting for this - unit. - - - BlockIOAccounting= - - - Turn on Block IO bandwidth accounting - for this unit. - - - - - MemoryAccounting= + CPUAccounting= - Turn on process and kernel memory - accounting for this unit. + Turn on CPU usage accounting for this unit. Takes a + boolean argument. Note that turning on CPU accounting for + one unit might also implicitly turn it on for all units + contained in the same slice and for all its parent slices and + the units contained therein. - CPUShares=weight @@ -133,6 +118,18 @@ along with systemd; If not, see . + + MemoryAccounting= + + + Turn on process and kernel memory accounting for this + unit. Takes a boolean argument. Note that turning on memory + accounting for one unit might also implicitly turn it on for + all units contained in the same slice and for all its parent + slices and the units contained therein. + + + MemoryLimit=bytes MemorySoftLimit=bytes @@ -158,6 +155,18 @@ along with systemd; If not, see . + + BlockIOAccounting= + + + Turn on Block IO accounting for this unit. Takes a + boolean argument. Note that turning on block IO accounting + for one unit might also implicitly turn it on for all units + contained in the same slice and all for its parent slices and + the units contained therein. + + + BlockIOWeight=weight @@ -172,7 +181,11 @@ along with systemd; If not, see . defaults to 1000. For details about this control group attribute, see blkio-controller.txt. + url="https://www.kernel.org/doc/Documentation/cgroups/blkio-controller.txt">blkio-controller.txt. + + Implies + BlockIOAccounting=true. + @@ -192,6 +205,9 @@ along with systemd; If not, see . times to set weights for multiple devices. For details about this control group attribute, see blkio-controller.txt. + + Implies + BlockIOAccounting=true. @@ -217,6 +233,9 @@ along with systemd; If not, see . group attributes, see blkio-controller.txt. + + Implies + BlockIOAccounting=true. @@ -283,6 +302,24 @@ along with systemd; If not, see . + + + Slice= + + + The name of the slice unit to place the unit + in. Defaults to system.slice for all + unit types, except for slice units themselves. This may be + used to arrange systemd units in a hierarchy of slices each + of which might have resource settings applied. + + For units of type slice the only accepted value for + this setting is the parent slice. Since the name of a slice + unit implies the parent slice it is hence redundant to ever + set this parameter directly for slice units. + + + @@ -298,6 +335,7 @@ along with systemd; If not, see . systemd.mount5, systemd.swap5, systemd.directives7, + systemd.special7, The documentation for control groups and specific controllers in the Linux kernel: cgroups.txt, cpuacct.txt, diff --git a/man/systemd.special.xml b/man/systemd.special.xml index 7dbc5580e2..6d456e18e5 100644 --- a/man/systemd.special.xml +++ b/man/systemd.special.xml @@ -1039,40 +1039,44 @@ -.slice The root slice is the - root of the hierarchy. It does - not contain services directly, - but is used to set defaults - for the whole tree. + root of the hierarchy. It + usually does not contain units + directly, but may be used to + set defaults for the whole + tree. system.slice - This slice contains + By default all services services started by - systemd. + systemd are + found in this slice. user.slice - This slice contains user + By default all user processes and services started on behalf of the user, including the per-user systemd - instance. + instance are found in this + slice. machine.slice - This slice contains - virtual machines and - containers registered with - systemd-machined. + By defalt all virtual + machines and containers + registered with + systemd-machined + are found in this slice. -- cgit v1.2.1 From 6aaa8c2f783cd1b3ac27c5ce40625d032e7e3d71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 19 Jul 2013 02:45:27 -0400 Subject: core: add %v specifier --- TODO | 4 +--- man/systemd.unit.xml | 10 ++++++++-- src/core/unit-printf.c | 4 +++- src/shared/install-printf.c | 4 +++- src/shared/specifier.c | 12 ++++++++++++ src/shared/specifier.h | 1 + 6 files changed, 28 insertions(+), 7 deletions(-) diff --git a/TODO b/TODO index 5de106e122..b086b933bb 100644 --- a/TODO +++ b/TODO @@ -60,7 +60,7 @@ Features: * given that logind/machined now let PID 1 do all nasty work we can probably reduce the capability set they retain substantially. -* btfs raid assembly: some .device jobs stay stuck in the queue +* btrfs raid assembly: some .device jobs stay stuck in the queue * Fedora: add an rpmlint check that verifies that all unit files in the RPM are listed in %systemd_post macros. @@ -80,8 +80,6 @@ Features: * journald: optionally, when messages with a high log priority are logged, sync() immediately. -* introduce %v resolving to the string returned by "uname -r" - * systemctl list-unit-files should list generated files (and probably with a new state "generated" for them, or so) * do we really need both hasprefix() and startswith()? diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index f45632a0e3..65ba545037 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -1175,7 +1175,7 @@ The following specifiers are interpreted in the - Install section: %n, %N, %p, %i, %U, %u, %m, %H, %b. + Install section: %n, %N, %p, %i, %U, %u, %m, %H, %b, %v. For their meaning see the next section. @@ -1293,6 +1293,11 @@ Host name The hostname of the running system. + + %v + Kernel release + Identical to uname -r output. + %% Escaped % @@ -1321,7 +1326,8 @@ systemd.snapshot5, systemd.time7, capabilities7, - systemd.directives7 + systemd.directives7, + uname1 diff --git a/src/core/unit-printf.c b/src/core/unit-printf.c index caf51259d2..ffc203dd92 100644 --- a/src/core/unit-printf.c +++ b/src/core/unit-printf.c @@ -268,6 +268,7 @@ char *unit_full_printf(Unit *u, const char *format) { * %m the machine ID of the running system * %H the host name of the running system * %b the boot ID of the running system + * %v `uname -r` of the running system */ const Specifier table[] = { @@ -291,7 +292,8 @@ char *unit_full_printf(Unit *u, const char *format) { { 'm', specifier_machine_id, NULL }, { 'H', specifier_host_name, NULL }, { 'b', specifier_boot_id, NULL }, - { 0, NULL, NULL } + { 'v', specifier_kernel_release, NULL }, + {} }; assert(format); diff --git a/src/shared/install-printf.c b/src/shared/install-printf.c index c44459b4e0..1157ea989b 100644 --- a/src/shared/install-printf.c +++ b/src/shared/install-printf.c @@ -108,6 +108,7 @@ char *install_full_printf(InstallInfo *i, const char *format) { * %m the machine ID of the running system * %H the host name of the running system * %b the boot ID of the running system + * %v `uname -r` of the running system */ const Specifier table[] = { @@ -122,7 +123,8 @@ char *install_full_printf(InstallInfo *i, const char *format) { { 'm', specifier_machine_id, NULL }, { 'H', specifier_host_name, NULL }, { 'b', specifier_boot_id, NULL }, - { 0, NULL, NULL } + { 'v', specifier_kernel_release, NULL }, + {} }; assert(i); diff --git a/src/shared/specifier.c b/src/shared/specifier.c index 7577c91052..bb8859fdfd 100644 --- a/src/shared/specifier.c +++ b/src/shared/specifier.c @@ -20,6 +20,7 @@ ***/ #include +#include #include "macro.h" #include "util.h" @@ -145,3 +146,14 @@ char *specifier_boot_id(char specifier, void *data, void *userdata) { char *specifier_host_name(char specifier, void *data, void *userdata) { return gethostname_malloc(); } + +char *specifier_kernel_release(char specifier, void *data, void *userdata) { + struct utsname uts; + int r; + + r = uname(&uts); + if (r < 0) + return NULL; + + return strdup(uts.release); +} diff --git a/src/shared/specifier.h b/src/shared/specifier.h index 0440dcac48..d13e6406b6 100644 --- a/src/shared/specifier.h +++ b/src/shared/specifier.h @@ -36,3 +36,4 @@ char *specifier_string(char specifier, void *data, void *userdata); char *specifier_machine_id(char specifier, void *data, void *userdata); char *specifier_boot_id(char specifier, void *data, void *userdata); char *specifier_host_name(char specifier, void *data, void *userdata); +char *specifier_kernel_release(char specifier, void *data, void *userdata); -- cgit v1.2.1 From aea38d8047a7a9370f8545007d242ede4a5cede1 Mon Sep 17 00:00:00 2001 From: Jesper Larsen Date: Fri, 19 Jul 2013 11:40:44 +0200 Subject: nspawn: Reorder includes to fix compilation Commit 2e996f4d4b642c5682c608c9692ad2ffae398ab2 added an include of linux/netlink.h This kernel header is not self contained in the linux 2.6 kernel which breaks compilation with an unknown type sa_family_t A workaround is to include linux/netlink.h after sys/socket.h --- src/nspawn/nspawn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index cfd88efc9e..fc005d9ce3 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -39,9 +39,9 @@ #include #include #include -#include #include #include +#include #include #include -- cgit v1.2.1 From 86d7de36869429f20d75e34bb3ddb2cfd2470e75 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Fri, 19 Jul 2013 13:54:51 +0200 Subject: man: Fix example to use the new --boot syntax --- man/journalctl.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/man/journalctl.xml b/man/journalctl.xml index da43bf2879..c8559a0cb0 100644 --- a/man/journalctl.xml +++ b/man/journalctl.xml @@ -851,9 +851,9 @@ journalctl /dev/sda - Show all kernel logs from last boot: + Show all kernel logs from previous boot: - journalctl -k -b : + journalctl -k -b -1 -- cgit v1.2.1 From ef89eef77ee098a6828169a6d0d74128e236bcbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 18 Jul 2013 19:36:55 -0400 Subject: udev: fix two trivial memleaks in error path Based-on-a-patch-by: Ian Stakenvicius --- src/udev/collect/collect.c | 6 +++--- src/udev/udevadm-hwdb.c | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/udev/collect/collect.c b/src/udev/collect/collect.c index f95ee23b75..1346f27f91 100644 --- a/src/udev/collect/collect.c +++ b/src/udev/collect/collect.c @@ -442,19 +442,19 @@ int main(int argc, char **argv) if (debug) fprintf(stderr, "ID %s: not in database\n", argv[i]); - him = malloc(sizeof (struct _mate)); + him = new(struct _mate, 1); if (!him) { ret = ENOMEM; goto out; } - him->name = malloc(strlen(argv[i]) + 1); + him->name = strdup(argv[i]); if (!him->name) { + free(him); ret = ENOMEM; goto out; } - strcpy(him->name, argv[i]); him->state = STATE_NONE; udev_list_node_append(&him->node, &bunch); } else { diff --git a/src/udev/udevadm-hwdb.c b/src/udev/udevadm-hwdb.c index 4136b17be5..d9dc73bfc1 100644 --- a/src/udev/udevadm-hwdb.c +++ b/src/udev/udevadm-hwdb.c @@ -303,8 +303,10 @@ static int64_t trie_store_nodes(struct trie_f *trie, struct trie_node *node) { int64_t child_off; child_off = trie_store_nodes(trie, node->children[i].child); - if (child_off < 0) + if (child_off < 0) { + free(children); return child_off; + } children[i].c = node->children[i].c; children[i].child_off = htole64(child_off); } -- cgit v1.2.1 From e2f2fb786059fbed410938f16e5cc8b851366b14 Mon Sep 17 00:00:00 2001 From: Maciej Wereski Date: Fri, 19 Jul 2013 15:43:12 +0200 Subject: tmpfiles: Fix memory leak in parse_line() --- src/tmpfiles/tmpfiles.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 555347ac36..eae993e6b6 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -971,6 +971,12 @@ static void item_free(Item *i) { free(i); } +static inline void item_freep(Item **i) { + if (*i) + item_free(*i); +} +#define _cleanup_item_free_ _cleanup_(item_freep) + static bool item_equal(Item *a, Item *b) { assert(a); assert(b); @@ -1013,7 +1019,7 @@ static bool item_equal(Item *a, Item *b) { } static int parse_line(const char *fname, unsigned line, const char *buffer) { - _cleanup_free_ Item *i = NULL; + _cleanup_item_free_ Item *i = NULL; Item *existing; _cleanup_free_ char *mode = NULL, *user = NULL, *group = NULL, *age = NULL; -- cgit v1.2.1 From dc7adf202b82fc0054c457ce6ca3bcedb88dde57 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 19 Jul 2013 17:23:10 +0200 Subject: man: drop the old cgroup settings from the man pages --- TODO | 11 +--- man/systemd.cgroup.xml | 11 +++- man/systemd.exec.xml | 155 +------------------------------------------------ 3 files changed, 12 insertions(+), 165 deletions(-) diff --git a/TODO b/TODO index b086b933bb..d111f36e9e 100644 --- a/TODO +++ b/TODO @@ -21,13 +21,7 @@ Bugfixes: Fedora 20: -* external: maybe it is time to patch procps so that "ps" links to - libsystemd-logind to print a pretty service name, seat name, session - name in its output. Currently it only shows cgroup membership, but - that's sometimes kinda hard to parse for a human. - -* cgroup attrs: - - update dbus interface docs in wiki +* external: ps should gain colums for slice and machine * localed: - localectl: support new converted x11→console keymaps @@ -51,7 +45,8 @@ CGroup Rework Completion: * introduce high-level settings for RT budget, swappiness -* wiki: document new bus APIs of PID 1 +* wiki: document new bus APIs of PID 1 (transient units, Reloading signal), systemctl commands +* review: scope units, slice units, pid1, machinectl, libsystem-login, pam_systemd, systemd-run, systemd-nspawn * Send SIGHUP and SIGTERM in session scopes diff --git a/man/systemd.cgroup.xml b/man/systemd.cgroup.xml index b93b52ff6d..c2a823eba5 100644 --- a/man/systemd.cgroup.xml +++ b/man/systemd.cgroup.xml @@ -309,9 +309,14 @@ along with systemd; If not, see . The name of the slice unit to place the unit in. Defaults to system.slice for all - unit types, except for slice units themselves. This may be - used to arrange systemd units in a hierarchy of slices each - of which might have resource settings applied. + non-instantiated units of all unit types (except for slice + units themselves see below). Instance units are by default + placed in a subslice of system.slice + that is named after the template name. + + This option may be used to arrange systemd units in a + hierarchy of slices each of which might have resource + settings applied. For units of type slice the only accepted value for this setting is the parent slice. Since the name of a slice diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 1169095978..c0e1d862a6 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -791,160 +791,6 @@ setting. - - ControlGroup= - - Controls the control - groups the executed processes shall be - made members of. Takes a - space-separated list of cgroup - identifiers. A cgroup identifier is - formatted like - cpu:/foo/bar, - where "cpu" indicates the kernel - control group controller used, and - /foo/bar is the - control group path. The controller - name and ":" may be omitted in which - case the named systemd control group - hierarchy is implied. Alternatively, - the path and ":" may be omitted, in - which case the default control group - path for this unit is implied. - - This option may be used to place - executed processes in arbitrary groups - in arbitrary hierarchies -- which may - then be externally configured with - additional execution limits. By - default systemd will place all - executed processes in separate - per-unit control groups (named after - the unit) in the systemd named - hierarchy. This option is primarily - intended to place executed processes - in specific paths in specific kernel - controller hierarchies. It is not - recommended to manipulate the service - control group path in the private - systemd named hierarchy - (i.e. name=systemd), - and doing this might result in - undefined behaviour. For details about - control groups see cgroups.txt. - - This option may appear more than - once, in which case the list of - control group assignments is - merged. If the same hierarchy gets two - different paths assigned only the - later setting will take effect. If the - empty string is assigned to this - option the list of control group - assignments is reset, all previous - assignments will have no - effect. - - Note that the list of control - group assignments of a unit is - extended implicitly based on the - settings of - DefaultControllers= - of - systemd-system.conf5, - but a unit's - ControlGroup= - setting for a specific controller - takes precedence. - - - - ControlGroupModify= - Takes a boolean - argument. If true, the control groups - created for this unit will be owned by - the user specified with - User= (and the - appropriate group), and he/she can create - subgroups as well as add processes to - the group. - - - - ControlGroupPersistent= - Takes a boolean - argument. If true, the control groups - created for this unit will be marked - to be persistent, i.e. systemd will - not remove them when stopping the - unit. The default is false, meaning - that the control groups will be - removed when the unit is stopped. For - details about the semantics of this - logic see PaxControlGroups. - - - - ControlGroupAttribute= - - Set a specific control - group attribute for executed - processes, and (if needed) add the - executed processes to a cgroup in the - hierarchy of the controller the - attribute belongs to. Takes two - space-separated arguments: the - attribute name (syntax is - cpu.shares where - cpu refers to a - specific controller and - shares to the - attribute name), and the attribute - value. Example: - ControlGroupAttribute=cpu.shares - 512. If this option is used - for an attribute that belongs to a - kernel controller hierarchy the unit - is not already configured to be added - to (for example via the - ControlGroup= - option) then the unit will be added to - the controller and the default unit - cgroup path is implied. Thus, using - ControlGroupAttribute= - is in most cases sufficient to make - use of control group enforcements, - explicit - ControlGroup= are - only necessary in case the implied - default control group path for a - service is not desirable. For details - about control group attributes see - cgroups.txt. This - option may appear more than once, in - order to set multiple control group - attributes. If this option is used - multiple times for the same cgroup - attribute only the later setting takes - effect. If the empty string is - assigned to this option the list of - attributes is reset, all previous - cgroup attribute settings have no - effect, including those done with - CPUShares=, - MemoryLimit=, - MemorySoftLimit, - DeviceAllow=, - DeviceDeny=, - BlockIOWeight=, - BlockIOReadBandwidth=, - BlockIOWriteBandwidth=. - - - ReadWriteDirectories= ReadOnlyDirectories= @@ -1143,6 +989,7 @@ systemd.swap5, systemd.mount5, systemd.kill5, + systemd.cgroup5, systemd.directives7 -- cgit v1.2.1 From 3803cde44c3d949765bdf0e8bce06886224d40b4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 19 Jul 2013 17:51:26 +0200 Subject: man: extend systemd-run man page a little --- man/systemd-run.xml | 37 +++++++++++++++++++++++++++---------- src/run/run.c | 2 +- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/man/systemd-run.xml b/man/systemd-run.xml index 4ced9bfc00..98ee4762dd 100644 --- a/man/systemd-run.xml +++ b/man/systemd-run.xml @@ -44,7 +44,7 @@ along with systemd; If not, see . systemd-run - Run programs as volatile systemd units + Run programs in transient scope or service units @@ -60,11 +60,26 @@ along with systemd; If not, see . Description - systemd-run may be used - create a transient .service unit - or a .scope unit and launch the - specified COMMAND as part - of this unit. + systemd-run may be used create and start + a transient .service or a + .scope unit and run the specified + COMMAND in it. + + If a command is run as transient service unit, it will be + started and managed by the service manager like any other service, + and thus show up in the output of systemctl + list-units like any other unit. It will run in a clean + and detached execution environment. systemd-run + will start the service asynchronously in the background and + immediately return. + + If a command is run as transient scope unit, it will be + started directly by systemd-run and thus + inherit the execution environment of the caller. It is however + managed by the service manager similar to normal services, and + will also show up in the output of systemctl + list-units. Execution in this case is synchronous, and + execution will return only when the command finishes. @@ -92,8 +107,8 @@ along with systemd; If not, see . - Talk to the systemd manager of the calling - user. + Talk to the service manager of the calling user, + rather than the service manager of the system. @@ -101,7 +116,7 @@ along with systemd; If not, see . - Create a .scope unit instead of + Create a transient .scope unit instead of the default transient .service unit. @@ -136,7 +151,8 @@ along with systemd; If not, see . All command-line arguments after the first non-option argument become part of the commandline of the launched - process. + process. If a command is run as service unit its first argument + needs to be an absolute binary path. @@ -150,6 +166,7 @@ along with systemd; If not, see . See Also systemd1, + systemctl1, systemd.unit5, systemd.service5, systemd.scope5, diff --git a/src/run/run.c b/src/run/run.c index e5a62d9e35..e56a977de3 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -38,7 +38,7 @@ static const char *arg_slice = NULL; static int help(void) { printf("%s [OPTIONS...] [COMMAND LINE...]\n\n" - "Notify the init system about service status updates.\n\n" + "Run the specified command in a transient scope or service unit.\n\n" " -h --help Show this help\n" " --version Show package version\n" " --user Run as user unit\n" -- cgit v1.2.1 From 431c72dc3d482732a01d3ab929aa9b2c36422d46 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 19 Jul 2013 17:55:52 +0200 Subject: man: update systemd-nspawn regarding new --slice= logic --- TODO | 4 ++-- man/systemd-nspawn.xml | 23 ++++++++++++----------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/TODO b/TODO index d111f36e9e..63b1280f04 100644 --- a/TODO +++ b/TODO @@ -45,8 +45,8 @@ CGroup Rework Completion: * introduce high-level settings for RT budget, swappiness -* wiki: document new bus APIs of PID 1 (transient units, Reloading signal), systemctl commands -* review: scope units, slice units, pid1, machinectl, libsystem-login, pam_systemd, systemd-run, systemd-nspawn +* wiki: document new bus APIs of PID 1 (transient units, Reloading signal) +* review: scope units, slice units, pid1, machinectl, libsystem-login, pam_system, systemctl commands * Send SIGHUP and SIGTERM in session scopes diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml index feafb31bc0..f4c5d77eed 100644 --- a/man/systemd-nspawn.xml +++ b/man/systemd-nspawn.xml @@ -239,6 +239,16 @@ container is used. + + + + Make the container + part of the specified slice, instead + of the + machine.slice. + + + @@ -250,16 +260,6 @@ - - - - - Makes the container appear in - other hierarchies than the name=systemd:/ one. - Takes a comma-separated list of controllers. - - - @@ -443,7 +443,8 @@ unshare1, yum8, debootstrap8, - pacman8 + pacman8, + systemd.slice5 -- cgit v1.2.1 From f7f74d8ec46532f13a1dc418d550eaf76b339fa3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 19 Jul 2013 18:00:21 +0200 Subject: man: a few corrections to the machinectl man page --- man/loginctl.xml | 4 ++-- man/machinectl.xml | 17 ++++++++--------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/man/loginctl.xml b/man/loginctl.xml index e129d1b136..ef0dfc06b6 100644 --- a/man/loginctl.xml +++ b/man/loginctl.xml @@ -91,7 +91,7 @@ When showing - session/user properties, limit + session/user/seat properties, limit display to certain properties as specified as argument. If not specified, all set properties are @@ -108,7 +108,7 @@ When showing - unit/job/manager properties, show all + session/user/seat properties, show all properties regardless whether they are set or not. diff --git a/man/machinectl.xml b/man/machinectl.xml index ced304d6d8..37fefeadc8 100644 --- a/man/machinectl.xml +++ b/man/machinectl.xml @@ -91,7 +91,7 @@ When showing - session/user properties, limit the + machine properties, limit the output to certain properties as specified by the argument. If not specified, all set properties are @@ -108,7 +108,7 @@ When showing - unit/job/manager properties, show all + machine properties, show all properties regardless of whether they are set or not. @@ -141,13 +141,13 @@ When used with - kill-session, + kill-machine, choose which processes to kill. Must be one of , or to select whether to kill only the leader process of the - session or all processes of the - session. If omitted, defaults to + machine or all processes of the + machine. If omitted, defaults to . @@ -156,11 +156,10 @@ When used with - kill-session or - kill-user, choose + kill-machine choose which signal to send to selected - processes. Must be one of the well-known - signal specifiers, such as + processes. Must be one of the + well-known signal specifiers, such as SIGTERM, SIGINT or SIGSTOP. If -- cgit v1.2.1 From 60211b35070a20ed0e78a83f39619139d56f7745 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 19 Jul 2013 18:10:12 +0200 Subject: man: document sd_pid_get_slice() call of libsystemd-login --- Makefile-man.am | 5 +++++ TODO | 2 +- man/sd_pid_get_session.xml | 42 +++++++++++++++++++++++++++++++----------- 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/Makefile-man.am b/Makefile-man.am index e74cceaada..a8d418fda6 100644 --- a/Makefile-man.am +++ b/Makefile-man.am @@ -828,6 +828,7 @@ MANPAGES_ALIAS += \ man/sd_login_monitor_unref.3 \ man/sd_pid_get_machine_name.3 \ man/sd_pid_get_owner_uid.3 \ + man/sd_pid_get_slice.3 \ man/sd_pid_get_unit.3 \ man/sd_pid_get_user_unit.3 \ man/sd_seat_can_multi_session.3 \ @@ -855,6 +856,7 @@ man/sd_login_monitor_get_timeout.3: man/sd_login_monitor_new.3 man/sd_login_monitor_unref.3: man/sd_login_monitor_new.3 man/sd_pid_get_machine_name.3: man/sd_pid_get_session.3 man/sd_pid_get_owner_uid.3: man/sd_pid_get_session.3 +man/sd_pid_get_slice.3: man/sd_pid_get_session.3 man/sd_pid_get_unit.3: man/sd_pid_get_session.3 man/sd_pid_get_user_unit.3: man/sd_pid_get_session.3 man/sd_seat_can_multi_session.3: man/sd_seat_get_active.3 @@ -904,6 +906,9 @@ man/sd_pid_get_machine_name.html: man/sd_pid_get_session.html man/sd_pid_get_owner_uid.html: man/sd_pid_get_session.html $(html-alias) +man/sd_pid_get_slice.html: man/sd_pid_get_session.html + $(html-alias) + man/sd_pid_get_unit.html: man/sd_pid_get_session.html $(html-alias) diff --git a/TODO b/TODO index 63b1280f04..d1d7140c8d 100644 --- a/TODO +++ b/TODO @@ -46,7 +46,7 @@ CGroup Rework Completion: * introduce high-level settings for RT budget, swappiness * wiki: document new bus APIs of PID 1 (transient units, Reloading signal) -* review: scope units, slice units, pid1, machinectl, libsystem-login, pam_system, systemctl commands +* review: scope units, slice units, pid1, pam_system, systemctl commands * Send SIGHUP and SIGTERM in session scopes diff --git a/man/sd_pid_get_session.xml b/man/sd_pid_get_session.xml index fd1ce4b87e..ecd22f7bfe 100644 --- a/man/sd_pid_get_session.xml +++ b/man/sd_pid_get_session.xml @@ -48,7 +48,10 @@ sd_pid_get_user_unit sd_pid_get_owner_uid sd_pid_get_machine_name - Determine session, service, owner of a session or container/VM of a specific PID + sd_pid_get_slice + Determine session, service, owner of a + session, container/VM or slice of a specific + PID @@ -84,6 +87,12 @@ pid_t pid char** name + + + int sd_pid_get_slice + pid_t pid + char** slice + @@ -138,11 +147,20 @@ and not being a shared process of a user this function will fail. - sd_pid_machine_name() may - be used to determine the name of the VM or container - is a member of. The machine name is a short string, - suitable for usage in file system paths. The returned - string needs to be freed with the libc + sd_pid_get_machine_name() + may be used to determine the name of the VM or + container is a member of. The machine name is a short + string, suitable for usage in file system paths. The + returned string needs to be freed with the libc + free3 + call after use. + + sd_pid_get_slice() may be + used to determine the slice unit the process is a + member of. See + systemd.slice5 + for details about slices. The returned string needs to + be freed with the libc free3 call after use. @@ -165,10 +183,11 @@ The sd_pid_get_session(), sd_pid_get_unit(), sd_pid_get_user_unit(), - sd_pid_get_owner_uid() and - sd_pid_get_machine_name() - interfaces are available as shared library, which can - be compiled and linked to with the + sd_pid_get_owner_uid(), + sd_pid_get_machine_name() and + sd_pid_get_slice() interfaces are + available as shared library, which can be compiled and + linked to with the libsystemd-login pkg-config1 file. @@ -186,7 +205,8 @@ systemd1, sd-login3, sd_session_is_active3, - getsid2 + getsid2, + systemd.slice5 -- cgit v1.2.1 From 1ec96668dd0dcb19cc2f7b99cbf73df0d769c97d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 19 Jul 2013 18:44:33 +0200 Subject: man: list scope and slice units in systemd(1) --- TODO | 2 +- man/systemd.xml | 50 ++++++++++++++++++++++++++++++++------------------ 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/TODO b/TODO index d1d7140c8d..ffd845b38e 100644 --- a/TODO +++ b/TODO @@ -46,7 +46,7 @@ CGroup Rework Completion: * introduce high-level settings for RT budget, swappiness * wiki: document new bus APIs of PID 1 (transient units, Reloading signal) -* review: scope units, slice units, pid1, pam_system, systemctl commands +* review: scope units, slice units, pam_system, systemctl commands * Send SIGHUP and SIGTERM in session scopes diff --git a/man/systemd.xml b/man/systemd.xml index c7aed3c6ff..06d2ecf6f8 100644 --- a/man/systemd.xml +++ b/man/systemd.xml @@ -285,25 +285,27 @@ Concepts systemd provides a dependency system between - various entities called "units". Units encapsulate - various objects that are relevant for system boot-up - and maintenance. The majority of units are configured - in unit configuration files, whose syntax and basic - set of options is described in + various entities called "units" of 12 different + types. Units encapsulate various objects that are + relevant for system boot-up and maintenance. The + majority of units are configured in unit configuration + files, whose syntax and basic set of options is + described in systemd.unit5, however some are created automatically from other - configuration or dynamically from system state. Units - may be 'active' (meaning started, bound, plugged in, - ... depending on the unit type, see below), or - 'inactive' (meaning stopped, unbound, unplugged, ...), - as well as in the process of being activated or - deactivated, i.e. between the two states (these states - are called 'activating', 'deactivating'). A special - 'failed' state is available as well which is very - similar to 'inactive' and is entered when the service - failed in some way (process returned error code on - exit, or crashed, or an operation timed out). If this - state is entered the cause will be logged, for later + configuration, dynamically from system state or + programmatically at runtime. Units may be 'active' + (meaning started, bound, plugged in, ... depending on + the unit type, see below), or 'inactive' (meaning + stopped, unbound, unplugged, ...), as well as in the + process of being activated or deactivated, + i.e. between the two states (these states are called + 'activating', 'deactivating'). A special 'failed' + state is available as well which is very similar to + 'inactive' and is entered when the service failed in + some way (process returned error code on exit, or + crashed, or an operation timed out). If this state is + entered the cause will be logged, for later reference. Note that the various unit types may have a number of additional substates, which are mapped to the five generalized unit states described @@ -312,7 +314,7 @@ The following unit types are available: - Service units, which control + Service units, which start and control daemons and the processes they consist of. For details see systemd.service5. @@ -369,6 +371,18 @@ objects change or are modified. See systemd.path5. + Slice units may be used to + group units which manage system processes + (such as service and scope units) in a + hierachial tree for resource management + purposes. See + systemd.slice5. + + Scope units are similar to + service units, but manage foreign processes + instead of starting them as well. See + systemd.scope5. + Units are named as their configuration -- cgit v1.2.1 From 7f0386f62c128896519aafa203caa1b3aafd4393 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 19 Jul 2013 18:45:11 +0200 Subject: core: update configuration directive list "systemd --dump-configuration-items" shows --- src/core/load-fragment.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index cf92f0df73..e5fc4a3bd9 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -2647,6 +2647,23 @@ void unit_dump_config_items(FILE *f) { { config_parse_unit_condition_string, "CONDITION" }, { config_parse_unit_condition_null, "CONDITION" }, { config_parse_unit_slice, "SLICE" }, + { config_parse_documentation, "URL" }, + { config_parse_service_timeout, "SECONDS" }, + { config_parse_start_limit_action, "ACTION" }, + { config_parse_set_status, "STATUS" }, + { config_parse_service_sockets, "SOCKETS" }, + { config_parse_fsck_passno, "PASSNO" }, + { config_parse_environ, "ENVIRON" }, + { config_parse_syscall_filter, "SYSCALL" }, + { config_parse_cpu_shares, "SHARES" }, + { config_parse_memory_limit, "LIMIT" }, + { config_parse_device_allow, "DEVICE" }, + { config_parse_device_policy, "POLICY" }, + { config_parse_blockio_bandwidth, "BANDWIDTH" }, + { config_parse_blockio_weight, "WEIGHT" }, + { config_parse_blockio_device_weight, "DEVICEWEIGHT" }, + { config_parse_long, "LONG" }, + { config_parse_socket_service, "SERVICE" }, }; const char *prev = NULL; -- cgit v1.2.1 From 3e2f69b779aa0f3466ebb45837e8507baa0832f7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 19 Jul 2013 18:52:09 +0200 Subject: man: update pam_systemd documentation to current state of the code --- TODO | 2 +- man/pam_systemd.xml | 140 ++++++++++------------------------------------------ 2 files changed, 26 insertions(+), 116 deletions(-) diff --git a/TODO b/TODO index ffd845b38e..a4535b5d9f 100644 --- a/TODO +++ b/TODO @@ -46,7 +46,7 @@ CGroup Rework Completion: * introduce high-level settings for RT budget, swappiness * wiki: document new bus APIs of PID 1 (transient units, Reloading signal) -* review: scope units, slice units, pam_system, systemctl commands +* review: scope units, slice units, systemctl commands * Send SIGHUP and SIGTERM in session scopes diff --git a/man/pam_systemd.xml b/man/pam_systemd.xml index 4e5cdf248b..1d924bc319 100644 --- a/man/pam_systemd.xml +++ b/man/pam_systemd.xml @@ -80,29 +80,32 @@ an independent session counter is used. - A new control group - /user/$USER/$XDG_SESSION_ID - is created and the login process moved into - it. + A new systemd scope unit is + created for the session. If this is the first + concurrent session of the user an implicit + slice below user.slice is + automatically created and the scope placed in + it. In instance of the system service + user@.service which runt + the systemd user manager + instance. On logout, this module ensures the following: - If - $XDG_SESSION_ID is set and - specified, all - remaining processes in the - /user/$USER/$XDG_SESSION_ID - control group are killed and the control group - is removed. - - If the last subgroup of the - /user/$USER control group - was removed the + If this is enabled all + processes of the session are terminated. If + the last concurrent session of a user ends his + user systemd instance will be terminated too, + and so will the user's slice + unit. + + If the las concurrent session + of a user ends the $XDG_RUNTIME_DIR directory - and all its contents are - removed, too. + and all its contents are removed, + too. If the system was not booted up with systemd as @@ -117,79 +120,6 @@ The following options are understood: - - - - Takes a boolean - argument. If true, all processes - created by the user during his session - and from his session will be - terminated when he logs out from his - session. - - - - - - Takes a comma-separated - list of usernames or - numeric user IDs as argument. If this - option is used, the effect of the - options - will apply only to the listed - users. If this option is not used, the - option applies to all local - users. Note that - - takes precedence over this list and is - hence subtracted from the list - specified here. - - - - - - Takes a comma-separated - list of usernames or - numeric user IDs as argument. Users - listed in this argument will not be - subject to the effect of - . - Note that this option takes precedence - over - , and - hence whatever is listed for - - is guaranteed to never be killed by - this PAM module, independent of any - other configuration - setting. - - - - - - Takes a comma-separated - list of control group - controllers in which hierarchies a - user/session control group will be - created by default for each user - logging in, in addition to the control - group in the named 'name=systemd' - hierarchy. If omitted, defaults to an - empty list. - - - - - - Takes a comma-separated - list of control group - controllers in which hierarchies the - logged in processes will be reset to - the root control - group. - @@ -209,29 +139,6 @@ operates. - - Note that setting - kill-session-processes=1 will break tools - like - screen1. - - Note that - kill-session-processes=1 is a - stricter version of - KillUserProcesses=1 which may be - configured system-wide in - logind.conf5. The - former kills processes of a session as soon as it - ends; the latter kills processes as soon as the last - session of the user ends. - - If the options are omitted they default to - , - , - , - , - , - . @@ -306,7 +213,7 @@ account required pam_unix.so password required pam_unix.so session required pam_unix.so session required pam_loginuid.so -session required pam_systemd.so kill-session-processes=1 +session required pam_systemd.so @@ -319,7 +226,10 @@ session required pam_systemd.so kill-session-processes=1 pam.conf5, pam.d5, pam8, - pam_loginuid8 + pam_loginuid8, + systemd.scope5, + systemd.slice5, + systemd.service5 -- cgit v1.2.1 From 9365b048c0c9f62ef7f696216ba049e6b4c2f2e5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 19 Jul 2013 19:04:17 +0200 Subject: man: update scope unit man page a bit --- TODO | 2 +- man/systemd.cgroup.xml | 6 +++++- man/systemd.scope.xml | 33 ++++++++++++++------------------- man/systemd.snapshot.xml | 2 +- 4 files changed, 21 insertions(+), 22 deletions(-) diff --git a/TODO b/TODO index a4535b5d9f..79be347737 100644 --- a/TODO +++ b/TODO @@ -46,7 +46,7 @@ CGroup Rework Completion: * introduce high-level settings for RT budget, swappiness * wiki: document new bus APIs of PID 1 (transient units, Reloading signal) -* review: scope units, slice units, systemctl commands +* review: slice units, systemctl commands * Send SIGHUP and SIGTERM in session scopes diff --git a/man/systemd.cgroup.xml b/man/systemd.cgroup.xml index c2a823eba5..12b19f5c4b 100644 --- a/man/systemd.cgroup.xml +++ b/man/systemd.cgroup.xml @@ -44,7 +44,7 @@ along with systemd; If not, see . systemd.cgroup - Cgroup configuration unit settings + Control Group configuration unit settings @@ -66,6 +66,10 @@ along with systemd; If not, see . configuration options which configure the control group settings for spawned processes. + Control Groups is a concept for organizing processes in a + hierarch tree of named groups for the purpose of resource + management. + This man page lists the configuration options shared by those six unit types. See systemd.unit5 diff --git a/man/systemd.scope.xml b/man/systemd.scope.xml index 126440a15f..1400f8f4b1 100644 --- a/man/systemd.scope.xml +++ b/man/systemd.scope.xml @@ -54,25 +54,20 @@ along with systemd; If not, see . Description - A unit configuration file whose name ends in - .scope encodes information about a unit created - by systemd to encapsulate processes not launched by systemd - itself. This management is performed by creating a node in the - control group tree. Processes are moved into the scope by means - of the D-Bus API. - systemd-run can be - used to easily launch a command in a new scope unit. - - See - systemd.unit5 - for the common options of all unit configuration - files. The common configuration items are configured - in the generic [Unit] and [Install] sections. The - scope specific configuration options are configured in - the [Scope] section. Currently, only generic cgroup settings - as described in - systemd.cgroup7 are allowed. - + Scope units are not configured via unit configuration files, + but are only created programmatically using the bus interfaces of + systemd. They are named similar to filenames. A unit whose name + ends in .scope refers to a scope unit. Scopes + units manage a set of system processes. Unlike service units scope + units manage externally created processes, and do not fork off + processes on its own. + + The main purpose of scope units is grouping worker processes + of a system service for organization and resource management. + + systemd-run may + be used to easily launch a command in a new scope unit from the + command line. Unless DefaultDependencies=false is used, scope units will implicitly have dependencies of diff --git a/man/systemd.snapshot.xml b/man/systemd.snapshot.xml index 4e8d5a901f..1bb074a9b1 100644 --- a/man/systemd.snapshot.xml +++ b/man/systemd.snapshot.xml @@ -56,7 +56,7 @@ Snapshot units are not configured via unit configuration files. Nonetheless they are named - similar to filenames. A unit name whose name ends in + similar to filenames. A unit whose name ends in .snapshot refers to a dynamic snapshot of the systemd runtime state. -- cgit v1.2.1 From 847ae0ae7f29e7bfb245d692409fc2948eab7d1d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 19 Jul 2013 19:16:47 +0200 Subject: man: update documentation of slice units a bit --- TODO | 2 +- man/systemd.scope.xml | 2 +- man/systemd.slice.xml | 34 ++++++++++++++++++++++++++++------ 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/TODO b/TODO index 79be347737..0b11599b8a 100644 --- a/TODO +++ b/TODO @@ -46,7 +46,7 @@ CGroup Rework Completion: * introduce high-level settings for RT budget, swappiness * wiki: document new bus APIs of PID 1 (transient units, Reloading signal) -* review: slice units, systemctl commands +* review: systemctl commands * Send SIGHUP and SIGTERM in session scopes diff --git a/man/systemd.scope.xml b/man/systemd.scope.xml index 1400f8f4b1..ff41c926f4 100644 --- a/man/systemd.scope.xml +++ b/man/systemd.scope.xml @@ -63,7 +63,7 @@ along with systemd; If not, see . processes on its own. The main purpose of scope units is grouping worker processes - of a system service for organization and resource management. + of a system service for organization and for managing resources. systemd-run may be used to easily launch a command in a new scope unit from the diff --git a/man/systemd.slice.xml b/man/systemd.slice.xml index 5376921689..7ddef85eec 100644 --- a/man/systemd.slice.xml +++ b/man/systemd.slice.xml @@ -55,14 +55,34 @@ along with systemd; If not, see . Description A unit configuration file whose name ends in - .slice encodes information about a slice - created by systemd to manage resources used by a certain group of + .slice encodes information about a slice which + is a concept for hierarchially managing resources of a group of processes. This management is performed by creating a node in the - control group tree. Those processes are part of different units, - usually .service units (see - systemd.unit5). + control group tree. Units that manage processes (primarilly scope + and service units) may be assigned to a specific slice. For each + slice certain resource limits may the be set, that apply to all + processes of all units contained in that slice. Slices are + organized hierarchially in a tree. The name of the slice encodes + the location in the tree. The name consists of a "-" separated + series of names, which describes the path to the slice from the + root slice. The root slice is named, + -.slice. Example: + foo-bar.slice is a slice that is located + within foo.slice, which in turn is located in + the root slice -.slice. + By default service and scope units are placed in + system.slice, virtual machines and containers + registered with + systemd-machined1 + are found in machine.slice, and user sessions + handled by + systemd-logind1 + in user.slice. See + systemd.special5 + for more information. + See systemd.unit5 for the common options of all unit configuration @@ -92,7 +112,9 @@ along with systemd; If not, see . systemd.unit5, systemd.cgroup5, systemd.service5, - systemd.directives7. + systemd.scope5, + systemd.special7, + systemd.directives7 -- cgit v1.2.1 From 83787333bd75f3fb5d2d844a5d5dbf68d93f7f3f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 19 Jul 2013 19:28:16 +0200 Subject: man: update documentation of systemctl cgroup commands --- TODO | 1 - man/systemctl.xml | 107 +++++++++------------------------------------- src/systemctl/systemctl.c | 2 +- 3 files changed, 21 insertions(+), 89 deletions(-) diff --git a/TODO b/TODO index 0b11599b8a..33308ef18a 100644 --- a/TODO +++ b/TODO @@ -46,7 +46,6 @@ CGroup Rework Completion: * introduce high-level settings for RT budget, swappiness * wiki: document new bus APIs of PID 1 (transient units, Reloading signal) -* review: systemctl commands * Send SIGHUP and SIGTERM in session scopes diff --git a/man/systemctl.xml b/man/systemctl.xml index 982051778e..4bfce95ffa 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -433,10 +433,7 @@ along with systemd; If not, see . is lost on reboot, the changes are lost too. Similar, when used with - set-cgroup-attr, - unset-cgroup-attr, - set-cgroup and - unset-cgroup, make changes only + set-property make changes only temporarily, so that they are lost on the next reboot. @@ -719,93 +716,28 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service - get-cgroup-attr NAME ATTRIBUTE... + set-property NAME ASSIGNMENT... - Retrieve the specified control group attributes of the - specified unit. Takes a unit name and one or more attribute - names such as cpu.shares. This will - output the current values of the specified attributes, - separated by new-lines. For attributes that take a list of - items, the output will be newline-separated, too. This - operation will always try to retrieve the data in question - from the kernel first, and if that is not available, use the - configured values instead. Instead of low-level control - group attribute names, high-level pretty names may be used, - as used for unit execution environment configuration, see - systemd.exec5 - for details. For example, passing - memory.limit_in_bytes and - MemoryLimit is equivalent. - - - - - set-cgroup-attr NAME ATTRIBUTE VALUE... - - - Set the specified control group attribute of the - specified unit to the specified value. Takes a unit - name and an attribute name such as - cpu.shares, plus one or more values - (multiple values may only be used for attributes that take - multiple values). This operation will immediately update the - kernel attribute for this unit and persistently store this - setting for later reboots (unless - is passed, in which case the setting is not saved - persistently and only valid until the next reboot.) Instead - of low-level control group attribute names, high-level pretty - names may be used, as used for unit execution environment - configuration, see - systemd.exec5 - for details. For example, passing - memory.limit_in_bytes and - MemoryLimit is equivalent. This operation - will implicitly create a control group for the unit in the - controller the attribute belongs to, if needed. For - attributes that take multiple values, this operation will - append the specified values to the previously set values - list (use unset-cgroup-attr to reset the - list explicitly). For attributes that take a single value - only, the list will be reset implicitly. - - - - - unset-cgroup-attr NAME ATTRIBUTE... + Set the specified unit properties at runtime where + this is supported. This allows changing configuration + parameter properties such as resource management controls at + runtime. Not all properties may be changed at runtime, but + many resource management settings (primarily those in + systemd.cgroup5) + may. The changes are applied instantly, and stored on disk + for future boots, unless is + passed in which case the settings only apply until the next + reboot. The syntax of the property assignment follows + closely the syntax of assignments in unit files. - Unset the specified control group attributes - of the specified unit. Takes a unit name and one or more - attribut names such as cpu.shares. This - operation might or might not have an immediate effect on the - current kernel attribute value. This will remove any - persistently stored configuration values for this attribute - (as set with set-cgroup-attr before), - unless is passed, in which case the - configuration is reset only until the next reboot. Again, - high-level control group attributes may be used instead of the - low-level kernel ones. For attributes which take multiple - values, all currently set values are reset. - - - - - set-cgroup NAME CGROUP... - unset-cgroup NAME CGROUP... + Example: systemctl set-property foobar.service CPUShares=777 - Add or remove a unit to/from a specific - control group hierarchy and/or control group path. Takes a - unit name, plus a control group specification in the syntax - CONTROLLER:PATH - or CONTROLLER. In the latter syntax - (where the path is omitted), the default unit control group - path is implied. Examples: cpu or - cpu:/foo/bar. If a unit is removed from a - control group hierarchy, all its processes will be moved to the - root group of the hierarchy and all control group attributes - will be reset. These operations are immediately reflected in - the kernel hierarchy, and stored persistently to disk (unless - is passed). + Note that this command allows changing multiple + properties at the same time, which is preferable over + setting them individually. Like unit file configuration + settings assigning the empty list to list parameters will + reset the list. @@ -1354,6 +1286,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service journalctl1, loginctl1, systemd.unit5, + systemd.cgroupq5, systemd.special7, wall1, systemd.preset5 diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index c9f9981f9c..9f47b2cf7c 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -4788,7 +4788,7 @@ static int systemctl_help(void) { " list-jobs List jobs\n" " cancel [JOB...] Cancel all, one, or more jobs\n\n" "Status Commands:\n" - " dump Dump server status\n" + " dump Dump server status\n\n" "Snapshot Commands:\n" " snapshot [NAME] Create a snapshot\n" " delete [NAME...] Remove one or more snapshots\n\n" -- cgit v1.2.1 From 19cace379f3f680d3201cd257ab3ca6708b2d45d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 19 Jul 2013 19:52:30 +0200 Subject: journald: after the cgroup rework processes may be in both user and system units at the same time --- src/journal/journald-server.c | 31 ++++++++++++++++--------------- src/journal/journald-server.h | 2 +- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 81de959666..60c32b1eff 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -623,19 +623,20 @@ static void dispatch_message_real( if (cg_path_get_unit(c, &t) >= 0) { x = strappenda("_SYSTEMD_UNIT=", t); free(t); - } else if (cg_path_get_user_unit(c, &t) >= 0) { + IOVEC_SET_STRING(iovec[n++], x); + } else if (unit_id && !session) { + x = strappenda("_SYSTEMD_UNIT=", unit_id); + IOVEC_SET_STRING(iovec[n++], x); + } + + if (cg_path_get_user_unit(c, &t) >= 0) { x = strappenda("_SYSTEMD_USER_UNIT=", t); free(t); - } else if (unit_id) { - if (session) - x = strappenda("_SYSTEMD_USER_UNIT=", unit_id); - else - x = strappenda("_SYSTEMD_UNIT=", unit_id); - } else - x = NULL; - - if (x) IOVEC_SET_STRING(iovec[n++], x); + } else if (unit_id && session) { + x = strappenda("_SYSTEMD_USER_UNIT=", unit_id); + IOVEC_SET_STRING(iovec[n++], x); + } free(c); } @@ -728,14 +729,14 @@ static void dispatch_message_real( if (cg_path_get_unit(c, &t) >= 0) { x = strappenda("OBJECT_SYSTEMD_UNIT=", t); free(t); - } else if (cg_path_get_user_unit(c, &t) >= 0) { + IOVEC_SET_STRING(iovec[n++], x); + } + + if (cg_path_get_user_unit(c, &t) >= 0) { x = strappenda("OBJECT_SYSTEMD_USER_UNIT=", t); free(t); - } else - x = NULL; - - if (x) IOVEC_SET_STRING(iovec[n++], x); + } free(c); } diff --git a/src/journal/journald-server.h b/src/journal/journald-server.h index 41f32ba68d..9ff3300a99 100644 --- a/src/journal/journald-server.h +++ b/src/journal/journald-server.h @@ -125,7 +125,7 @@ typedef struct Server { bool sync_scheduled; } Server; -#define N_IOVEC_META_FIELDS 17 +#define N_IOVEC_META_FIELDS 19 #define N_IOVEC_KERNEL_FIELDS 64 #define N_IOVEC_UDEV_FIELDS 32 #define N_IOVEC_OBJECT_FIELDS 11 -- cgit v1.2.1 From d4d60b316914770e9e671122394f96521841eac7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 19 Jul 2013 19:04:08 -0400 Subject: man: also mention /run/log/journal in systemd-jouranld.service(8) --- man/systemd-journald.service.xml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/man/systemd-journald.service.xml b/man/systemd-journald.service.xml index 45091c62ab..5634dd0a21 100644 --- a/man/systemd-journald.service.xml +++ b/man/systemd-journald.service.xml @@ -206,11 +206,15 @@ + /run/log/journal/machine-id/*.journal + /run/log/journal/machine-id/*.journal~ /var/log/journal/machine-id/*.journal /var/log/journal/machine-id/*.journal~ systemd-journald writes entries to files in + /run/log/journal/machine-id/ + or /var/log/journal/machine-id/ with the .journal suffix. If the daemon is stopped @@ -219,7 +223,15 @@ using the .journal~ suffix, and systemd-journald - starts writing to a new file. + starts writing to a new + file. /run is + used when + /var/log/journal + is not available, or when + is + set in the + journald.conf5 + configuration file. -- cgit v1.2.1 From e7c431d3bcfdeeec5dcae0707145edb9a3f749aa Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Thu, 18 Jul 2013 09:18:55 +0200 Subject: make: Automake is complaining about .PRECIOUS being redefined Yesterday I added test-suite.log as dependency to the .PRECIOUS target. Automake is warning about this target being redefined and from what I see there is no way I can stop the warning but I can add the %MAKEFILE% as dependency. automake warning: Makefile.am:35: warning: user target '.PRECIOUS' defined here ... /usr/share/automake-1.13/am/configure.am: ... overrides Automake target '.PRECIOUS' defined here [zj: s/%MAKEFILE%/Makefile/ because %MAKEFILE% wasn't actually substituted properly.] --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index c4b9b1ad2f..3ece887b13 100644 --- a/Makefile.am +++ b/Makefile.am @@ -32,7 +32,7 @@ SUBDIRS = . po .SECONDARY: # Keep the test-suite.log -.PRECIOUS: $(TEST_SUITE_LOG) +.PRECIOUS: $(TEST_SUITE_LOG) Makefile LIBUDEV_CURRENT=4 LIBUDEV_REVISION=6 -- cgit v1.2.1 From bf7f800f2b3e93ccd1229d4717166f3a4d3af72f Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 20 Jul 2013 14:29:12 +0200 Subject: rules: drivers - always call kmod, even when a driver is bound to the device On Sat, Jul 20, 2013 at 12:56 PM, Rafael J. Wysocki wrote: > After a recent change present in 3.11-rc1 there is a driver, called processor, > that can be bound to the CPU devices whose sysfs directories are located under > /sys/devices/system/cpu/. A side effect of this is that, after the driver has > been bound to those devices, the kernel adds DRIVER=processor to ENV for CPU > uevents and they don't match the default rule for autoloading modules matching > MODALIAS: > > DRIVER!="?*", ENV{MODALIAS}=="?*", IMPORT{builtin}="kmod load $env{MODALIAS}" > > any more. However, there are some modules whose module aliases match specific > CPU features through the modalias string and those modules should be loaded > automatically if a compatible CPU is present. Yet, with the processor driver > bound to the CPU devices the above rule is not sufficient for that, so we need > a new default udev rule allowing those modules to be autoloaded even if the > CPU devices have drivers. --- rules/80-drivers.rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/80-drivers.rules b/rules/80-drivers.rules index 50523e4333..0b22d73ce5 100644 --- a/rules/80-drivers.rules +++ b/rules/80-drivers.rules @@ -2,7 +2,7 @@ ACTION=="remove", GOTO="drivers_end" -DRIVER!="?*", ENV{MODALIAS}=="?*", RUN{builtin}="kmod load $env{MODALIAS}" +ENV{MODALIAS}=="?*", RUN{builtin}="kmod load $env{MODALIAS}" SUBSYSTEM=="tifm", ENV{TIFM_CARD_TYPE}=="SD", RUN{builtin}="kmod load tifm_sd" SUBSYSTEM=="tifm", ENV{TIFM_CARD_TYPE}=="MS", RUN{builtin}="kmod load tifm_ms" SUBSYSTEM=="memstick", RUN{builtin}="kmod load ms_block mspro_block" -- cgit v1.2.1 From 459da00fe6496a77dcc31df964b59a17e9746c94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 20 Jul 2013 16:12:10 -0400 Subject: core: correct dbus parameter direction --- src/core/dbus-manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index d7604b1ab9..e1a169ca21 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -236,7 +236,7 @@ " \n" \ " \n" \ " \n" \ - " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ -- cgit v1.2.1 From eb75d0ed059f56f0b5a8dcb8d490fae7063c76ca Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 21 Jul 2013 01:32:27 +0200 Subject: man: udev - add section about hwdb --- man/udev.xml | 49 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/man/udev.xml b/man/udev.xml index ca8444c12c..435dec4c61 100644 --- a/man/udev.xml +++ b/man/udev.xml @@ -30,7 +30,7 @@ udev - Linux dynamic device management + Dynamic device management Description @@ -54,7 +54,7 @@ sources is provided by the library libudev. - Rules files + Rules Files The udev rules are read from the files located in the system rules directory /usr/lib/udev/rules.d, the volatile runtime directory /run/udev/rules.d @@ -67,10 +67,8 @@ used to override a system-supplied rules file with a local file if needed; a symlink in /etc with the same name as a rules file in /lib, pointing to /dev/null, - disables the rules file entirely. - - Rule files must have the extension .rules; other - extensions are ignored. + disables the rules file entirely. Rule files must have the extension + .rules; other extensions are ignored. Every line in the rules file contains at least one key-value pair. Except for empty lines or lines beginning with #, which are ignored. @@ -273,7 +271,7 @@ - Most of the fields support shell-style pattern matching. The following + Most of the fields support shell glob pattern matching. The following pattern characters are supported: @@ -471,7 +469,7 @@ Import the stored keys from the parent device by reading the database entry of the parent device. The value assigned to is used as a filter of key names - to import (with the same shell-style pattern matching used for + to import (with the same shell glob pattern matching used for comparisons). @@ -701,6 +699,41 @@ + Hardware Database Files + The hwdb files are read from the files located in the + system hwdb directory /usr/lib/udev/hwdb.d, + the volatile runtime directory /run/udev/hwdb.d + and the local administration directory /etc/udev/hwdb.d. + All rules files are collectively sorted and processed in lexical order, + regardless of the directories in which they live. However, files with + identical filenames replace each other. Files in /etc + have the highest priority, files in /run take precedence + over files with the same name in /lib. This can be + used to override a system-supplied hwdb file with a local file if needed; + a symlink in /etc with the same name as a rules file in + /lib, pointing to /dev/null, + disables the rules file entirely. Hwdb files must have the extension + .hwdb; other extensions are ignored. + + The hwdb file contains data records consisting of matches and + associated key-value pairs. Every record in the hwdb starts with one or + more match string, specifying a shell glob to compare the database + lookup string against. Multiple match lines are specified in additional + consecutive lines. Every match line is compared indivdually, they are + combined by OR. Every match line must start at the first character of + the line. + + The match lines are followed by one or more key-value pair lines, which + are recognized by a leading space character. The key name and value are separated + by =. An empty line signifies the end + of a record. Lines beginning with # are ignored. + + The content of all hwdb files is read by + udevadm8 + and compiled to a binary database located at /etc/udev/hwdb.bin. + During runtime only the binary database is used. + + See Also -- cgit v1.2.1 From 3c475ce44e6b3b5bd6b22cff11a1322dabd95ba0 Mon Sep 17 00:00:00 2001 From: Shawn Landden Date: Sat, 20 Jul 2013 10:15:13 -0700 Subject: shared: fix build on !x86 --- src/shared/virt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shared/virt.c b/src/shared/virt.c index 1abd6863ea..4f8134a773 100644 --- a/src/shared/virt.c +++ b/src/shared/virt.c @@ -29,6 +29,8 @@ /* Returns a short identifier for the various VM implementations */ int detect_vm(const char **id) { + _cleanup_free_ char *cpuinfo_contents = NULL; + int r; #if defined(__i386__) || defined(__x86_64__) @@ -67,8 +69,6 @@ int detect_vm(const char **id) { const char *j, *k; bool hypervisor; _cleanup_free_ char *hvtype = NULL; - _cleanup_free_ char *cpuinfo_contents = NULL; - int r; /* Try high-level hypervisor sysfs file first: * -- cgit v1.2.1 From 44affdc5fd20f812c25bc9d2b1a9fc04215274a1 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 21 Jul 2013 16:32:43 +0200 Subject: rules: net, tty description - ask hwdb explicitly for pci data --- rules/75-net-description.rules | 4 ++-- rules/75-tty-description.rules | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/rules/75-net-description.rules b/rules/75-net-description.rules index fe9fca14db..7e62f8b26b 100644 --- a/rules/75-net-description.rules +++ b/rules/75-net-description.rules @@ -4,11 +4,11 @@ ACTION=="remove", GOTO="net_end" SUBSYSTEM!="net", GOTO="net_end" IMPORT{builtin}="net_id" + SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb" SUBSYSTEMS=="usb", GOTO="net_end" SUBSYSTEMS=="pci", ENV{ID_BUS}="pci", ENV{ID_VENDOR_ID}="$attr{vendor}", ENV{ID_MODEL_ID}="$attr{device}" - -IMPORT{builtin}="hwdb" +SUBSYSTEMS=="pci", IMPORT{builtin}="hwdb --subsystem=pci" LABEL="net_end" diff --git a/rules/75-tty-description.rules b/rules/75-tty-description.rules index 83083d93ea..11277b7d6f 100644 --- a/rules/75-tty-description.rules +++ b/rules/75-tty-description.rules @@ -7,7 +7,6 @@ SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=u SUBSYSTEMS=="usb", GOTO="tty_end" SUBSYSTEMS=="pci", ENV{ID_BUS}="pci", ENV{ID_VENDOR_ID}="$attr{vendor}", ENV{ID_MODEL_ID}="$attr{device}" - -IMPORT{builtin}="hwdb" +SUBSYSTEMS=="pci", IMPORT{builtin}="hwdb --subsystem=pci" LABEL="tty_end" -- cgit v1.2.1 From fbce11397f4d19821a9dfe66ee3ebe11cad90057 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sun, 21 Jul 2013 06:53:14 +0200 Subject: man: wording and grammar updates This includes regularly-submitted corrections to comma setting and orthographical mishaps that appeared in man/ in recent commits. --- man/crypttab.xml | 4 ++-- man/journalctl.xml | 2 +- man/machinectl.xml | 2 +- man/pam_systemd.xml | 12 ++++++------ man/systemctl.xml | 10 +++++----- man/systemd-bootchart.xml | 2 +- man/systemd-machined.service.xml | 2 +- man/systemd-run.xml | 2 +- man/systemd.cgroup.xml | 4 ++-- man/systemd.scope.xml | 2 +- man/systemd.slice.xml | 6 +++--- man/systemd.special.xml | 6 +++--- man/systemd.unit.xml | 2 +- man/systemd.xml | 14 +++++++------- man/udev.xml | 2 +- 15 files changed, 36 insertions(+), 36 deletions(-) diff --git a/man/crypttab.xml b/man/crypttab.xml index 298f39e0e3..5aade57c42 100644 --- a/man/crypttab.xml +++ b/man/crypttab.xml @@ -167,7 +167,7 @@ luks Force LUKS mode. When this mode - is used the following options are ignored since + is used, the following options are ignored since they are provided by the LUKS header on the device: cipher=, hash=, @@ -232,7 +232,7 @@ tcrypt Use TrueCrypt encryption mode. - When this mode is used the following options are + When this mode is used, the following options are ignored since they are provided by the TrueCrypt header on the device or do not apply: cipher=, diff --git a/man/journalctl.xml b/man/journalctl.xml index c8559a0cb0..dcc6d5dce9 100644 --- a/man/journalctl.xml +++ b/man/journalctl.xml @@ -269,7 +269,7 @@ - is very similar + is very similar, but shows ISO 8601 wallclock timestamps. diff --git a/man/machinectl.xml b/man/machinectl.xml index 37fefeadc8..5efa3a542a 100644 --- a/man/machinectl.xml +++ b/man/machinectl.xml @@ -156,7 +156,7 @@ When used with - kill-machine choose + kill-machine, choose which signal to send to selected processes. Must be one of the well-known signal specifiers, such as diff --git a/man/pam_systemd.xml b/man/pam_systemd.xml index 1d924bc319..951ae207a4 100644 --- a/man/pam_systemd.xml +++ b/man/pam_systemd.xml @@ -82,11 +82,11 @@ A new systemd scope unit is created for the session. If this is the first - concurrent session of the user an implicit + concurrent session of the user, an implicit slice below user.slice is automatically created and the scope placed in it. In instance of the system service - user@.service which runt + user@.service which runs the systemd user manager instance. @@ -94,15 +94,15 @@ On logout, this module ensures the following: - If this is enabled all + If this is enabled, all processes of the session are terminated. If - the last concurrent session of a user ends his + the last concurrent session of a user ends, his user systemd instance will be terminated too, and so will the user's slice unit. - If the las concurrent session - of a user ends the + If the last concurrent session + of a user ends, the $XDG_RUNTIME_DIR directory and all its contents are removed, too. diff --git a/man/systemctl.xml b/man/systemctl.xml index 4bfce95ffa..ee13a70fef 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -111,8 +111,8 @@ along with systemd; If not, see . - Argument should be a comma-separated list of unit LOAD - or SUB or ACTIVE states. When listing units show only those + The argument should be a comma-separated list of unit LOAD + or SUB or ACTIVE states. When listing units, show only those with specified LOAD or SUB or ACTIVE state. @@ -433,7 +433,7 @@ along with systemd; If not, see . is lost on reboot, the changes are lost too. Similar, when used with - set-property make changes only + set-property, make changes only temporarily, so that they are lost on the next reboot. @@ -727,7 +727,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service systemd.cgroup5) may. The changes are applied instantly, and stored on disk for future boots, unless is - passed in which case the settings only apply until the next + passed, in which case the settings only apply until the next reboot. The syntax of the property assignment follows closely the syntax of assignments in unit files. @@ -736,7 +736,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service Note that this command allows changing multiple properties at the same time, which is preferable over setting them individually. Like unit file configuration - settings assigning the empty list to list parameters will + settings, assigning the empty list to list parameters will reset the list. diff --git a/man/systemd-bootchart.xml b/man/systemd-bootchart.xml index 8de4c69a2d..ae432b563f 100644 --- a/man/systemd-bootchart.xml +++ b/man/systemd-bootchart.xml @@ -203,7 +203,7 @@ - Specify the output folder for the + Specify the output directory for the graphs. By default, bootchart writes the graphs to /run/log. diff --git a/man/systemd-machined.service.xml b/man/systemd-machined.service.xml index 525944b1bc..abe221a178 100644 --- a/man/systemd-machined.service.xml +++ b/man/systemd-machined.service.xml @@ -63,7 +63,7 @@ See systemd-nspawn1 - for some examples how to start a container the systemd + for some examples on how to start a container the systemd way. See the . All command-line arguments after the first non-option argument become part of the commandline of the launched - process. If a command is run as service unit its first argument + process. If a command is run as service unit, its first argument needs to be an absolute binary path. diff --git a/man/systemd.cgroup.xml b/man/systemd.cgroup.xml index 12b19f5c4b..cc0eb15abb 100644 --- a/man/systemd.cgroup.xml +++ b/man/systemd.cgroup.xml @@ -322,9 +322,9 @@ along with systemd; If not, see . hierarchy of slices each of which might have resource settings applied. - For units of type slice the only accepted value for + For units of type slice, the only accepted value for this setting is the parent slice. Since the name of a slice - unit implies the parent slice it is hence redundant to ever + unit implies the parent slice, it is hence redundant to ever set this parameter directly for slice units. diff --git a/man/systemd.scope.xml b/man/systemd.scope.xml index ff41c926f4..e8fa1aed59 100644 --- a/man/systemd.scope.xml +++ b/man/systemd.scope.xml @@ -58,7 +58,7 @@ along with systemd; If not, see . but are only created programmatically using the bus interfaces of systemd. They are named similar to filenames. A unit whose name ends in .scope refers to a scope unit. Scopes - units manage a set of system processes. Unlike service units scope + units manage a set of system processes. Unlike service units, scope units manage externally created processes, and do not fork off processes on its own. diff --git a/man/systemd.slice.xml b/man/systemd.slice.xml index 7ddef85eec..b7b0622d3c 100644 --- a/man/systemd.slice.xml +++ b/man/systemd.slice.xml @@ -60,10 +60,10 @@ along with systemd; If not, see . processes. This management is performed by creating a node in the control group tree. Units that manage processes (primarilly scope and service units) may be assigned to a specific slice. For each - slice certain resource limits may the be set, that apply to all + slice, certain resource limits may the be set that apply to all processes of all units contained in that slice. Slices are organized hierarchially in a tree. The name of the slice encodes - the location in the tree. The name consists of a "-" separated + the location in the tree. The name consists of a dash-separated series of names, which describes the path to the slice from the root slice. The root slice is named, -.slice. Example: @@ -72,7 +72,7 @@ along with systemd; If not, see . the root slice -.slice. - By default service and scope units are placed in + By default, service and scope units are placed in system.slice, virtual machines and containers registered with systemd-machined1 diff --git a/man/systemd.special.xml b/man/systemd.special.xml index 6d456e18e5..e1299abcb0 100644 --- a/man/systemd.special.xml +++ b/man/systemd.special.xml @@ -1050,7 +1050,7 @@ system.slice - By default all services + By default, all services services started by systemd are found in this slice. @@ -1060,7 +1060,7 @@ user.slice - By default all user + By default, all user processes and services started on behalf of the user, including the per-user systemd @@ -1072,7 +1072,7 @@ machine.slice - By defalt all virtual + By defalt, all virtual machines and containers registered with systemd-machined diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index 65ba545037..f6a0791bf9 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -1119,7 +1119,7 @@ A symbolic link is created in the .wants/ or - .requires/ folder + .requires/ directory of the listed unit when this unit is activated by systemctl enable. This has the effect diff --git a/man/systemd.xml b/man/systemd.xml index 06d2ecf6f8..1e54eac926 100644 --- a/man/systemd.xml +++ b/man/systemd.xml @@ -294,18 +294,18 @@ systemd.unit5, however some are created automatically from other configuration, dynamically from system state or - programmatically at runtime. Units may be 'active' - (meaning started, bound, plugged in, ... depending on - the unit type, see below), or 'inactive' (meaning + programmatically at runtime. Units may be "active" + (meaning started, bound, plugged in, ..., depending on + the unit type, see below), or "inactive" (meaning stopped, unbound, unplugged, ...), as well as in the process of being activated or deactivated, i.e. between the two states (these states are called - 'activating', 'deactivating'). A special 'failed' - state is available as well which is very similar to - 'inactive' and is entered when the service failed in + "activating", "deactivating"). A special "failed" + state is available as well, which is very similar to + "inactive" and is entered when the service failed in some way (process returned error code on exit, or crashed, or an operation timed out). If this state is - entered the cause will be logged, for later + entered, the cause will be logged, for later reference. Note that the various unit types may have a number of additional substates, which are mapped to the five generalized unit states described diff --git a/man/udev.xml b/man/udev.xml index 435dec4c61..0220725140 100644 --- a/man/udev.xml +++ b/man/udev.xml @@ -712,7 +712,7 @@ used to override a system-supplied hwdb file with a local file if needed; a symlink in /etc with the same name as a rules file in /lib, pointing to /dev/null, - disables the rules file entirely. Hwdb files must have the extension + disables the rules file entirely. hwdb files must have the extension .hwdb; other extensions are ignored. The hwdb file contains data records consisting of matches and -- cgit v1.2.1 From 408f281bc7d65c86563f46e99e07efd1a1d9e03a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 22 Jul 2013 00:16:17 +0200 Subject: NEWS: prepare half a NEWS file for upcoming 206 --- NEWS | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ TODO | 2 ++ 2 files changed, 57 insertions(+) diff --git a/NEWS b/NEWS index 5560355b90..d44e6feaf1 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,60 @@ systemd System and Service Manager +CHANGES WITH 206: + + * The documentation has been updated to cover the various new + concepts introduced with 205. + + * Unit files now understand the new %v specifier which + resolves to the kernel version string as returned by "uname + -r". + + * systemctl now supports filtering the unit list output by + load state, active state and sub state, using the new + --type= parameter. + + * "systemctl status" will now show the results of the + condition checks (like ConditionPathExists= and similar) of + the last start attempts of the unit. They are also logged to + the journal. + + * "journalctl -b" may now be used to look for boot output of a + specific boot. Try "journalctl -b -1" for the previous boot, + but the syntax is substantially more powerful. + + * "journalctl --show-cursor" has been added which prints the + cursor string the last shown log line. This may then be used + with the new "journalctl --after-cursor=" switch to continue + browsing logs from that point on. + + * "journalctl --force" may now be used to force regeneration + of an FSS key. + + * Device ACLs may now be applied to "dead" devices nodes too, + i.e. device nodes that are created based on modalias + information of unloaded kernel modules. + + * A new RPM macro has been added that may be used to apply + tmpfiles configuration during package installation. + + * systemd-detect-virt and ConditionVirtualization= now can + detect User-Mode-Linux machines (UML). + + * journald will now log the effective capabilities set of + processes in the message metadata. + + * systemd-cryptsetup has gained support for TrueCrypt volumes. + + * The initrd interface has been simplified (more specifically, + support for passing performance data via environment + variables and fsck results via files in /run has been + removed). These features were non-essential, and are + nowadays available in a much nicer way by having systemd in + the initrd serialize its state and have the hosts systemd + deserialize it again. + + ... + CHANGES WITH 205: * Two new unit types have been introduced: diff --git a/TODO b/TODO index 33308ef18a..ba8bb8e80f 100644 --- a/TODO +++ b/TODO @@ -51,6 +51,8 @@ CGroup Rework Completion: Features: +* journalctl: instead --after-cursor= maybe have a --cursor=XYZ+1 syntax? + * given that logind/machined now let PID 1 do all nasty work we can probably reduce the capability set they retain substantially. -- cgit v1.2.1 From ef7e6e0598b1711d7ccf741bb8e4e07a02ef33a7 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Mon, 22 Jul 2013 16:59:26 +0200 Subject: systemd-tmpfiles-setup-dev: remain after exit Without this, tmpfiles-setpu-dev would be re-run if any other service, which pulls in basic.target, was started after setup-dev was finished and before basic.target was active. --- units/systemd-tmpfiles-setup-dev.service.in | 1 + 1 file changed, 1 insertion(+) diff --git a/units/systemd-tmpfiles-setup-dev.service.in b/units/systemd-tmpfiles-setup-dev.service.in index 8073b1229d..5c45d3465b 100644 --- a/units/systemd-tmpfiles-setup-dev.service.in +++ b/units/systemd-tmpfiles-setup-dev.service.in @@ -14,4 +14,5 @@ ConditionCapability=CAP_MKNOD [Service] Type=oneshot +RemainAfterExit=true ExecStart=@rootbindir@/systemd-tmpfiles --prefix=/dev --create -- cgit v1.2.1 From 7e380bba1cd517570655c0e653e2239e33988cd1 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Mon, 22 Jul 2013 17:10:15 +0200 Subject: kmod-static-nodes: remain after exit --- units/kmod-static-nodes.service.in | 1 + units/systemd-tmpfiles-setup-dev.service.in | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/units/kmod-static-nodes.service.in b/units/kmod-static-nodes.service.in index 624a650526..cdfc6e56e1 100644 --- a/units/kmod-static-nodes.service.in +++ b/units/kmod-static-nodes.service.in @@ -12,5 +12,6 @@ Before=sysinit.target systemd-tmpfiles-setup-dev.service [Service] Type=oneshot +RemainAfterExit=yes ExecStartPre=@MKDIR_P@ /run/tmpfiles.d ExecStart=@KMOD@ static-nodes --format=tmpfiles --output=/run/tmpfiles.d/kmod.conf diff --git a/units/systemd-tmpfiles-setup-dev.service.in b/units/systemd-tmpfiles-setup-dev.service.in index 5c45d3465b..579e7c6a4f 100644 --- a/units/systemd-tmpfiles-setup-dev.service.in +++ b/units/systemd-tmpfiles-setup-dev.service.in @@ -14,5 +14,5 @@ ConditionCapability=CAP_MKNOD [Service] Type=oneshot -RemainAfterExit=true +RemainAfterExit=yes ExecStart=@rootbindir@/systemd-tmpfiles --prefix=/dev --create -- cgit v1.2.1 From 28f5c779e5513ab1301ac103471009711b0961e0 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 22 Jul 2013 20:17:26 +0200 Subject: TODO: update --- NEWS | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index d44e6feaf1..d7ab865f11 100644 --- a/NEWS +++ b/NEWS @@ -31,8 +31,8 @@ CHANGES WITH 206: of an FSS key. * Device ACLs may now be applied to "dead" devices nodes too, - i.e. device nodes that are created based on modalias - information of unloaded kernel modules. + i.e. device nodes that are created based on kernel module + information of not yet loaded kernel modules. * A new RPM macro has been added that may be used to apply tmpfiles configuration during package installation. @@ -53,7 +53,10 @@ CHANGES WITH 206: the initrd serialize its state and have the hosts systemd deserialize it again. - ... + * The udev "keymap" data files and tools to apply keyboard + specific mappings of scan to key codes, and force-release + scan code lists have been entirely replaced by a udev + "keyboard" builtin and a hwdb data file. CHANGES WITH 205: -- cgit v1.2.1 From efa3c0af8e0c8a9c7e3059bde65081b0020dfa6c Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 22 Jul 2013 23:00:31 +0200 Subject: bus: update for kdbus changes --- src/libsystemd-bus/bus-kernel.c | 11 +++-------- src/libsystemd-bus/kdbus.h | 3 --- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index ffa843d5d1..bf8de04ab6 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -654,7 +654,7 @@ int bus_kernel_read_message(sd_bus *bus, sd_bus_message **m) { int bus_kernel_create(const char *name, char **s) { struct kdbus_cmd_bus_make *make; - struct kdbus_item *n, *cg; + struct kdbus_item *n; size_t l; int fd; char *p; @@ -671,17 +671,12 @@ int bus_kernel_create(const char *name, char **s) { KDBUS_ITEM_HEADER_SIZE + sizeof(uint64_t) + KDBUS_ITEM_HEADER_SIZE + DECIMAL_STR_MAX(uid_t) + 1 + l + 1); - cg = make->items; - cg->type = KDBUS_MAKE_CGROUP; - cg->data64[0] = 1; - cg->size = KDBUS_ITEM_HEADER_SIZE + sizeof(uint64_t); - - n = KDBUS_ITEM_NEXT(cg); + n = make->items; n->type = KDBUS_MAKE_NAME; sprintf(n->str, "%lu-%s", (unsigned long) getuid(), name); n->size = KDBUS_ITEM_HEADER_SIZE + strlen(n->str) + 1; - make->size = offsetof(struct kdbus_cmd_bus_make, items) + cg->size + n->size; + make->size = offsetof(struct kdbus_cmd_bus_make, items) + n->size; make->flags = KDBUS_MAKE_POLICY_OPEN; make->bus_flags = 0; make->bloom_size = BLOOM_SIZE; diff --git a/src/libsystemd-bus/kdbus.h b/src/libsystemd-bus/kdbus.h index 4604eb32b7..06c2c245f3 100644 --- a/src/libsystemd-bus/kdbus.h +++ b/src/libsystemd-bus/kdbus.h @@ -283,9 +283,6 @@ enum { enum { _KDBUS_MAKE_NULL, KDBUS_MAKE_NAME, - KDBUS_MAKE_CGROUP, /* the cgroup hierarchy ID for which to attach - * cgroup membership paths to messages. - * FIXME: remove, use *the* hierarchy */ KDBUS_MAKE_CRED, /* allow translator services which connect * to the bus on behalf of somebody else, * allow specifiying the credentials of the -- cgit v1.2.1 From 33b521be152f67cd722695ba9a2966eda5ee6765 Mon Sep 17 00:00:00 2001 From: Maciej Wereski Date: Mon, 22 Jul 2013 11:02:50 +0200 Subject: NEWS: fix mistake --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index d7ab865f11..346b906992 100644 --- a/NEWS +++ b/NEWS @@ -11,7 +11,7 @@ CHANGES WITH 206: * systemctl now supports filtering the unit list output by load state, active state and sub state, using the new - --type= parameter. + --state= parameter. * "systemctl status" will now show the results of the condition checks (like ConditionPathExists= and similar) of -- cgit v1.2.1 From 251cc8194228ac86c9a7a4c75a54a94cea2095c7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 23 Jul 2013 01:32:36 +0200 Subject: build-sys: prepare 206 --- Makefile.am | 8 ++++---- NEWS | 49 ++++++++++++++++++++++++++++++++++++++++++++----- configure.ac | 2 +- 3 files changed, 49 insertions(+), 10 deletions(-) diff --git a/Makefile.am b/Makefile.am index 3ece887b13..7933de677a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -35,7 +35,7 @@ SUBDIRS = . po .PRECIOUS: $(TEST_SUITE_LOG) Makefile LIBUDEV_CURRENT=4 -LIBUDEV_REVISION=6 +LIBUDEV_REVISION=7 LIBUDEV_AGE=3 LIBGUDEV_CURRENT=1 @@ -43,7 +43,7 @@ LIBGUDEV_REVISION=3 LIBGUDEV_AGE=1 LIBSYSTEMD_LOGIN_CURRENT=8 -LIBSYSTEMD_LOGIN_REVISION=0 +LIBSYSTEMD_LOGIN_REVISION=1 LIBSYSTEMD_LOGIN_AGE=8 LIBSYSTEMD_DAEMON_CURRENT=0 @@ -51,11 +51,11 @@ LIBSYSTEMD_DAEMON_REVISION=10 LIBSYSTEMD_DAEMON_AGE=0 LIBSYSTEMD_ID128_CURRENT=0 -LIBSYSTEMD_ID128_REVISION=23 +LIBSYSTEMD_ID128_REVISION=24 LIBSYSTEMD_ID128_AGE=0 LIBSYSTEMD_JOURNAL_CURRENT=11 -LIBSYSTEMD_JOURNAL_REVISION=0 +LIBSYSTEMD_JOURNAL_REVISION=1 LIBSYSTEMD_JOURNAL_AGE=11 # Dirs of external packages diff --git a/NEWS b/NEWS index 346b906992..f9929d0725 100644 --- a/NEWS +++ b/NEWS @@ -30,9 +30,25 @@ CHANGES WITH 206: * "journalctl --force" may now be used to force regeneration of an FSS key. - * Device ACLs may now be applied to "dead" devices nodes too, - i.e. device nodes that are created based on kernel module - information of not yet loaded kernel modules. + * Creation of "dead" device nodes has been moved from udev + into kmod and tmpfiles. Previously, udev would read the kmod + databases to pre-generate dead device nodes based on meta + information contained in kernel modules, so that these would + be auto-loaded on access rather then at boot. As this + doesn't really have much to do with the exposing actual + kernel devices to userspace this has always been slightly + alien in the udev codebase. Following the new scheme kmod + will now generate a runtime snippet for tmpfiles from the + module meta information and it now is tmpfiles' job to the + create the nodes. This also allows overriding access and + other parameters for the nodes using the usual tmpfiles + facilities. As side effect this allows us to remove the + CAP_SYS_MKNOD capability bit from udevd entirely. + + * logind's device ACLs may now be applied to these "dead" + devices nodes too, thus finally allowing managed access to + devices such as /dev/snd/sequencer whithout loading the + backing module right-away. * A new RPM macro has been added that may be used to apply tmpfiles configuration during package installation. @@ -40,8 +56,8 @@ CHANGES WITH 206: * systemd-detect-virt and ConditionVirtualization= now can detect User-Mode-Linux machines (UML). - * journald will now log the effective capabilities set of - processes in the message metadata. + * journald will now implicitly log the effective capabilities + set of processes in the message metadata. * systemd-cryptsetup has gained support for TrueCrypt volumes. @@ -58,6 +74,29 @@ CHANGES WITH 206: scan code lists have been entirely replaced by a udev "keyboard" builtin and a hwdb data file. + * systemd will now honour the kernel's "quiet" command line + argument also during late shutdown, resulting in a + completely silent shutdown when used. + + * There's now an option to control the SO_REUSEPORT socket + option in .socket units. + + * Instance units will now automatically get a per-template + subslice of system.slice unless something else is explicitly + configured. For example, instances of sshd@.service will now + implicitly be placed in system-sshd.slice rather than + system.slice as before. + + * Test coverage support may now be enabled at build time. + + Contributions from: Dave Reisner, Frederic Crozat, Harald + Hoyer, Holger Hans Peter Freyther, Jan Engelhardt, Jan + Janssen, Jason St. John, Jesper Larsen, Kay Sievers, Lennart + Poettering, Lukas Nykryn, Maciej Wereski, Martin Pitt, Michael + Olbrich, Ramkumar Ramachandra, Ross Lagerwall, Shawn Landden, + Thomas H.P. Andersen, Tom Gundersen, Tomasz Torcz, William + Giokas, Zbigniew Jędrzejewski-Szmek + CHANGES WITH 205: * Two new unit types have been introduced: diff --git a/configure.ac b/configure.ac index 9095be7ca6..759073a2c1 100644 --- a/configure.ac +++ b/configure.ac @@ -20,7 +20,7 @@ AC_PREREQ([2.64]) AC_INIT([systemd], - [205], + [206], [http://bugs.freedesktop.org/enter_bug.cgi?product=systemd], [systemd], [http://www.freedesktop.org/wiki/Software/systemd]) -- cgit v1.2.1 From f4f8f7b546508e1e7c94b072df685ac1342e8d7e Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Tue, 23 Jul 2013 04:54:40 +0200 Subject: README Bump minimum required version of kmod See edeb68c53f1cdc452016b4c8512586a70b1262e3. --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 3cd93f01f4..46eb28eda1 100644 --- a/README +++ b/README @@ -89,7 +89,7 @@ REQUIREMENTS: dbus >= 1.4.0 libcap libblkid >= 2.20 (from util-linux) (optional) - libkmod >= 5 (optional) + libkmod >= 14 (optional) PAM >= 1.1.2 (optional) libcryptsetup (optional) libaudit (optional) -- cgit v1.2.1 From 0778c3db87383ffcbe0fd303019c8b7e96b75394 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Tue, 23 Jul 2013 05:03:17 +0200 Subject: man: Fix copy&paste error --- man/udev.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/man/udev.xml b/man/udev.xml index 0220725140..f107482329 100644 --- a/man/udev.xml +++ b/man/udev.xml @@ -704,15 +704,15 @@ system hwdb directory /usr/lib/udev/hwdb.d, the volatile runtime directory /run/udev/hwdb.d and the local administration directory /etc/udev/hwdb.d. - All rules files are collectively sorted and processed in lexical order, + All hwdb files are collectively sorted and processed in lexical order, regardless of the directories in which they live. However, files with identical filenames replace each other. Files in /etc have the highest priority, files in /run take precedence over files with the same name in /lib. This can be used to override a system-supplied hwdb file with a local file if needed; - a symlink in /etc with the same name as a rules file in + a symlink in /etc with the same name as a hwdb file in /lib, pointing to /dev/null, - disables the rules file entirely. hwdb files must have the extension + disables the hwdb file entirely. hwdb files must have the extension .hwdb; other extensions are ignored. The hwdb file contains data records consisting of matches and -- cgit v1.2.1 From 21bf2ab082b42f03df5b4685df2fddc4d6e0d572 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 23 Jul 2013 12:25:32 +0200 Subject: remove left-over initrd time stamp handling --- src/core/main.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index 77cdcfe872..ad155e13ca 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1280,18 +1280,8 @@ int main(int argc, char *argv[]) { log_set_target(LOG_TARGET_KMSG); log_open(); - if (in_initrd()) { - char *rd_timestamp = NULL; - + if (in_initrd()) initrd_timestamp = userspace_timestamp; - asprintf(&rd_timestamp, "%llu %llu", - (unsigned long long) initrd_timestamp.realtime, - (unsigned long long) initrd_timestamp.monotonic); - if (rd_timestamp) { - setenv("RD_TIMESTAMP", rd_timestamp, 1); - free(rd_timestamp); - } - } if (!skip_setup) { mount_setup_early(); -- cgit v1.2.1 From 41f1a1da57a0cef035d1f78c21bcff3dc3f76f79 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Tue, 23 Jul 2013 11:26:58 -0400 Subject: remove systemd-timestamp from sources No sense in keeping this around if support for reading RD_TIMESTAMP has been removed. --- .gitignore | 1 - Makefile.am | 8 -------- src/timestamp/Makefile | 1 - src/timestamp/timestamp.c | 39 --------------------------------------- 4 files changed, 49 deletions(-) delete mode 120000 src/timestamp/Makefile delete mode 100644 src/timestamp/timestamp.c diff --git a/.gitignore b/.gitignore index bdf9d4afd8..694fc3d8f2 100644 --- a/.gitignore +++ b/.gitignore @@ -75,7 +75,6 @@ /systemd-sysctl /systemd-system-update-generator /systemd-timedated -/systemd-timestamp /systemd-tmpfiles /systemd-tty-ask-password-agent /systemd-uaccess diff --git a/Makefile.am b/Makefile.am index 7933de677a..d013dfd85f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -315,7 +315,6 @@ rootlibexec_PROGRAMS = \ systemd-remount-fs \ systemd-reply-password \ systemd-fsck \ - systemd-timestamp \ systemd-ac-power \ systemd-sysctl \ systemd-sleep @@ -1606,13 +1605,6 @@ systemd_fsck_LDADD = \ libsystemd-dbus.la \ libudev.la -# ------------------------------------------------------------------------------ -systemd_timestamp_SOURCES = \ - src/timestamp/timestamp.c - -systemd_timestamp_LDADD = \ - libsystemd-shared.la - # ------------------------------------------------------------------------------ systemd_ac_power_SOURCES = \ src/ac-power/ac-power.c diff --git a/src/timestamp/Makefile b/src/timestamp/Makefile deleted file mode 120000 index d0b0e8e008..0000000000 --- a/src/timestamp/Makefile +++ /dev/null @@ -1 +0,0 @@ -../Makefile \ No newline at end of file diff --git a/src/timestamp/timestamp.c b/src/timestamp/timestamp.c deleted file mode 100644 index 1152f1b52e..0000000000 --- a/src/timestamp/timestamp.c +++ /dev/null @@ -1,39 +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 Lesser General Public License as published by - the Free Software Foundation; either version 2.1 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see . -***/ - -#include - -#include "util.h" - -int main(int argc, char *argv[]) { - struct dual_timestamp t; - - /* This is mostly useful for stuff like init ram disk scripts - * which want to take a proper timestamp to do minimal bootup - * profiling. */ - - dual_timestamp_get(&t); - printf("%llu %llu\n", - (unsigned long long) t.realtime, - (unsigned long long) t.monotonic); - - return 0; -} -- cgit v1.2.1 From 8b18fdc19531ba56d0bdfe34c62870997a9bcc96 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 24 Jul 2013 07:24:05 +0200 Subject: core: synchronously block when logging Previously, the logging sockets were asynchronous and if clogged we'd lose messages. We did this to be extra careful given that PID 1 might need to spawn the logging daemon as response to PID 1's own log messages and we really should avoid a deadlock in that case. As it turns out this causes loss of too many messages, hence make the socket blocking again, however put a time limit on it to avoid unbounded deadlocks in the unlikely case they happen. https://bugs.freedesktop.org/show_bug.cgi?id=66664 --- src/shared/log.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/shared/log.c b/src/shared/log.c index 27317f7ed3..8f4995a0c8 100644 --- a/src/shared/log.c +++ b/src/shared/log.c @@ -115,16 +115,20 @@ void log_close_syslog(void) { static int create_log_socket(int type) { int fd; + struct timeval tv; - /* All output to the syslog/journal fds we do asynchronously, - * and if the buffers are full we just drop the messages */ - - fd = socket(AF_UNIX, type|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); + fd = socket(AF_UNIX, type|SOCK_CLOEXEC, 0); if (fd < 0) return -errno; fd_inc_sndbuf(fd, SNDBUF_SIZE); + /* We need a blocking fd here since we'd otherwise lose + messages way too early. However, let's not hang forever in the + unlikely case of a deadlock. */ + timeval_store(&tv, 1*USEC_PER_MINUTE); + setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); + return fd; } -- cgit v1.2.1 From d07f7b9ef2835c290d6beadebd17d15308608eea Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 24 Jul 2013 08:08:57 +0200 Subject: journal: immediately sync to disk as soon as we receieve an EMERG/ALERT/CRIT message --- TODO | 2 -- man/journald.conf.xml | 14 +++++++++++--- src/journal/journald-server.c | 26 ++++++++++++++++---------- src/journal/journald-server.h | 2 +- 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/TODO b/TODO index ba8bb8e80f..279ea60ebd 100644 --- a/TODO +++ b/TODO @@ -74,8 +74,6 @@ Features: * journald: optionally, log debug messages to /run but everything else to /var -* journald: optionally, when messages with a high log priority are logged, sync() immediately. - * systemctl list-unit-files should list generated files (and probably with a new state "generated" for them, or so) * do we really need both hasprefix() and startswith()? diff --git a/man/journald.conf.xml b/man/journald.conf.xml index 487e8d618a..9219b3daaf 100644 --- a/man/journald.conf.xml +++ b/man/journald.conf.xml @@ -348,9 +348,17 @@ SyncIntervalSec= - The timeout before synchronizing journal - data to disk. After syncing, journal files have - the OFFLINE state. Default timeout is 5 minutes. + The timeout before + synchronizing journal files to + disk. After syncing, journal files are + placed in the OFFLINE state. Note that + syncing is unconditionally done + immediately after a log message of + priority CRIT, ALERT or EMERG has been + logged, this setting hence applies + only to messages of the levels ERR, + WARNING, NOTICE, INFO, DEBUG. The + default timeout is 5 minutes. diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 60c32b1eff..821935c390 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -352,13 +352,12 @@ void server_rotate(Server *s) { } void server_sync(Server *s) { + static const struct itimerspec sync_timer_disable = {}; JournalFile *f; void *k; Iterator i; int r; - static const struct itimerspec sync_timer_disable = {}; - if (s->system_journal) { r = journal_file_set_offline(s->system_journal); if (r < 0) @@ -443,7 +442,7 @@ bool shall_try_append_again(JournalFile *f, int r) { return true; } -static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned n) { +static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned n, int priority) { JournalFile *f; bool vacuumed = false; int r; @@ -469,7 +468,7 @@ static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL); if (r >= 0) { - server_schedule_sync(s); + server_schedule_sync(s, priority); return; } @@ -499,7 +498,8 @@ static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned size += iovec[i].iov_len; log_error("Failed to write entry (%d items, %zu bytes) despite vacuuming, ignoring: %s", n, size, strerror(-r)); - } + } else + server_schedule_sync(s, priority); } static void dispatch_message_real( @@ -509,6 +509,7 @@ static void dispatch_message_real( struct timeval *tv, const char *label, size_t label_len, const char *unit_id, + int priority, pid_t object_pid) { char pid[sizeof("_PID=") + DECIMAL_STR_MAX(pid_t)], @@ -523,7 +524,6 @@ static void dispatch_message_real( o_owner_uid[sizeof("OBJECT_SYSTEMD_OWNER_UID=") + DECIMAL_STR_MAX(uid_t)]; uid_t object_uid; gid_t object_gid; - char *x; sd_id128_t id; int r; @@ -786,7 +786,7 @@ static void dispatch_message_real( else journal_uid = 0; - write_to_journal(s, journal_uid, iovec, n); + write_to_journal(s, journal_uid, iovec, n, priority); } void server_driver_message(Server *s, sd_id128_t message_id, const char *format, ...) { @@ -820,7 +820,7 @@ void server_driver_message(Server *s, sd_id128_t message_id, const char *format, ucred.uid = getuid(); ucred.gid = getgid(); - dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL, NULL, 0, NULL, 0); + dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL, NULL, 0, NULL, LOG_INFO, 0); } void server_dispatch_message( @@ -886,7 +886,7 @@ void server_dispatch_message( "Suppressed %u messages from %s", rl - 1, path); finish: - dispatch_message_real(s, iovec, n, m, ucred, tv, label, label_len, unit_id, object_pid); + dispatch_message_real(s, iovec, n, m, ucred, tv, label, label_len, unit_id, priority, object_pid); } @@ -1423,11 +1423,17 @@ static int server_open_sync_timer(Server *s) { return 0; } -int server_schedule_sync(Server *s) { +int server_schedule_sync(Server *s, int priority) { int r; assert(s); + if (priority <= LOG_CRIT) { + /* Immediately sync to disk when this is of priority CRIT, ALERT, EMERG */ + server_sync(s); + return 0; + } + if (s->sync_scheduled) return 0; diff --git a/src/journal/journald-server.h b/src/journal/journald-server.h index 9ff3300a99..e856ef277a 100644 --- a/src/journal/journald-server.h +++ b/src/journal/journald-server.h @@ -153,7 +153,7 @@ void server_done(Server *s); void server_sync(Server *s); void server_vacuum(Server *s); void server_rotate(Server *s); -int server_schedule_sync(Server *s); +int server_schedule_sync(Server *s, int priority); int server_flush_to_var(Server *s); int process_event(Server *s, struct epoll_event *ev); void server_maybe_append_tags(Server *s); -- cgit v1.2.1 From e946948eff517e895b287d0fd8c6d069ab9bbbb9 Mon Sep 17 00:00:00 2001 From: Jesper Larsen Date: Tue, 23 Jul 2013 15:50:09 +0200 Subject: README: Bump to Linux 3.0 Support for writing to cgroup.procs was introduced in 3.0 --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 46eb28eda1..0d7db41160 100644 --- a/README +++ b/README @@ -34,7 +34,7 @@ LICENSE: - except src/udev/ which is (currently still) GPLv2+ REQUIREMENTS: - Linux kernel >= 2.6.39 + Linux kernel >= 3.0 CONFIG_DEVTMPFS CONFIG_CGROUPS (it's OK to disable all controllers) CONFIG_INOTIFY_USER -- cgit v1.2.1 From 4c10771ce273872f4833da4e9dd7e1c72cf20de5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 23 Jul 2013 22:01:39 -0400 Subject: initctl: use irreversible jobs when switching runlevels Spotted by uau in #systemd. --- src/initctl/initctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/initctl/initctl.c b/src/initctl/initctl.c index 735f1e1450..5fbce4a9a7 100644 --- a/src/initctl/initctl.c +++ b/src/initctl/initctl.c @@ -122,7 +122,7 @@ static void change_runlevel(Server *s, int runlevel) { if (isolate) mode = "isolate"; else - mode = "replace"; + mode = "replace-irreversibly"; log_debug("Running request %s/start/%s", target, mode); -- cgit v1.2.1 From 80d39fbb3e3d2fb51988f9ade378663694947e28 Mon Sep 17 00:00:00 2001 From: William Giokas <1007380@gmail.com> Date: Tue, 23 Jul 2013 21:55:22 -0500 Subject: shell-completion: Add machinectl zsh completion --- shell-completion/systemd-zsh-completion.zsh | 49 ++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/shell-completion/systemd-zsh-completion.zsh b/shell-completion/systemd-zsh-completion.zsh index c85e00e384..b62b6df946 100644 --- a/shell-completion/systemd-zsh-completion.zsh +++ b/shell-completion/systemd-zsh-completion.zsh @@ -1,4 +1,4 @@ -#compdef systemctl loginctl journalctl hostnamectl localectl timedatectl systemd-coredumpctl udevadm systemd-analyze systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-inhibit systemd-machine-id-setup systemd-notify systemd-nspawn systemd-tmpfiles systemd-tty-ask-password-agent +#compdef systemctl loginctl journalctl hostnamectl localectl timedatectl systemd-coredumpctl udevadm systemd-analyze systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-inhibit systemd-machine-id-setup systemd-notify systemd-nspawn systemd-tmpfiles systemd-tty-ask-password-agent machinectl _ctls() { @@ -263,6 +263,21 @@ _ctls() '--plymouth[Ask question with plymouth(8).]' \ '--console[Ask question on /dev/console.]' ;; + machinectl) + _arguments \ + {-h,--help}'[Prints a short help text and exits.]' \ + '--version[Prints a short version string and exits.]' \ + {-p,--property=}'[Limit output to specified property.]:property:(Name Id Timestamp TimestampMonotonic Service Scope Leader Class State RootDirectory)' \ + {-a,--all}'[Show all proerties]' \ + (-l,--full)'[Do not ellipsize cgroup members]' \ + '--no-pager[Do not pipe output into a pager]' \ + '--no-ask-password[Do not ask for system passwords]' \ + '--kill-who=[Who to send signal to]:killwho:(leader all)' \ + {-s,--signal=}'[Which signal to send]:signal:_signals' \ + {-H,--host=}'[Show information for remote host]:userathost:_hosts_or_user_at_host' \ + {-P,--privileged}'[Acquire privileges before execution]' \ + '*::machinectl command:_machinectl_command' + ;; *) _message 'eh?' ;; esac } @@ -916,6 +931,38 @@ _systemd-coredumpctl_command(){ } +(( $+functions[_machinectl_command] )) || _machinectl_command() +{ + local -a _machinectl_cmds + _machinectl_cmds=( + "list:List currently running VMs/containers" + "status:Show VM/container status" + "show:Show properties of one or more VMs/containers" + "terminate:Terminate one or more VMs/containers" + "kill:Send signal to process or a VM/container" + ) + if (( CURRENT == 1 )); then + _describe -t commands 'machinectl command' _machinectl_cmds || compadd "$@" + else + local curcontext="$curcontext" + cmd="${${_machinectl_cmds[(r)$words[1]:*]%%:*}}" + if (( $#cmd )); then + case $cmd in + list) msg="no options" ;; + *) + _machines=( "${(foa)$(machinectl list | awk '{print $1}')}" ) + if [[ -n "$_machines" ]]; then + _describe 'machines' _machines + else + _message 'no machines' + fi + esac + else + _message "no more options" + fi + fi +} + _udevadm_info(){ _arguments \ '--query=[Query the database for specified type of device data. It needs the --path or --name to identify the specified device.]:type:(name symlink path property all)' \ -- cgit v1.2.1 From 490f0087627f441d5fece276ec86b64b5a9d6495 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Wed, 24 Jul 2013 14:55:19 +0200 Subject: udev: log error if chmod/chown of static dev nodes fails --- src/udev/udev-rules.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index 8ace7050db..fe4965feb9 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -2593,13 +2593,21 @@ int udev_rules_apply_static_dev_perms(struct udev_rules *rules) mode = 0600; } if (mode != (stats.st_mode & 01777)) { - chmod(device_node, mode); - log_debug("chmod '%s' %#o\n", device_node, mode); + r = chmod(device_node, mode); + if (r < 0) { + log_error("failed to chmod '%s' %#o\n", device_node, mode); + return -errno; + } else + log_debug("chmod '%s' %#o\n", device_node, mode); } if ((uid != 0 && uid != stats.st_uid) || (gid != 0 && gid != stats.st_gid)) { - chown(device_node, uid, gid); - log_debug("chown '%s' %u %u\n", device_node, uid, gid); + r = chown(device_node, uid, gid); + if (r < 0) { + log_error("failed to chown '%s' %u %u \n", device_node, uid, gid); + return -errno; + } else + log_debug("chown '%s' %u %u\n", device_node, uid, gid); } utimensat(AT_FDCWD, device_node, NULL, 0); -- cgit v1.2.1 From 15a722007dc1d8a9a11934b2ab528cf4d25b6c62 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Wed, 24 Jul 2013 15:05:48 +0200 Subject: udev: static_node - don't touch permissions uneccessarily Don't set default permissions if only TAGS were specified in a rule. --- src/udev/udev-rules.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index fe4965feb9..769b670b20 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -2586,6 +2586,10 @@ int udev_rules_apply_static_dev_perms(struct udev_rules *rules) } } + /* don't touch the permissions if only the tags were set */ + if (mode == 0 && uid == 0 && gid == 0) + goto next; + if (mode == 0) { if (gid > 0) mode = 0660; -- cgit v1.2.1 From a2aced4add1964f82cfd250f1fee8de9d974b507 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Wed, 24 Jul 2013 11:10:05 -0400 Subject: tmpfiles: support passing --prefix multiple times --- man/systemd-tmpfiles.xml | 3 ++- src/tmpfiles/tmpfiles.c | 24 +++++++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/man/systemd-tmpfiles.xml b/man/systemd-tmpfiles.xml index 405a9f1781..b0f2d9ceb7 100644 --- a/man/systemd-tmpfiles.xml +++ b/man/systemd-tmpfiles.xml @@ -121,7 +121,8 @@ Only apply rules that apply to paths with the specified - prefix. + prefix. This option can be specified + multiple times. diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index eae993e6b6..cb15133e5e 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -105,7 +105,7 @@ static bool arg_create = false; static bool arg_clean = false; static bool arg_remove = false; -static const char *arg_prefix = NULL; +static char **include_prefixes = NULL; static const char conf_file_dirs[] = "/etc/tmpfiles.d\0" @@ -1018,6 +1018,21 @@ static bool item_equal(Item *a, Item *b) { return true; } +static bool should_include_path(const char *path) { + char **prefix; + + /* no explicit paths specified for inclusion, so everything is valid */ + if (strv_length(include_prefixes) == 0) + return true; + + STRV_FOREACH(prefix, include_prefixes) { + if (path_startswith(path, *prefix)) + return true; + } + + return false; +} + static int parse_line(const char *fname, unsigned line, const char *buffer) { _cleanup_item_free_ Item *i = NULL; Item *existing; @@ -1119,7 +1134,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { path_kill_slashes(i->path); - if (arg_prefix && !path_startswith(i->path, arg_prefix)) + if (!should_include_path(i->path)) return 0; if (user && !streq(user, "-")) { @@ -1258,7 +1273,8 @@ static int parse_argv(int argc, char *argv[]) { break; case ARG_PREFIX: - arg_prefix = optarg; + if (strv_extend(&include_prefixes, optarg) < 0) + return log_oom(); break; case '?': @@ -1423,6 +1439,8 @@ finish: hashmap_free(items); hashmap_free(globs); + strv_free(include_prefixes); + set_free_free(unix_sockets); label_finish(); -- cgit v1.2.1 From 5c7951141fa9f33e1b97de97586cc16bce2776e0 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Wed, 24 Jul 2013 11:19:24 -0400 Subject: tmpfiles: introduce --exclude-prefix The opposite of --prefix, allows specifying path prefixes which should be skipped when processing rules. --- man/systemd-tmpfiles.xml | 7 +++++ shell-completion/systemd-zsh-completion.zsh | 1 + src/tmpfiles/tmpfiles.c | 44 ++++++++++++++++++----------- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/man/systemd-tmpfiles.xml b/man/systemd-tmpfiles.xml index b0f2d9ceb7..403592dd71 100644 --- a/man/systemd-tmpfiles.xml +++ b/man/systemd-tmpfiles.xml @@ -124,6 +124,13 @@ prefix. This option can be specified multiple times. + + + Ignore rules that + apply to paths with the specified + prefix. This option can be specified + multiple times. + diff --git a/shell-completion/systemd-zsh-completion.zsh b/shell-completion/systemd-zsh-completion.zsh index b62b6df946..1ab1311ec1 100644 --- a/shell-completion/systemd-zsh-completion.zsh +++ b/shell-completion/systemd-zsh-completion.zsh @@ -249,6 +249,7 @@ _ctls() '--clean[Clean up all files and directories with an age parameter configured.]' \ '--remove[All files and directories marked with r, R in the configuration files are removed.]' \ '--prefix=[Only apply rules that apply to paths with the specified prefix.]' \ + '--exclude-prefix=[Ignore rules that apply to paths with the specified prefix.]' \ '--help[Prints a short help text and exits.]' \ '*::files:_files' ;; diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index cb15133e5e..5eca82ad26 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -106,6 +106,7 @@ static bool arg_clean = false; static bool arg_remove = false; static char **include_prefixes = NULL; +static char **exclude_prefixes = NULL; static const char conf_file_dirs[] = "/etc/tmpfiles.d\0" @@ -1021,16 +1022,19 @@ static bool item_equal(Item *a, Item *b) { static bool should_include_path(const char *path) { char **prefix; - /* no explicit paths specified for inclusion, so everything is valid */ - if (strv_length(include_prefixes) == 0) - return true; + STRV_FOREACH(prefix, exclude_prefixes) { + if (path_startswith(path, *prefix)) + return false; + } STRV_FOREACH(prefix, include_prefixes) { if (path_startswith(path, *prefix)) return true; } - return false; + /* no matches, so we should include this path only if we + * have no whitelist at all */ + return strv_length(include_prefixes) == 0; } static int parse_line(const char *fname, unsigned line, const char *buffer) { @@ -1219,11 +1223,12 @@ static int help(void) { printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n" "Creates, deletes and cleans up volatile and temporary files and directories.\n\n" - " -h --help Show this help\n" - " --create Create marked files/directories\n" - " --clean Clean up marked directories\n" - " --remove Remove marked files/directories\n" - " --prefix=PATH Only apply rules that apply to paths with the specified prefix\n", + " -h --help Show this help\n" + " --create Create marked files/directories\n" + " --clean Clean up marked directories\n" + " --remove Remove marked files/directories\n" + " --prefix=PATH Only apply rules that apply to paths with the specified prefix\n" + " --exclude-prefix=PATH Ignore rules that apply to paths with the specified prefix\n", program_invocation_short_name); return 0; @@ -1235,16 +1240,18 @@ static int parse_argv(int argc, char *argv[]) { ARG_CREATE, ARG_CLEAN, ARG_REMOVE, - ARG_PREFIX + ARG_PREFIX, + ARG_EXCLUDE_PREFIX, }; static const struct option options[] = { - { "help", no_argument, NULL, 'h' }, - { "create", no_argument, NULL, ARG_CREATE }, - { "clean", no_argument, NULL, ARG_CLEAN }, - { "remove", no_argument, NULL, ARG_REMOVE }, - { "prefix", required_argument, NULL, ARG_PREFIX }, - { NULL, 0, NULL, 0 } + { "help", no_argument, NULL, 'h' }, + { "create", no_argument, NULL, ARG_CREATE }, + { "clean", no_argument, NULL, ARG_CLEAN }, + { "remove", no_argument, NULL, ARG_REMOVE }, + { "prefix", required_argument, NULL, ARG_PREFIX }, + { "exclude-prefix", required_argument, NULL, ARG_EXCLUDE_PREFIX }, + { NULL, 0, NULL, 0 } }; int c; @@ -1277,6 +1284,11 @@ static int parse_argv(int argc, char *argv[]) { return log_oom(); break; + case ARG_EXCLUDE_PREFIX: + if (strv_extend(&exclude_prefixes, optarg) < 0) + return log_oom(); + break; + case '?': return -EINVAL; -- cgit v1.2.1 From ec99834cb0e76a9e7096bd42249053712db9c32d Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Wed, 24 Jul 2013 11:58:35 -0400 Subject: tmpfiles-setup: exclude /dev prefixes files Fixes Arch Linux bug: https://bugs.archlinux.org/task/36259 --- units/systemd-tmpfiles-setup.service.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/units/systemd-tmpfiles-setup.service.in b/units/systemd-tmpfiles-setup.service.in index 67c7d4af43..6f98063744 100644 --- a/units/systemd-tmpfiles-setup.service.in +++ b/units/systemd-tmpfiles-setup.service.in @@ -21,4 +21,4 @@ ConditionDirectoryNotEmpty=|/run/tmpfiles.d [Service] Type=oneshot RemainAfterExit=yes -ExecStart=@rootbindir@/systemd-tmpfiles --create --remove +ExecStart=@rootbindir@/systemd-tmpfiles --create --remove --exclude-prefix=/dev -- cgit v1.2.1 From 819da59577758a7a328020546127091e45bc59e7 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 26 Jul 2013 02:33:51 +0200 Subject: shell-completion: add kernel-install --- Makefile.am | 3 +- shell-completion/bash/kernel-install | 68 ++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 shell-completion/bash/kernel-install diff --git a/Makefile.am b/Makefile.am index d013dfd85f..3d08d7cb9c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -339,7 +339,8 @@ dist_bashcompletion_DATA = \ shell-completion/bash/journalctl \ shell-completion/bash/systemctl \ shell-completion/bash/systemd-analyze \ - shell-completion/bash/udevadm + shell-completion/bash/udevadm \ + shell-completion/bash/kernel-install dist_sysctl_DATA = \ sysctl.d/50-default.conf diff --git a/shell-completion/bash/kernel-install b/shell-completion/bash/kernel-install new file mode 100644 index 0000000000..1832d4aba4 --- /dev/null +++ b/shell-completion/bash/kernel-install @@ -0,0 +1,68 @@ +# kernel-install(8) completion -*- shell-script -*- +# +# This file is part of systemd. +# +# Copyright 2013 Kay Sievers +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 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 Lesser General Public License +# along with systemd; If not, see . + +__contains_word () { + local word=$1; shift + for w in $*; do [[ $w = $word ]] && return 0; done + return 1 +} + +_kernel_install() { + local i verb comps + local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} + local OPTS='-h --help' + + local -A VERBS=( + [ADD]='add' + [REMOVE]='remove' + ) + + for ((i=0; $i <= $COMP_CWORD; i++)); do + if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} && + ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then + verb=${COMP_WORDS[i]} + break + fi + done + + if [[ -z $verb && $cur = -* ]]; then + COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") ) + return 0 + fi + + if [[ -z $verb ]]; then + comps=${VERBS[*]} + + elif __contains_word "$verb" ${VERBS[ADD]}; then + if [[ $prev = "$verb" ]]; then + comps=$(cd /lib/modules; echo [0-9]*) + elif [[ $prev = [0-9]* ]]; then + comps=$(echo /boot/vmlinuz-$prev*) + fi + + elif __contains_word "$verb" ${VERBS[REMOVE]}; then + comps=$(cd /lib/modules; echo [0-9]*) + + fi + + COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) + return 0 +} + +complete -F _kernel_install kernel-install -- cgit v1.2.1 From 39bdfa31f2f00c3357e2a7a5f139abee6d7c7cd3 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 26 Jul 2013 03:34:18 +0200 Subject: shared: split mkdir_*() and mkdir_*_label() from each other Avoid pulling-in selinux for tools which just create directories but not need to fix the selinux label. --- Makefile.am | 1 + src/shared/cgroup-label.c | 2 +- src/shared/label.c | 4 ++-- src/shared/label.h | 2 +- src/shared/mkdir-label.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++ src/shared/mkdir.c | 40 +++++++++-------------------------- src/shared/mkdir.h | 21 ++++++++++++------- 7 files changed, 81 insertions(+), 42 deletions(-) create mode 100644 src/shared/mkdir-label.c diff --git a/Makefile.am b/Makefile.am index 3d08d7cb9c..8ac1d8d0f3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -752,6 +752,7 @@ libsystemd_label_la_SOURCES = \ src/shared/selinux-util.c \ src/shared/selinux-util.h \ src/shared/mkdir.c \ + src/shared/mkdir-label.c \ src/shared/mkdir.h \ src/shared/ask-password-api.c \ src/shared/ask-password-api.h \ diff --git a/src/shared/cgroup-label.c b/src/shared/cgroup-label.c index 574a7be3ee..bae0a627d2 100644 --- a/src/shared/cgroup-label.c +++ b/src/shared/cgroup-label.c @@ -47,7 +47,7 @@ int cg_create(const char *controller, const char *path) { if (r < 0) return r; - r = mkdir_parents_prefix("/sys/fs/cgroup", fs, 0755); + r = mkdir_parents_prefix_label("/sys/fs/cgroup", fs, 0755); if (r < 0) return r; diff --git a/src/shared/label.c b/src/shared/label.c index 1fe4574633..fde39f2259 100644 --- a/src/shared/label.c +++ b/src/shared/label.c @@ -257,14 +257,14 @@ void label_free(const char *label) { #endif } -int label_mkdir(const char *path, mode_t mode, bool apply) { +int label_mkdir(const char *path, mode_t mode) { /* Creates a directory and labels it according to the SELinux policy */ #ifdef HAVE_SELINUX int r; security_context_t fcon = NULL; - if (!apply || !use_selinux() || !label_hnd) + if (!use_selinux() || !label_hnd) goto skipped; if (path_is_absolute(path)) diff --git a/src/shared/label.h b/src/shared/label.h index dda4d1c024..09e15e3c08 100644 --- a/src/shared/label.h +++ b/src/shared/label.h @@ -40,7 +40,7 @@ void label_free(const char *label); int label_get_create_label_from_exe(const char *exe, char **label); -int label_mkdir(const char *path, mode_t mode, bool apply); +int label_mkdir(const char *path, mode_t mode); void label_retest_selinux(void); diff --git a/src/shared/mkdir-label.c b/src/shared/mkdir-label.c new file mode 100644 index 0000000000..4ee6251bcd --- /dev/null +++ b/src/shared/mkdir-label.c @@ -0,0 +1,53 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + Copyright 2013 Kay Sievers + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include + +#include "label.h" +#include "util.h" +#include "path-util.h" +#include "mkdir.h" + +int mkdir_label(const char *path, mode_t mode) { + return label_mkdir(path, mode); +} + +int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid) { + return mkdir_safe_internal(path, mode, uid, gid, label_mkdir); +} + +int mkdir_parents_label(const char *path, mode_t mode) { + return mkdir_parents_internal(NULL, path, mode, label_mkdir); +} + +int mkdir_parents_prefix_label(const char *prefix, const char *path, mode_t mode) { + return mkdir_parents_internal(prefix, path, mode, label_mkdir); +} + +int mkdir_p_label(const char *path, mode_t mode) { + return mkdir_p_internal(NULL, path, mode, label_mkdir); +} diff --git a/src/shared/mkdir.c b/src/shared/mkdir.c index e21a0f3989..b7e5c6e67b 100644 --- a/src/shared/mkdir.c +++ b/src/shared/mkdir.c @@ -31,14 +31,10 @@ #include "path-util.h" #include "mkdir.h" -int mkdir_label(const char *path, mode_t mode) { - return label_mkdir(path, mode, true); -} - -static int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, bool apply) { +int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, mkdir_func_t _mkdir) { struct stat st; - if (label_mkdir(path, mode, apply) >= 0) + if (_mkdir(path, mode) >= 0) if (chmod_and_chown(path, mode, uid, gid) < 0) return -errno; @@ -60,10 +56,6 @@ int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid) { return mkdir_safe_internal(path, mode, uid, gid, false); } -int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid) { - return mkdir_safe_internal(path, mode, uid, gid, true); -} - static int is_dir(const char* path) { struct stat st; @@ -73,7 +65,7 @@ static int is_dir(const char* path) { return S_ISDIR(st.st_mode); } -static int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, bool apply) { +int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir) { const char *p, *e; int r; @@ -116,34 +108,26 @@ static int mkdir_parents_internal(const char *prefix, const char *path, mode_t m if (prefix && path_startswith(prefix, t)) continue; - r = label_mkdir(t, mode, apply); + r = _mkdir(t, mode); if (r < 0 && errno != EEXIST) return -errno; } } int mkdir_parents(const char *path, mode_t mode) { - return mkdir_parents_internal(NULL, path, mode, false); -} - -int mkdir_parents_label(const char *path, mode_t mode) { - return mkdir_parents_internal(NULL, path, mode, true); -} - -int mkdir_parents_prefix(const char *prefix, const char *path, mode_t mode) { - return mkdir_parents_internal(prefix, path, mode, true); + return mkdir_parents_internal(NULL, path, mode, mkdir); } -static int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, bool apply) { +int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir) { int r; /* Like mkdir -p */ - r = mkdir_parents_internal(prefix, path, mode, apply); + r = mkdir_parents_internal(prefix, path, mode, _mkdir); if (r < 0) return r; - r = label_mkdir(path, mode, apply); + r = _mkdir(path, mode); if (r < 0 && (errno != EEXIST || is_dir(path) <= 0)) return -errno; @@ -151,13 +135,9 @@ static int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, b } int mkdir_p(const char *path, mode_t mode) { - return mkdir_p_internal(NULL, path, mode, false); -} - -int mkdir_p_label(const char *path, mode_t mode) { - return mkdir_p_internal(NULL, path, mode, true); + return mkdir_p_internal(NULL, path, mode, mkdir); } int mkdir_p_prefix(const char *prefix, const char *path, mode_t mode) { - return mkdir_p_internal(prefix, path, mode, false); + return mkdir_p_internal(prefix, path, mode, mkdir); } diff --git a/src/shared/mkdir.h b/src/shared/mkdir.h index 3d39b2910f..5b34db4229 100644 --- a/src/shared/mkdir.h +++ b/src/shared/mkdir.h @@ -7,6 +7,7 @@ This file is part of systemd. Copyright 2010 Lennart Poettering + Copyright 2013 Kay Sievers systemd is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -24,17 +25,21 @@ #include -int mkdir_label(const char *path, mode_t mode); - int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid); -int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid); - int mkdir_parents(const char *path, mode_t mode); -int mkdir_parents_label(const char *path, mode_t mode); -int mkdir_parents_prefix(const char *prefix, const char *path, mode_t mode); - int mkdir_p(const char *path, mode_t mode); -int mkdir_p_label(const char *path, mode_t mode); int mkdir_p_prefix(const char *prefix, const char *path, mode_t mode); +/* selinux versions */ +int mkdir_label(const char *path, mode_t mode); +int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid); +int mkdir_parents_label(const char *path, mode_t mode); +int mkdir_p_label(const char *path, mode_t mode); +int mkdir_parents_prefix_label(const char *prefix, const char *path, mode_t mode); + +/* internally used */ +typedef int (*mkdir_func_t)(const char *pathname, mode_t mode); +int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, mkdir_func_t _mkdir); +int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir); +int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir); #endif -- cgit v1.2.1 From 6577c7cea72f19185ad999c223bcf663c010dc6f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 26 Jul 2013 16:09:25 +0200 Subject: core: allow setting RemainAfterExit= for transient services --- man/systemd-run.xml | 13 +++++++++++++ src/core/dbus-service.c | 17 ++++++++++++++++- src/run/run.c | 43 +++++++++++++++++++++++++++---------------- 3 files changed, 56 insertions(+), 17 deletions(-) diff --git a/man/systemd-run.xml b/man/systemd-run.xml index 3f777b5a4e..707d88d766 100644 --- a/man/systemd-run.xml +++ b/man/systemd-run.xml @@ -147,6 +147,19 @@ along with systemd; If not, see . instead of the system.slice. + + + + + After the service's process terminated keep + the service around until it is explicitly stopped. This is + useful to collect runtime information about the service after + it finished running. Also see + RemainAfterExit= in + systemd.service5. + + + All command-line arguments after the first non-option diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c index 8b157b5f3c..1a44e1fd1b 100644 --- a/src/core/dbus-service.c +++ b/src/core/dbus-service.c @@ -180,7 +180,22 @@ static int bus_service_set_transient_property( assert(s); assert(i); - if (streq(name, "ExecStart")) { + if (streq(name, "RemainAfterExit")) { + if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_BOOLEAN) + return -EINVAL; + + if (mode != UNIT_CHECK) { + dbus_bool_t b; + + dbus_message_iter_get_basic(i, &b); + + s->remain_after_exit = b; + unit_write_drop_in_private_format(UNIT(s), mode, name, "RemainAfterExit=%s\n", yes_no(b)); + } + + return 1; + + } else if (streq(name, "ExecStart")) { DBusMessageIter sub; unsigned n = 0; diff --git a/src/run/run.c b/src/run/run.c index e56a977de3..c1a0ffb13f 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -31,6 +31,7 @@ static bool arg_scope = false; static bool arg_user = false; +static bool arg_remain_after_exit = false; static const char *arg_unit = NULL; static const char *arg_description = NULL; static const char *arg_slice = NULL; @@ -39,13 +40,14 @@ static int help(void) { printf("%s [OPTIONS...] [COMMAND LINE...]\n\n" "Run the specified command in a transient scope or service unit.\n\n" - " -h --help Show this help\n" - " --version Show package version\n" - " --user Run as user unit\n" - " --scope Run this as scope rather than service\n" - " --unit=UNIT Run under the specified unit name\n" - " --description=TEXT Description for unit\n" - " --slice=SLICE Run in the specified slice\n", + " -h --help Show this help\n" + " --version Show package version\n" + " --user Run as user unit\n" + " --scope Run this as scope rather than service\n" + " --unit=UNIT Run under the specified unit name\n" + " --description=TEXT Description for unit\n" + " --slice=SLICE Run in the specified slice\n" + " -r --remain-after-exit Leave service around until explicitly stopped\n", program_invocation_short_name); return 0; @@ -63,14 +65,15 @@ static int parse_argv(int argc, char *argv[]) { }; static const struct option options[] = { - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, ARG_VERSION }, - { "user", no_argument, NULL, ARG_USER }, - { "scope", no_argument, NULL, ARG_SCOPE }, - { "unit", required_argument, NULL, ARG_UNIT }, - { "description", required_argument, NULL, ARG_DESCRIPTION }, - { "slice", required_argument, NULL, ARG_SLICE }, - { NULL, 0, NULL, 0 }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "user", no_argument, NULL, ARG_USER }, + { "scope", no_argument, NULL, ARG_SCOPE }, + { "unit", required_argument, NULL, ARG_UNIT }, + { "description", required_argument, NULL, ARG_DESCRIPTION }, + { "slice", required_argument, NULL, ARG_SLICE }, + { "remain-after-exit", required_argument, NULL, 'r' }, + { NULL, 0, NULL, 0 }, }; int c; @@ -78,7 +81,7 @@ static int parse_argv(int argc, char *argv[]) { assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "+h", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "+hr", options, NULL)) >= 0) { switch (c) { @@ -111,6 +114,10 @@ static int parse_argv(int argc, char *argv[]) { arg_slice = optarg; break; + case 'r': + arg_remain_after_exit = true; + break; + case '?': return -EINVAL; @@ -204,6 +211,10 @@ static int start_transient_service( if (r < 0) return r; + r = sd_bus_message_append(m, "(sv)", "RemainAfterExit", "b", arg_remain_after_exit); + if (r < 0) + return r; + r = sd_bus_message_open_container(m, 'r', "sv"); if (r < 0) return r; -- cgit v1.2.1 From 9ea9d4cf1656075559fcd6aeceb9530714c87d5b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 26 Jul 2013 16:34:52 +0200 Subject: systemctl: move "dump" command from systemctl to systemd-analyze It's an analysis command and its format is explicitly not covered by any stability guarantees, hence move away from systemctl and into systemd-analyze, minimizing the already large interface of systemctl a bit. This patch also adds auto-paging to the various systemd-analyze commands where that makes sense --- TODO | 2 - man/systemctl.xml | 9 ---- man/systemd-analyze.xml | 39 +++++++++++++- src/analyze/systemd-analyze.c | 120 +++++++++++++++++++++++++++++++----------- src/systemctl/systemctl.c | 111 +++++++++++++------------------------- 5 files changed, 165 insertions(+), 116 deletions(-) diff --git a/TODO b/TODO index 279ea60ebd..5294b74d30 100644 --- a/TODO +++ b/TODO @@ -90,8 +90,6 @@ Features: * move systemctl set-log-level to systemd-analyze? -* move "systemctl dump" to systemd-analyze - * add a fixed dbus path for "my own unit", "my own session", ... to PID1, logind, ... * service_coldplug() appears to reinstall the wrong stop timeout watch? diff --git a/man/systemctl.xml b/man/systemctl.xml index ee13a70fef..06c8c18465 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -993,16 +993,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service all pending jobs. - - dump - - Dump server status. This will output a (usually very - long) human readable manager status dump. Its format is - subject to change without notice and should not be parsed by - applications. - - list-dependencies NAME diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml index f5a9424248..905b44b6d9 100644 --- a/man/systemd-analyze.xml +++ b/man/systemd-analyze.xml @@ -82,6 +82,11 @@ dot PATTERN + + systemd-analyze + OPTIONS + dump + @@ -127,7 +132,7 @@ been started at what time, highlighting the time they spent on initialization. - systemd-analyze dot Generate + systemd-analyze dot generates textual dependency graph description in dot format for further processing with the GraphViz dot1 @@ -143,6 +148,12 @@ any of these patterns match either the origin or destination node. + systemd-analyze dump outputs + a (usually very long) human-readable serialization of + the complete server state. Its format is subject to + change without notice and should not be parsed by + applications. + If no command is passed, systemd-analyze time is implied. @@ -228,6 +239,14 @@ unless specified with a different unit, e.g. "50ms". + + + + + + Do not pipe output into a pager. + + @@ -256,6 +275,24 @@ $ eog targets.svg + + Environment + + + + $SYSTEMD_PAGER + + + Pager to use when is not + given; overrides $PAGER. Setting this to + an empty string or the value cat is + equivalent to passing + . + + + + + See Also diff --git a/src/analyze/systemd-analyze.c b/src/analyze/systemd-analyze.c index ffdcd14700..2748b3afc9 100644 --- a/src/analyze/systemd-analyze.c +++ b/src/analyze/systemd-analyze.c @@ -38,6 +38,7 @@ #include "unit-name.h" #include "special.h" #include "hashmap.h" +#include "pager.h" #define SCALE_X (0.1 / 1000.0) /* pixels per us */ #define SCALE_Y 20.0 @@ -67,8 +68,8 @@ static enum dot { } arg_dot = DEP_ALL; static char** arg_dot_from_patterns = NULL; static char** arg_dot_to_patterns = NULL; - -usec_t arg_fuzz = 0; +static usec_t arg_fuzz = 0; +static bool arg_no_pager = false; struct boot_times { usec_t firmware_time; @@ -83,6 +84,7 @@ struct boot_times { usec_t unitsload_start_time; usec_t unitsload_finish_time; }; + struct unit_times { char *name; usec_t ixt; @@ -92,6 +94,14 @@ struct unit_times { usec_t time; }; +static void pager_open_if_enabled(void) { + + if (arg_no_pager) + return; + + pager_open(false); +} + static int bus_get_uint64_property(DBusConnection *bus, const char *path, const char *interface, const char *property, uint64_t *val) { _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; DBusMessageIter iter, sub; @@ -590,7 +600,6 @@ static int analyze_plot(DBusConnection *bus) { svg_text("right", 400000, y, "Loading unit files"); y++; - svg("\n\n"); svg(""); @@ -600,7 +609,6 @@ static int analyze_plot(DBusConnection *bus) { return 0; } - static int list_dependencies_print(const char *name, unsigned int level, unsigned int branches, bool last, struct unit_times *times, struct boot_times *boot) { unsigned int i; @@ -914,6 +922,8 @@ static int analyze_critical_chain(DBusConnection *bus, char *names[]) { } unit_times_hashmap = h; + pager_open_if_enabled(); + puts("The time after the unit is active or started is printed after the \"@\" character.\n" "The time the unit takes to start is printed after the \"+\" character.\n"); @@ -921,9 +931,8 @@ static int analyze_critical_chain(DBusConnection *bus, char *names[]) { char **name; STRV_FOREACH(name, names) list_dependencies(bus, *name); - } else { + } else list_dependencies(bus, SPECIAL_DEFAULT_TARGET); - } hashmap_free(h); free_unit_times(times, (unsigned) n); @@ -941,6 +950,8 @@ static int analyze_blame(DBusConnection *bus) { qsort(times, n, sizeof(struct unit_times), compare_unit_time); + pager_open_if_enabled(); + for (i = 0; i < (unsigned) n; i++) { char ts[FORMAT_TIMESPAN_MAX]; @@ -1165,8 +1176,44 @@ static int dot(DBusConnection *bus, char* patterns[]) { return 0; } -static void analyze_help(void) -{ +static int dump(DBusConnection *bus, char **args) { + _cleanup_free_ DBusMessage *reply = NULL; + DBusError error; + int r; + const char *text; + + dbus_error_init(&error); + + pager_open_if_enabled(); + + r = bus_method_call_with_reply( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "Dump", + &reply, + NULL, + DBUS_TYPE_INVALID); + if (r < 0) + return r; + + if (!dbus_message_get_args(reply, &error, + DBUS_TYPE_STRING, &text, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse reply: %s", bus_error_message(&error)); + dbus_error_free(&error); + return -EIO; + } + + fputs(text, stdout); + return 0; +} + +static void analyze_help(void) { + + pager_open_if_enabled(); + printf("%s [OPTIONS...] {COMMAND} ...\n\n" "Process systemd profiling information\n\n" " -h --help Show this help\n" @@ -1181,13 +1228,15 @@ static void analyze_help(void) " --fuzz=TIMESPAN When printing the tree of the critical chain, print also\n" " services, which finished TIMESPAN earlier, than the\n" " latest in the branch. The unit of TIMESPAN is seconds\n" - " unless specified with a different unit, i.e. 50ms\n\n" + " unless specified with a different unit, i.e. 50ms\n" + " --no-pager Do not pipe output into a pager\n\n" "Commands:\n" " time Print time spent in the kernel before reaching userspace\n" " blame Print list of running units ordered by time to init\n" " critical-chain Print a tree of the time critical chain of units\n" " plot Output SVG graphic showing service initialization\n" - " dot Dump dependency graph (in dot(1) format)\n\n", + " dot Output dependency graph in dot(1) format\n" + " dump Output state serialization of service manager\n", program_invocation_short_name); /* When updating this list, including descriptions, apply @@ -1195,8 +1244,7 @@ static void analyze_help(void) * shell-completion/systemd-zsh-completion.zsh too. */ } -static int parse_argv(int argc, char *argv[]) -{ +static int parse_argv(int argc, char *argv[]) { int r; enum { @@ -1207,20 +1255,22 @@ static int parse_argv(int argc, char *argv[]) ARG_SYSTEM, ARG_DOT_FROM_PATTERN, ARG_DOT_TO_PATTERN, - ARG_FUZZ + ARG_FUZZ, + ARG_NO_PAGER }; static const struct option options[] = { - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, ARG_VERSION }, - { "order", no_argument, NULL, ARG_ORDER }, - { "require", no_argument, NULL, ARG_REQUIRE }, - { "user", no_argument, NULL, ARG_USER }, - { "system", no_argument, NULL, ARG_SYSTEM }, - { "from-pattern", required_argument, NULL, ARG_DOT_FROM_PATTERN}, - { "to-pattern", required_argument, NULL, ARG_DOT_TO_PATTERN }, - { "fuzz", required_argument, NULL, ARG_FUZZ }, - { NULL, 0, NULL, 0 } + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "order", no_argument, NULL, ARG_ORDER }, + { "require", no_argument, NULL, ARG_REQUIRE }, + { "user", no_argument, NULL, ARG_USER }, + { "system", no_argument, NULL, ARG_SYSTEM }, + { "from-pattern", required_argument, NULL, ARG_DOT_FROM_PATTERN }, + { "to-pattern", required_argument, NULL, ARG_DOT_TO_PATTERN }, + { "fuzz", required_argument, NULL, ARG_FUZZ }, + { "no-pager", no_argument, NULL, ARG_NO_PAGER }, + { NULL, 0, NULL, 0 } }; assert(argc >= 0); @@ -1271,6 +1321,10 @@ static int parse_argv(int argc, char *argv[]) return r; break; + case ARG_NO_PAGER: + arg_no_pager = true; + break; + case -1: return 1; @@ -1293,14 +1347,14 @@ int main(int argc, char *argv[]) { log_open(); r = parse_argv(argc, argv); - if (r < 0) - return EXIT_FAILURE; - else if (r <= 0) - return EXIT_SUCCESS; + if (r <= 0) + goto finish; bus = dbus_bus_get(arg_scope == UNIT_FILE_SYSTEM ? DBUS_BUS_SYSTEM : DBUS_BUS_SESSION, NULL); - if (!bus) - return EXIT_FAILURE; + if (!bus) { + r = -EIO; + goto finish; + } if (!argv[optind] || streq(argv[optind], "time")) r = analyze_time(bus); @@ -1312,12 +1366,18 @@ int main(int argc, char *argv[]) { r = analyze_plot(bus); else if (streq(argv[optind], "dot")) r = dot(bus, argv+optind+1); + else if (streq(argv[optind], "dump")) + r = dump(bus, argv+optind+1); else log_error("Unknown operation '%s'.", argv[optind]); + dbus_connection_unref(bus); + +finish: + pager_close(); + strv_free(arg_dot_from_patterns); strv_free(arg_dot_to_patterns); - dbus_connection_unref(bus); return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 9f47b2cf7c..4e33a4182f 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -3797,40 +3797,6 @@ static int set_property(DBusConnection *bus, char **args) { return 0; } -static int dump(DBusConnection *bus, char **args) { - _cleanup_free_ DBusMessage *reply = NULL; - DBusError error; - int r; - const char *text; - - dbus_error_init(&error); - - pager_open_if_enabled(); - - r = bus_method_call_with_reply( - bus, - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - "Dump", - &reply, - NULL, - DBUS_TYPE_INVALID); - if (r < 0) - return r; - - if (!dbus_message_get_args(reply, &error, - DBUS_TYPE_STRING, &text, - DBUS_TYPE_INVALID)) { - log_error("Failed to parse reply: %s", bus_error_message(&error)); - dbus_error_free(&error); - return -EIO; - } - - fputs(text, stdout); - return 0; -} - static int snapshot(DBusConnection *bus, char **args) { _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; DBusError error; @@ -4787,8 +4753,6 @@ static int systemctl_help(void) { "Job Commands:\n" " list-jobs List jobs\n" " cancel [JOB...] Cancel all, one, or more jobs\n\n" - "Status Commands:\n" - " dump Dump server status\n\n" "Snapshot Commands:\n" " snapshot [NAME] Create a snapshot\n" " delete [NAME...] Remove one or more snapshots\n\n" @@ -4927,43 +4891,43 @@ static int systemctl_parse_argv(int argc, char *argv[]) { }; static const struct option options[] = { - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, ARG_VERSION }, - { "type", required_argument, NULL, 't' }, - { "property", required_argument, NULL, 'p' }, - { "all", no_argument, NULL, 'a' }, - { "reverse", no_argument, NULL, ARG_REVERSE }, - { "after", no_argument, NULL, ARG_AFTER }, - { "before", no_argument, NULL, ARG_BEFORE }, - { "show-types", no_argument, NULL, ARG_SHOW_TYPES }, - { "failed", no_argument, NULL, ARG_FAILED }, - { "full", no_argument, NULL, 'l' }, - { "fail", no_argument, NULL, ARG_FAIL }, - { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, - { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, - { "ignore-inhibitors", no_argument, NULL, 'i' }, - { "user", no_argument, NULL, ARG_USER }, - { "system", no_argument, NULL, ARG_SYSTEM }, - { "global", no_argument, NULL, ARG_GLOBAL }, - { "no-block", no_argument, NULL, ARG_NO_BLOCK }, - { "no-legend", no_argument, NULL, ARG_NO_LEGEND }, - { "no-pager", no_argument, NULL, ARG_NO_PAGER }, - { "no-wall", no_argument, NULL, ARG_NO_WALL }, - { "quiet", no_argument, NULL, 'q' }, - { "root", required_argument, NULL, ARG_ROOT }, - { "force", no_argument, NULL, ARG_FORCE }, - { "no-reload", no_argument, NULL, ARG_NO_RELOAD }, - { "kill-who", required_argument, NULL, ARG_KILL_WHO }, - { "signal", required_argument, NULL, 's' }, - { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD }, - { "host", required_argument, NULL, 'H' }, - { "privileged",no_argument, NULL, 'P' }, - { "runtime", no_argument, NULL, ARG_RUNTIME }, - { "lines", required_argument, NULL, 'n' }, - { "output", required_argument, NULL, 'o' }, - { "plain", no_argument, NULL, ARG_PLAIN }, - { "state", required_argument, NULL, ARG_STATE }, - { NULL, 0, NULL, 0 } + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "type", required_argument, NULL, 't' }, + { "property", required_argument, NULL, 'p' }, + { "all", no_argument, NULL, 'a' }, + { "reverse", no_argument, NULL, ARG_REVERSE }, + { "after", no_argument, NULL, ARG_AFTER }, + { "before", no_argument, NULL, ARG_BEFORE }, + { "show-types", no_argument, NULL, ARG_SHOW_TYPES }, + { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */ + { "full", no_argument, NULL, 'l' }, + { "fail", no_argument, NULL, ARG_FAIL }, + { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, + { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, + { "ignore-inhibitors", no_argument, NULL, 'i' }, + { "user", no_argument, NULL, ARG_USER }, + { "system", no_argument, NULL, ARG_SYSTEM }, + { "global", no_argument, NULL, ARG_GLOBAL }, + { "no-block", no_argument, NULL, ARG_NO_BLOCK }, + { "no-legend", no_argument, NULL, ARG_NO_LEGEND }, + { "no-pager", no_argument, NULL, ARG_NO_PAGER }, + { "no-wall", no_argument, NULL, ARG_NO_WALL }, + { "quiet", no_argument, NULL, 'q' }, + { "root", required_argument, NULL, ARG_ROOT }, + { "force", no_argument, NULL, ARG_FORCE }, + { "no-reload", no_argument, NULL, ARG_NO_RELOAD }, + { "kill-who", required_argument, NULL, ARG_KILL_WHO }, + { "signal", required_argument, NULL, 's' }, + { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD }, + { "host", required_argument, NULL, 'H' }, + { "privileged", no_argument, NULL, 'P' }, + { "runtime", no_argument, NULL, ARG_RUNTIME }, + { "lines", required_argument, NULL, 'n' }, + { "output", required_argument, NULL, 'o' }, + { "plain", no_argument, NULL, ARG_PLAIN }, + { "state", required_argument, NULL, ARG_STATE }, + { NULL, 0, NULL, 0 } }; int c; @@ -5829,7 +5793,6 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError { "show", MORE, 1, show }, { "status", MORE, 1, show }, { "help", MORE, 2, show }, - { "dump", EQUAL, 1, dump }, { "snapshot", LESS, 2, snapshot }, { "delete", MORE, 2, delete_snapshot }, { "daemon-reload", EQUAL, 1, daemon_reload }, -- cgit v1.2.1 From a65615ca5d78be0dcd7d9c9b4a663fa75f758606 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 26 Jul 2013 16:59:55 +0200 Subject: systemctl: move set-log-level to systemd-analyze "systemctl set-log-level" is a command for analysis and tracing hence "systemd-analyze" should be the better home for it, thus allowing us to make the overly large "systemctl" a bit smaller. --- TODO | 6 ++--- man/systemctl.xml | 13 ---------- man/systemd-analyze.xml | 20 ++++++++++++++-- src/analyze/systemd-analyze.c | 56 +++++++++++++++++++++++++++++++++++++++++++ src/systemctl/systemctl.c | 49 +------------------------------------ 5 files changed, 77 insertions(+), 67 deletions(-) diff --git a/TODO b/TODO index 5294b74d30..35ce46ff40 100644 --- a/TODO +++ b/TODO @@ -51,6 +51,8 @@ CGroup Rework Completion: Features: +* remove systemctl load-unit + * journalctl: instead --after-cursor= maybe have a --cursor=XYZ+1 syntax? * given that logind/machined now let PID 1 do all nasty work we can @@ -88,8 +90,6 @@ Features: * load .d/*.conf dropins for device units -* move systemctl set-log-level to systemd-analyze? - * add a fixed dbus path for "my own unit", "my own session", ... to PID1, logind, ... * service_coldplug() appears to reinstall the wrong stop timeout watch? @@ -123,8 +123,6 @@ Features: * something pulls in pcre as so dep into our daemons such as hostnamed. -* cgroup-agent: downgrade error messages - * document systemd-journal-flush.service properly * change systemd-journal-flush into a service that stays around during diff --git a/man/systemctl.xml b/man/systemctl.xml index 06c8c18465..45955da179 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -539,19 +539,6 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service - - set-log-level LEVEL - - - Change current log level of the - systemd daemon to - LEVEL (accepts the same values - as described in - systemd1). - - - - start NAME... diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml index 905b44b6d9..a8adf87713 100644 --- a/man/systemd-analyze.xml +++ b/man/systemd-analyze.xml @@ -81,20 +81,28 @@ OPTIONS dot PATTERN + > file.dot systemd-analyze OPTIONS dump + + systemd-analyze + OPTIONS + set-log-level + LEVEL + Description systemd-analyze may be used - to determine system boot-up performance of the current - boot. + to determine system boot-up performance statistics and + retrieve other state and tracing information from the + system and service manager. systemd-analyze time prints the time spent in the kernel before @@ -154,6 +162,14 @@ change without notice and should not be parsed by applications. + systemd-analyze set-log-level + LEVEL changes the + current log level of the systemd + daemon to LEVEL (accepts + the same values as + described in + systemd1). + If no command is passed, systemd-analyze time is implied. diff --git a/src/analyze/systemd-analyze.c b/src/analyze/systemd-analyze.c index 2748b3afc9..27d063c548 100644 --- a/src/analyze/systemd-analyze.c +++ b/src/analyze/systemd-analyze.c @@ -1184,6 +1184,11 @@ static int dump(DBusConnection *bus, char **args) { dbus_error_init(&error); + if (!strv_isempty(args)) { + log_error("Too many arguments."); + return -E2BIG; + } + pager_open_if_enabled(); r = bus_method_call_with_reply( @@ -1210,6 +1215,54 @@ static int dump(DBusConnection *bus, char **args) { return 0; } +static int set_log_level(DBusConnection *bus, char **args) { + _cleanup_dbus_error_free_ DBusError error; + _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL; + DBusMessageIter iter, sub; + const char* property = "LogLevel"; + const char* interface = "org.freedesktop.systemd1.Manager"; + const char* value; + + assert(bus); + assert(args); + + if (strv_length(args) != 1) { + log_error("This command expects one argument only."); + return -E2BIG; + } + + value = args[0]; + dbus_error_init(&error); + + m = dbus_message_new_method_call("org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.DBus.Properties", + "Set"); + if (!m) + return log_oom(); + + dbus_message_iter_init_append(m, &iter); + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &interface) || + !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &property) || + !dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "s", &sub)) + return log_oom(); + + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &value)) + return log_oom(); + + if (!dbus_message_iter_close_container(&iter, &sub)) + return log_oom(); + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + return -EIO; + } + + return 0; +} + static void analyze_help(void) { pager_open_if_enabled(); @@ -1236,6 +1289,7 @@ static void analyze_help(void) { " critical-chain Print a tree of the time critical chain of units\n" " plot Output SVG graphic showing service initialization\n" " dot Output dependency graph in dot(1) format\n" + " set-log-level LEVEL Set logging threshold for systemd\n" " dump Output state serialization of service manager\n", program_invocation_short_name); @@ -1368,6 +1422,8 @@ int main(int argc, char *argv[]) { r = dot(bus, argv+optind+1); else if (streq(argv[optind], "dump")) r = dump(bus, argv+optind+1); + else if (streq(argv[optind], "set-log-level")) + r = set_log_level(bus, argv+optind+1); else log_error("Unknown operation '%s'.", argv[optind]); diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 4e33a4182f..08981a8002 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -4527,51 +4527,6 @@ finish: return r; } -static int set_log_level(DBusConnection *bus, char **args) { - _cleanup_dbus_error_free_ DBusError error; - _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL; - DBusMessageIter iter, sub; - const char* property = "LogLevel"; - const char* interface = "org.freedesktop.systemd1.Manager"; - const char* value; - - assert(bus); - assert(args); - - value = args[1]; - dbus_error_init(&error); - - m = dbus_message_new_method_call("org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.DBus.Properties", - "Set"); - if (!m) - return log_oom(); - - dbus_message_iter_init_append(m, &iter); - - if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &interface) || - !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &property) || - !dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "s", &sub)) - return log_oom(); - - if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &value)) { - dbus_message_iter_abandon_container(&iter, &sub); - return log_oom(); - } - - if (!dbus_message_iter_close_container(&iter, &sub)) - return log_oom(); - - reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); - if (!reply) { - log_error("Failed to issue method call: %s", bus_error_message(&error)); - return -EIO; - } - - return 0; -} - static int unit_is_enabled(DBusConnection *bus, char **args) { _cleanup_dbus_error_free_ DBusError error; int r; @@ -4759,8 +4714,7 @@ static int systemctl_help(void) { "Environment Commands:\n" " show-environment Dump environment\n" " set-environment [NAME=VALUE...] Set one or more environment variables\n" - " unset-environment [NAME...] Unset one or more environment variables\n" - " set-log-level LEVEL Set logging threshold for systemd\n\n" + " unset-environment [NAME...] Unset one or more environment variables\n\n" "Manager Lifecycle Commands:\n" " daemon-reload Reload systemd manager configuration\n" " daemon-reexec Reexecute systemd manager\n\n" @@ -5824,7 +5778,6 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError { "list-dependencies", LESS, 2, list_dependencies }, { "set-default", EQUAL, 2, enable_unit }, { "get-default", LESS, 1, get_default }, - { "set-log-level", EQUAL, 2, set_log_level }, { "set-property", MORE, 3, set_property }, }; -- cgit v1.2.1 From 223ab9345d70e2ea8498b96ff07ee73c25ad18b4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 26 Jul 2013 17:05:43 +0200 Subject: systemctl: remove "load" command "systemctl load" has always been racy since the GC could hit any time, before making use of the loaded unit. Very recent systemd will run GC immeidately after all unit state changes which has the effect that the the effect of "systemctl load" is completely gone now, so let's remove the support for it in "systemctl" for good. --- man/systemctl.xml | 22 ---------------------- src/systemctl/systemctl.c | 31 ------------------------------- 2 files changed, 53 deletions(-) diff --git a/man/systemctl.xml b/man/systemctl.xml index 45955da179..2a23655cfe 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -942,28 +942,6 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service - - load NAME... - - - Load one or more units specified on the command - line. This will simply load their configuration from disk, - but not start them. To start them, you need to use the - start command which will implicitly load - a unit that has not been loaded yet. Note that systemd - garbage collects loaded units that are not active or - referenced by an active unit. This means that units loaded - this way will usually not stay loaded for long. Also note - that this command cannot be used to reload unit - configuration. Use the daemon-reload - command for that. All in all, this command is of little use - except for debugging. - - This command should not be confused with the - daemon-reload or - reload. - - list-jobs diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 08981a8002..60dee5dc61 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -1388,36 +1388,6 @@ static int list_jobs(DBusConnection *bus, char **args) { return 0; } -static int load_unit(DBusConnection *bus, char **args) { - char **name; - - assert(args); - - STRV_FOREACH(name, args+1) { - _cleanup_free_ char *n = NULL; - int r; - - n = unit_name_mangle(*name); - if (!n) - return log_oom(); - - r = bus_method_call_with_reply( - bus, - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - "LoadUnit", - NULL, - NULL, - DBUS_TYPE_STRING, &n, - DBUS_TYPE_INVALID); - if (r < 0) - return r; - } - - return 0; -} - static int cancel_job(DBusConnection *bus, char **args) { char **name; @@ -4687,7 +4657,6 @@ static int systemctl_help(void) { " help [NAME...|PID...] Show manual for one or more units\n" " reset-failed [NAME...] Reset failed state for all, one, or more\n" " units\n" - " load [NAME...] Load one or more units\n" " list-dependencies [NAME] Recursively show units which are required\n" " or wanted by this unit or by which this\n" " unit is required or wanted\n\n" -- cgit v1.2.1 From a521ae4a5657f5b779b3ffd7771cfba0ee4b1968 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 26 Jul 2013 17:11:41 +0200 Subject: systemctl: rearrange --help output a bit --- src/systemctl/systemctl.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 60dee5dc61..5a4d80c4d6 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -4594,7 +4594,7 @@ static int systemctl_help(void) { " -h --help Show this help\n" " --version Show package version\n" " -t --type=TYPE List only units of a particular type\n" - " --state=STATE Show only units with particular LOAD or SUB or ACTIVE state\n" + " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n" " -p --property=NAME Show only properties by this name\n" " -a --all Show all loaded units/properties, including dead/empty\n" " ones. To list all units installed on the system, use\n" @@ -4603,10 +4603,11 @@ static int systemctl_help(void) { " -l --full Don't ellipsize unit names on output\n" " --fail When queueing a new job, fail if conflicting jobs are\n" " pending\n" - " --irreversible Create jobs which cannot be implicitly cancelled\n" - " --show-types When showing sockets, explicitly show their type\n" + " --irreversible When queueing a new job, make sure it cannot be implicitly\n" + " cancelled\n" " --ignore-dependencies\n" " When queueing a new job, ignore all its dependencies\n" + " --show-types When showing sockets, explicitly show their type\n" " -i --ignore-inhibitors\n" " When shutting down or sleeping, ignore inhibitors\n" " --kill-who=WHO Who to send signal to\n" @@ -4626,11 +4627,11 @@ static int systemctl_help(void) { " --system Connect to system manager\n" " --user Connect to user service manager\n" " --global Enable/disable unit files globally\n" + " --runtime Enable unit files only temporarily until next reboot\n" " -f --force When enabling unit files, override existing symlinks\n" " When shutting down, execute action immediately\n" " --root=PATH Enable unit files in the specified root directory\n" - " --runtime Enable unit files only temporarily until next reboot\n" - " -n --lines=INTEGER Journal entries to show\n" + " -n --lines=INTEGER Numer of journal entries to show\n" " -o --output=STRING Change journal output mode (short, short-monotonic,\n" " verbose, export, json, json-pretty, json-sse, cat)\n\n" "Unit Commands:\n" @@ -4667,13 +4668,13 @@ static int systemctl_help(void) { " reenable [NAME...] Reenable one or more unit files\n" " preset [NAME...] Enable/disable one or more unit files\n" " based on preset configuration\n" + " is-enabled [NAME...] Check whether unit files are enabled\n\n" " mask [NAME...] Mask one or more units\n" " unmask [NAME...] Unmask one or more units\n" " link [PATH...] Link one or more units files into\n" " the search path\n" " get-default Get the name of the default target\n" " set-default NAME Set the default target\n" - " is-enabled [NAME...] Check whether unit files are enabled\n\n" "Job Commands:\n" " list-jobs List jobs\n" " cancel [JOB...] Cancel all, one, or more jobs\n\n" @@ -5695,7 +5696,6 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError { "list-sockets", LESS, 1, list_sockets }, { "list-jobs", EQUAL, 1, list_jobs }, { "clear-jobs", EQUAL, 1, daemon_reload }, - { "load", MORE, 2, load_unit }, { "cancel", MORE, 2, cancel_job }, { "start", MORE, 2, start_unit }, { "stop", MORE, 2, start_unit }, -- cgit v1.2.1 From b59f043c3d0c84b578cf170b255bb6ac5670beeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 25 Jul 2013 18:55:08 -0400 Subject: systemd-python: use modern C --- src/python-systemd/_reader.c | 49 +++++++++----------------------------------- 1 file changed, 10 insertions(+), 39 deletions(-) diff --git a/src/python-systemd/_reader.c b/src/python-systemd/_reader.c index 6ac2f20491..98a99aa0ab 100644 --- a/src/python-systemd/_reader.c +++ b/src/python-systemd/_reader.c @@ -1046,48 +1046,20 @@ static PyMethodDef Reader_methods[] = { static PyTypeObject ReaderType = { PyVarObject_HEAD_INIT(NULL, 0) - "_reader._Reader", /*tp_name*/ - sizeof(Reader), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)Reader_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - Reader__doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - Reader_methods, /* tp_methods */ - 0, /* tp_members */ - Reader_getsetters, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc) Reader_init, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ + .tp_name = "_reader._Reader", + .tp_basicsize = sizeof(Reader), + .tp_dealloc = (destructor) Reader_dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .tp_doc = Reader__doc__, + .tp_methods = Reader_methods, + .tp_getset = Reader_getsetters, + .tp_init = (initproc) Reader_init, + .tp_new = PyType_GenericNew, }; static PyMethodDef methods[] = { { "_get_catalog", get_catalog, METH_VARARGS, get_catalog__doc__}, - { NULL, NULL, 0, NULL } /* Sentinel */ + {} /* Sentinel */ }; #if PY_MAJOR_VERSION >= 3 @@ -1097,7 +1069,6 @@ static PyModuleDef module = { module__doc__, -1, methods, - NULL, NULL, NULL, NULL }; #endif -- cgit v1.2.1 From a6c0b31d509f76023d8efbcd5e912863c8fb254c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 26 Jul 2013 10:08:15 -0400 Subject: build-sys: use pkg-config for python compilation flags Python 2.7, and 3.2 and higher support querying compilation flags through pkg-config. This makes python support follow rules similar to various other optional compilation-time libraries. New flags are called PYTHON_DEVEL_CFLAGS and PYTHON_DEVEL_LIBS, because PYTHON (without _DEVEL), is already used for the python binary name, and things would be confusing if the same prefix was used for two things. configure has --disable-python-devel to disable python modules. One advantage is that CFLAGS for modules gets smaller: - -I/usr/include/python3.3m -I/usr/include/python3.3m -Wno-unused-result -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv + -I/usr/include/python3.3m as does LIBS: - -lpthread -ldl -lutil -lm -lpython3.3m + -lpython3.3m Support for Python 2.6 is removed, but can be easily restored by using PYTHON_DEVEL_CFLAGS="$(python2.6-config --cflags)", etc., as ./configure parameters. https://bugs.freedesktop.org/show_bug.cgi?id=57800 --- Makefile.am | 20 ++++++++++---------- configure.ac | 35 ++++++++++++++++------------------- 2 files changed, 26 insertions(+), 29 deletions(-) diff --git a/Makefile.am b/Makefile.am index 8ac1d8d0f3..7b4753d300 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3905,7 +3905,7 @@ _journal_la_SOURCES = \ _journal_la_CFLAGS = \ $(AM_CFLAGS) \ -fvisibility=default \ - $(PYTHON_CFLAGS) + $(PYTHON_DEVEL_CFLAGS) _journal_la_LDFLAGS = \ $(AM_LDFLAGS) \ @@ -3914,7 +3914,7 @@ _journal_la_LDFLAGS = \ -avoid-version _journal_la_LIBADD = \ - $(PYTHON_LIBS) \ + $(PYTHON_DEVEL_LIBS) \ libsystemd-journal.la id128_la_SOURCES = \ @@ -3926,7 +3926,7 @@ id128_la_SOURCES = \ id128_la_CFLAGS = \ $(AM_CFLAGS) \ -fvisibility=default \ - $(PYTHON_CFLAGS) \ + $(PYTHON_DEVEL_CFLAGS) \ -I$(top_builddir)/src/python-systemd id128_la_LDFLAGS = \ @@ -3936,7 +3936,7 @@ id128_la_LDFLAGS = \ -avoid-version id128_la_LIBADD = \ - $(PYTHON_LIBS) \ + $(PYTHON_DEVEL_LIBS) \ libsystemd-id128.la _daemon_la_SOURCES = \ @@ -3947,7 +3947,7 @@ _daemon_la_SOURCES = \ _daemon_la_CFLAGS = \ $(AM_CFLAGS) \ -fvisibility=default \ - $(PYTHON_CFLAGS) \ + $(PYTHON_DEVEL_CFLAGS) \ -I$(top_builddir)/src/python-systemd _daemon_la_LDFLAGS = \ @@ -3957,7 +3957,7 @@ _daemon_la_LDFLAGS = \ -avoid-version _daemon_la_LIBADD = \ - $(PYTHON_LIBS) \ + $(PYTHON_DEVEL_LIBS) \ libsystemd-daemon.la _reader_la_SOURCES = \ @@ -3968,7 +3968,7 @@ _reader_la_SOURCES = \ _reader_la_CFLAGS = \ $(AM_CFLAGS) \ -fvisibility=default \ - $(PYTHON_CFLAGS) + $(PYTHON_DEVEL_CFLAGS) _reader_la_LDFLAGS = \ $(AM_LDFLAGS) \ @@ -3977,7 +3977,7 @@ _reader_la_LDFLAGS = \ -avoid-version _reader_la_LIBADD = \ - $(PYTHON_LIBS) \ + $(PYTHON_DEVEL_LIBS) \ libsystemd-journal.la \ libsystemd-id128.la \ libsystemd-shared.la \ @@ -3991,7 +3991,7 @@ login_la_SOURCES = \ login_la_CFLAGS = \ $(AM_CFLAGS) \ -fvisibility=default \ - $(PYTHON_CFLAGS) + $(PYTHON_DEVEL_CFLAGS) login_la_LDFLAGS = \ $(AM_LDFLAGS) \ @@ -4000,7 +4000,7 @@ login_la_LDFLAGS = \ -avoid-version login_la_LIBADD = \ - $(PYTHON_LIBS) \ + $(PYTHON_DEVEL_LIBS) \ libsystemd-journal.la \ libsystemd-login.la \ libsystemd-shared.la \ diff --git a/configure.ac b/configure.ac index 759073a2c1..4e8c573ab3 100644 --- a/configure.ac +++ b/configure.ac @@ -144,11 +144,10 @@ CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [\ --param=ssp-buffer-size=4]) AC_SUBST([OUR_CFLAGS], $with_cflags) -AS_CASE([$CFLAGS], [*-O[[12345g\ ]]*], [ - CC_CHECK_FLAGS_APPEND([with_cppflags], [CPPFLAGS], [\ - -Wp,-D_FORTIFY_SOURCE=2])], [ - python_extra_cflags=-Wp,-U_FORTIFY_SOURCE - AC_MSG_RESULT([skipping -D_FORTIFY_SOURCE, optimization not enabled])]) +AS_CASE([$CFLAGS], [*-O[[12345g\ ]]*], + [CC_CHECK_FLAGS_APPEND([with_cppflags], [CPPFLAGS], [\ + -Wp,-D_FORTIFY_SOURCE=2])], + [AC_MSG_RESULT([skipping -D_FORTIFY_SOURCE, optimization not enabled])]) AC_SUBST([OUR_CPPFLAGS], $with_cppflags) CC_CHECK_FLAGS_APPEND([with_ldflags], [LDFLAGS], [\ @@ -162,8 +161,6 @@ AC_SUBST([OUR_LDFLAGS], $with_ldflags) # ------------------------------------------------------------------------------ # we use python to build the man page index, and for systemd-python have_python=no -have_python_devel=no - AC_ARG_WITH([python], [AS_HELP_STRING([--without-python], [Disable building the man page index and systemd-python (default: test)])]) @@ -178,16 +175,16 @@ AS_IF([test "x$PYTHON_BINARY" = "x"], [PYTHON_BINARY=/usr/bin/python])]) AC_ARG_VAR(PYTHON_BINARY, [Python binary used to launch installed scripts]) -AS_IF([test "x$with_python" != "xno"], [ - AC_PATH_PROG(PYTHON_CONFIG, python${PYTHON_VERSION}-config) - AS_IF([test -n "$PYTHON_CONFIG"], [ - have_python_devel=yes - PYTHON_CFLAGS="$($PYTHON_CONFIG --cflags) $python_extra_cflags" - PYTHON_LIBS="$($PYTHON_CONFIG --ldflags)" - AC_SUBST(PYTHON_CFLAGS) - AC_SUBST(PYTHON_LIBS) - AC_PATH_PROGS(SPHINX_BUILD, sphinx-build-${PYTHON_VERSION} sphinx-build) - ]) +have_python_devel=no +AC_ARG_ENABLE(python_devel, AS_HELP_STRING([--disable-python-devel], [Do not build python modules])) +AS_IF([test "x$enable_python_devel" != "xno"], [ + PKG_CHECK_MODULES([PYTHON_DEVEL], [python-${PYTHON_VERSION}], + [have_python_devel=yes], + [PKG_CHECK_MODULES([PYTHON_DEVEL], [python], + [have_python_devel=yes], + [have_python_devel=no])]) + AS_IF([test "x$have_python_devel" = xno -a "x$enable_python_devel" = xyes], + [AC_MSG_ERROR([*** python-devel support requested but libraries not found])]) ]) AM_CONDITIONAL([HAVE_PYTHON_DEVEL], [test "$have_python_devel" = "yes"]) @@ -1039,6 +1036,6 @@ AC_MSG_RESULT([ CFLAGS: ${OUR_CFLAGS} ${CFLAGS} CPPFLAGS: ${OUR_CPPFLAGS} ${CPPFLAGS} LDFLAGS: ${OUR_LDFLAGS} ${LDFLAGS} - PYTHON_CFLAGS: ${PYTHON_CFLAGS} - PYTHON_LIBS: ${PYTHON_LIBS} + PYTHON_CFLAGS: ${PYTHON_DEVEL_CFLAGS} + PYTHON_LIBS: ${PYTHON_DEVEL_LIBS} ]) -- cgit v1.2.1 From fd587c876d480863d56bbbdc5e9fcf7e735d98f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 26 Jul 2013 11:02:27 -0400 Subject: systemd-python: fix gcc warning src/python-systemd/_reader.c: In function Reader_get_catalog: src/python-systemd/_reader.c:912:53: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] assert(mid_len > l); ^ --- src/python-systemd/_reader.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/python-systemd/_reader.c b/src/python-systemd/_reader.c index 98a99aa0ab..a678f69318 100644 --- a/src/python-systemd/_reader.c +++ b/src/python-systemd/_reader.c @@ -908,9 +908,9 @@ static PyObject* Reader_get_catalog(Reader *self, PyObject *args) r = sd_journal_get_data(self->j, "MESSAGE_ID", &mid, &mid_len); if (r == 0) { - const int l = sizeof("MESSAGE_ID"); + const size_t l = sizeof("MESSAGE_ID"); assert(mid_len > l); - PyErr_Format(PyExc_KeyError, "%.*s", (int) mid_len - l, + PyErr_Format(PyExc_KeyError, "%.*s", (int) (mid_len - l), (const char*) mid + l); } else if (r == -ENOENT) PyErr_SetString(PyExc_IndexError, "no MESSAGE_ID field"); -- cgit v1.2.1 From cba38758b4d49c6fe7c2f0eea255e11ee9df23eb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 26 Jul 2013 17:32:19 +0200 Subject: logind: update state file after generating the session fifo, not before https://bugs.freedesktop.org/show_bug.cgi?id=67273 --- src/login/logind-dbus.c | 7 ++++++- src/login/logind-session-dbus.c | 4 ++++ src/machine/machined-dbus.c | 3 ++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 39af637d1b..b5e975a9f7 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -643,6 +643,10 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message) { session->create_message = dbus_message_ref(message); + /* Now, let's wait until the slice unit and stuff got + * created. We send the reply back from + * session_send_create_reply().*/ + return 0; fail: @@ -2356,7 +2360,6 @@ DBusHandlerResult bus_message_filter( if (streq_ptr(path, s->scope_job)) { free(s->scope_job); s->scope_job = NULL; - session_save(s); if (s->started) { if (streq(result, "done")) @@ -2366,6 +2369,8 @@ DBusHandlerResult bus_message_filter( session_send_create_reply(s, &error); } } + + session_save(s); } session_add_to_gc_queue(s); diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c index 62b9ffd52a..210f7564da 100644 --- a/src/login/logind-session-dbus.c +++ b/src/login/logind-session-dbus.c @@ -535,6 +535,10 @@ int session_send_create_reply(Session *s, DBusError *error) { if (!s->create_message) return 0; + /* This is called after the session scope was successfully + * created, and finishes where bus_manager_create_session() + * left off. */ + if (error) { DBusError buffer; diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c index 1e8bc609a3..6c4d50b3a2 100644 --- a/src/machine/machined-dbus.c +++ b/src/machine/machined-dbus.c @@ -543,7 +543,6 @@ DBusHandlerResult bus_message_filter( if (streq_ptr(path, mm->scope_job)) { free(mm->scope_job); mm->scope_job = NULL; - machine_save(mm); if (mm->started) { if (streq(result, "done")) @@ -553,6 +552,8 @@ DBusHandlerResult bus_message_filter( machine_send_create_reply(mm, &error); } } + + machine_save(mm); } machine_add_to_gc_queue(mm); -- cgit v1.2.1 From 68fee104e630eb19f04b8196a83c14c2c9c469e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 19 Jul 2013 04:02:50 -0400 Subject: journalctl: use _COMM= match for scripts In case of scripts, _EXE is set to the interpreter name, and _COMM is set based on the file name. Add a match for _COMM, and _EXE if the interpreter is not a link (e.g. for yum, the interpreter is /usr/bin/python, but it is a link to /usr/bin/python2, which in turn is a link to /usr/bin/python2.7, at least on Fedora, so we end up with _EXE=/usr/bin/python2.7). I don't think that such link chasing makes sense, because the final _EXE name is more likely to change. --- src/journal/journalctl.c | 30 ++++++++++++++++++++++++++---- src/shared/fileio.c | 29 +++++++++++++++++++++++++++++ src/shared/fileio.h | 2 ++ src/test/test-fileio.c | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 92 insertions(+), 4 deletions(-) diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 083a597116..dde2ed7e37 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -45,6 +45,7 @@ #include "logs-show.h" #include "util.h" #include "path-util.h" +#include "fileio.h" #include "build.h" #include "pager.h" #include "logs-show.h" @@ -627,8 +628,9 @@ static int add_matches(sd_journal *j, char **args) { if (streq(*i, "+")) r = sd_journal_add_disjunction(j); else if (path_is_absolute(*i)) { - _cleanup_free_ char *p, *t = NULL; + _cleanup_free_ char *p, *t = NULL, *t2 = NULL; const char *path; + _cleanup_free_ char *interpreter = NULL; struct stat st; p = canonicalize_file_name(*i); @@ -639,9 +641,27 @@ static int add_matches(sd_journal *j, char **args) { return -errno; } - if (S_ISREG(st.st_mode) && (0111 & st.st_mode)) - t = strappend("_EXE=", path); - else if (S_ISCHR(st.st_mode)) + if (S_ISREG(st.st_mode) && (0111 & st.st_mode)) { + if (executable_is_script(path, &interpreter) > 0) { + _cleanup_free_ char *comm; + + comm = strndup(path_get_file_name(path), 15); + if (!comm) + return log_oom(); + + t = strappend("_COMM=", comm); + + /* Append _EXE only if the interpreter is not a link. + Otherwise it might be outdated often. */ + if (lstat(interpreter, &st) == 0 && + !S_ISLNK(st.st_mode)) { + t2 = strappend("_EXE=", interpreter); + if (!t2) + return log_oom(); + } + } else + t = strappend("_EXE=", path); + } else if (S_ISCHR(st.st_mode)) asprintf(&t, "_KERNEL_DEVICE=c%u:%u", major(st.st_rdev), minor(st.st_rdev)); else if (S_ISBLK(st.st_mode)) asprintf(&t, "_KERNEL_DEVICE=b%u:%u", major(st.st_rdev), minor(st.st_rdev)); @@ -654,6 +674,8 @@ static int add_matches(sd_journal *j, char **args) { return log_oom(); r = sd_journal_add_match(j, t, 0); + if (t2) + r = sd_journal_add_match(j, t2, 0); } else r = sd_journal_add_match(j, *i, 0); diff --git a/src/shared/fileio.c b/src/shared/fileio.c index dc13c9ee63..2b1dab8053 100644 --- a/src/shared/fileio.c +++ b/src/shared/fileio.c @@ -593,3 +593,32 @@ int write_env_file(const char *fname, char **l) { return r; } + +int executable_is_script(const char *path, char **interpreter) { + int r; + char _cleanup_free_ *line = NULL; + int len; + char *ans; + + assert(path); + + r = read_one_line_file(path, &line); + if (r < 0) + return r; + + if (!startswith(line, "#!")) + return 0; + + ans = strstrip(line + 2); + len = strcspn(ans, " \t"); + + if (len == 0) + return 0; + + ans = strndup(ans, len); + if (!ans) + return -ENOMEM; + + *interpreter = ans; + return 1; +} diff --git a/src/shared/fileio.h b/src/shared/fileio.h index 0ca6878ea4..a0aae28bae 100644 --- a/src/shared/fileio.h +++ b/src/shared/fileio.h @@ -35,3 +35,5 @@ int read_full_file(const char *fn, char **contents, size_t *size); int parse_env_file(const char *fname, const char *separator, ...) _sentinel_; int load_env_file(const char *fname, const char *separator, char ***l); int write_env_file(const char *fname, char **l); + +int executable_is_script(const char *path, char **interpreter); diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c index d56f7cc856..b08e796b7d 100644 --- a/src/test/test-fileio.c +++ b/src/test/test-fileio.c @@ -139,7 +139,42 @@ static void test_parse_env_file(void) { unlink("/tmp/test-fileio"); } +static void test_executable_is_script(void) { + char t[] = "/tmp/test-executable-XXXXXX"; + int fd, r; + FILE *f; + char *command; + + fd = mkostemp(t, O_CLOEXEC); + assert_se(fd >= 0); + + f = fdopen(fd, "w"); + assert_se(f); + + fputs("#! /bin/script -a -b \ngoo goo", f); + fflush(f); + + r = executable_is_script(t, &command); + assert_se(r > 0); + assert_se(streq(command, "/bin/script")); + free(command); + + r = executable_is_script("/bin/sh", &command); + assert_se(r == 0); + + r = executable_is_script("/usr/bin/yum", &command); + assert_se(r > 0 || r == -ENOENT); + if (r > 0) { + assert_se(startswith(command, "/")); + free(command); + } + + fclose(f); + unlink(t); +} + int main(int argc, char *argv[]) { test_parse_env_file(); + test_executable_is_script(); return 0; } -- cgit v1.2.1 From e21fea24ae2a7a04f6d5c9d2bbbaf5833d248952 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 26 Jul 2013 05:22:22 +0200 Subject: rework systemd's own process environment handling/passing Stop importing non-sensical kernel-exported variables. All parameters in the kernel command line are exported to the initial environment of PID1, but suppressed if they are recognized by kernel built-in code. The EFI booted kernel will add further kernel-internal things which do not belong into userspace. The passed original environ data of the process is not touched and preserved across re-execution, to allow external reading of /proc/self/environ for process properties like container*=. --- man/systemd.xml | 15 ++++------- src/core/locale-setup.c | 21 +++++++++------ src/core/locale-setup.h | 2 +- src/core/main.c | 71 ++++++++----------------------------------------- src/core/manager.c | 47 ++++++++++++++++++++------------ src/core/manager.h | 2 +- src/shared/strv.c | 15 +++++++++++ src/shared/strv.h | 1 + 8 files changed, 77 insertions(+), 97 deletions(-) diff --git a/man/systemd.xml b/man/systemd.xml index 1e54eac926..32bca0b607 100644 --- a/man/systemd.xml +++ b/man/systemd.xml @@ -1113,16 +1113,11 @@ systemd.setenv= Takes a string - argument in the form - VARIABLE=VALUE. May be used to set - environment variables for the init - process and all its children at boot - time. May be used more than once to - set multiple variables. If the equal - sign and variable are missing it unsets - an environment variable which might be - passed in from the initial ram - disk. + argument in the form VARIABLE=VALUE. + May be used to set default environment + variables to add to forked child processes. + May be used more than once to set multiple + variables. diff --git a/src/core/locale-setup.c b/src/core/locale-setup.c index daf81d080e..31374ac644 100644 --- a/src/core/locale-setup.c +++ b/src/core/locale-setup.c @@ -28,6 +28,7 @@ #include "macro.h" #include "virt.h" #include "fileio.h" +#include "strv.h" enum { /* We don't list LC_ALL here on purpose. People should be @@ -67,7 +68,8 @@ static const char * const variable_names[_VARIABLE_MAX] = { [VARIABLE_LC_IDENTIFICATION] = "LC_IDENTIFICATION" }; -int locale_setup(void) { +int locale_setup(char ***environment) { + char **env; char *variables[_VARIABLE_MAX] = {}; int r = 0, i; @@ -118,13 +120,16 @@ int locale_setup(void) { } for (i = 0; i < _VARIABLE_MAX; i++) { - if (variables[i]) { - if (setenv(variable_names[i], variables[i], 1) < 0) { - r = -errno; - goto finish; - } - } else - unsetenv(variable_names[i]); + if (!variables[i]) + continue; + + env = strv_appendf(*environment, "%s=%s", variable_names[i], variables[i]); + if (!env) { + r = -ENOMEM; + goto finish; + } + + *environment = env; } r = 0; diff --git a/src/core/locale-setup.h b/src/core/locale-setup.h index 5a0f2f7888..62c654c37c 100644 --- a/src/core/locale-setup.h +++ b/src/core/locale-setup.h @@ -21,4 +21,4 @@ along with systemd; If not, see . ***/ -int locale_setup(void); +int locale_setup(char ***environment); diff --git a/src/core/main.c b/src/core/main.c index ad155e13ca..91cbee2e59 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -64,7 +64,6 @@ #endif #include "hostname-setup.h" #include "machine-id-setup.h" -#include "locale-setup.h" #include "selinux-setup.h" #include "ima-setup.h" #include "fileio.h" @@ -349,32 +348,21 @@ static int parse_proc_cmdline_word(const char *word) { arg_default_std_error = r; } else if (startswith(word, "systemd.setenv=")) { _cleanup_free_ char *cenv = NULL; - char *eq; - int r; cenv = strdup(word + 15); if (!cenv) return -ENOMEM; - eq = strchr(cenv, '='); - if (!eq) { - if (!env_name_is_valid(cenv)) - log_warning("Environment variable name '%s' is not valid. Ignoring.", cenv); - else { - r = unsetenv(cenv); - if (r < 0) - log_warning("Unsetting environment variable '%s' failed, ignoring: %m", cenv); - } - } else { - if (!env_assignment_is_valid(cenv)) - log_warning("Environment variable assignment '%s' is not valid. Ignoring.", cenv); - else { - *eq = 0; - r = setenv(cenv, eq + 1, 1); - if (r < 0) - log_warning("Setting environment variable '%s=%s' failed, ignoring: %m", cenv, eq + 1); - } - } + if (env_assignment_is_valid(cenv)) { + char **env; + + env = strv_env_set(arg_default_environment, cenv); + if (env) + arg_default_environment = env; + else + log_warning("Setting environment variable '%s' failed, ignoring: %m", cenv); + } else + log_warning("Environment variable name '%s' is not valid. Ignoring.", cenv); } else if (startswith(word, "systemd.") || (in_initrd() && startswith(word, "rd.systemd."))) { @@ -1445,42 +1433,7 @@ int main(int argc, char *argv[]) { if (serialization) assert_se(fdset_remove(fds, fileno(serialization)) >= 0); - /* Set up PATH unless it is already set */ - setenv("PATH", -#ifdef HAVE_SPLIT_USR - "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", -#else - "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin", -#endif - arg_running_as == SYSTEMD_SYSTEM); - if (arg_running_as == SYSTEMD_SYSTEM) { - /* Unset some environment variables passed in from the - * kernel that don't really make sense for us. */ - unsetenv("HOME"); - unsetenv("TERM"); - - /* When we are invoked by a shell, these might be set, - * but make little sense to pass on */ - unsetenv("PWD"); - unsetenv("SHLVL"); - unsetenv("_"); - - /* When we are invoked by a chroot-like tool such as - * nspawn, these might be set, but make little sense - * to pass on */ - unsetenv("USER"); - unsetenv("LOGNAME"); - - /* We suppress the socket activation env vars, as - * we'll try to match *any* open fd to units if - * possible. */ - unsetenv("LISTEN_FDS"); - unsetenv("LISTEN_PID"); - - /* All other variables are left as is, so that clients - * can still read them via /proc/1/environ */ - /* Become a session leader if we aren't one yet. */ setsid(); @@ -1528,8 +1481,6 @@ int main(int argc, char *argv[]) { log_debug(PACKAGE_STRING " running in user mode. (" SYSTEMD_FEATURES ")"); if (arg_running_as == SYSTEMD_SYSTEM && !skip_setup) { - locale_setup(); - if (arg_show_status || plymouth_running()) status_welcome(); @@ -1595,7 +1546,7 @@ int main(int argc, char *argv[]) { manager_set_default_rlimits(m, arg_default_rlimit); if (arg_default_environment) - manager_set_default_environment(m, arg_default_environment); + manager_environment_add(m, arg_default_environment); manager_set_show_status(m, arg_show_status); diff --git a/src/core/manager.c b/src/core/manager.c index 6c082c96b9..10ccffb404 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -55,6 +55,7 @@ #include "util.h" #include "mkdir.h" #include "ratelimit.h" +#include "locale-setup.h" #include "mount-setup.h" #include "unit-name.h" #include "dbus-unit.h" @@ -454,22 +455,36 @@ static int manager_setup_signals(Manager *m) { return 0; } -static void manager_strip_environment(Manager *m) { +static int manager_default_environment(Manager *m) { +#ifdef HAVE_SPLIT_USR + const char *path = "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"; +#else + const char *path = "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin"; +#endif + assert(m); - /* Remove variables from the inherited set that are part of - * the container interface: - * http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface */ - strv_remove_prefix(m->environment, "container="); - strv_remove_prefix(m->environment, "container_"); + if (m->running_as == SYSTEMD_SYSTEM) { + /* The system manager always starts with a clean + * environment for its children. It does not import + * the kernel or the parents exported variables. + * + * The initial passed environ is untouched to keep + * /proc/self/environ valid; it is used for tagging + * the init process inside containers. */ + m->environment = strv_new(path, NULL); + + /* Import locale variables LC_*= from configuration */ + locale_setup(&m->environment); + } else + /* The user manager passes its own environment + * along to its children. */ + m->environment = strv_copy(environ); - /* Remove variables from the inherited set that are part of - * the initrd interface: - * http://www.freedesktop.org/wiki/Software/systemd/InitrdInterface */ - strv_remove_prefix(m->environment, "RD_"); + if (!m->environment) + return -ENOMEM; - /* Drop invalid entries */ - strv_env_clean(m->environment); + return 0; } int manager_new(SystemdRunningAs running_as, bool reexecuting, Manager **_m) { @@ -505,12 +520,10 @@ int manager_new(SystemdRunningAs running_as, bool reexecuting, Manager **_m) { m->epoll_fd = m->dev_autofs_fd = -1; m->current_job_id = 1; /* start as id #1, so that we can leave #0 around as "null-like" value */ - m->environment = strv_copy(environ); - if (!m->environment) + r = manager_default_environment(m); + if (r < 0) goto fail; - manager_strip_environment(m); - if (!(m->units = hashmap_new(string_hash_func, string_compare_func))) goto fail; @@ -2651,7 +2664,7 @@ void manager_undo_generators(Manager *m) { remove_generator_dir(m, &m->generator_unit_path_late); } -int manager_set_default_environment(Manager *m, char **environment) { +int manager_environment_add(Manager *m, char **environment) { char **e = NULL; assert(m); diff --git a/src/core/manager.h b/src/core/manager.h index bd068ac3c9..3969553e3e 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -281,7 +281,7 @@ unsigned manager_dispatch_load_queue(Manager *m); unsigned manager_dispatch_run_queue(Manager *m); unsigned manager_dispatch_dbus_queue(Manager *m); -int manager_set_default_environment(Manager *m, char **environment); +int manager_environment_add(Manager *m, char **environment); int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit); int manager_loop(Manager *m); diff --git a/src/shared/strv.c b/src/shared/strv.c index a5ce7e9593..3e7778d61c 100644 --- a/src/shared/strv.c +++ b/src/shared/strv.c @@ -387,6 +387,21 @@ fail: return NULL; } +char **strv_appendf(char **l, const char *format, ...) { + va_list ap; + _cleanup_free_ char *s = NULL; + int r; + + va_start(ap, format); + r = vasprintf(&s, format, ap); + va_end(ap); + + if (r < 0) + return NULL; + + return strv_append(l, s); +} + int strv_push(char ***l, char *value) { char **c; unsigned n; diff --git a/src/shared/strv.h b/src/shared/strv.h index e35118752f..4ade827a42 100644 --- a/src/shared/strv.h +++ b/src/shared/strv.h @@ -42,6 +42,7 @@ unsigned strv_length(char * const *l) _pure_; char **strv_merge(char **a, char **b); char **strv_merge_concat(char **a, char **b, const char *suffix); char **strv_append(char **l, const char *s); +char **strv_appendf(char **l, const char *format, ...) _printf_attr_(2, 3); int strv_extend(char ***l, const char *value); int strv_push(char ***l, char *value); -- cgit v1.2.1 From 76e665855edef5b7103cb09d114377d477bfae02 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 26 Jul 2013 18:59:46 +0200 Subject: logind: update the session state file before we send out the CreateSession() reply https://bugs.freedesktop.org/show_bug.cgi?id=67273 --- TODO | 2 -- src/login/logind-dbus.c | 5 ++--- src/login/logind-session-dbus.c | 4 ++++ src/machine/machine-dbus.c | 4 ++++ src/machine/machined-dbus.c | 5 ++--- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/TODO b/TODO index 35ce46ff40..57ff3311c9 100644 --- a/TODO +++ b/TODO @@ -51,8 +51,6 @@ CGroup Rework Completion: Features: -* remove systemctl load-unit - * journalctl: instead --after-cursor= maybe have a --cursor=XYZ+1 syntax? * given that logind/machined now let PID 1 do all nasty work we can diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index b5e975a9f7..7b9bd201b2 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -2368,9 +2368,8 @@ DBusHandlerResult bus_message_filter( dbus_set_error(&error, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result); session_send_create_reply(s, &error); } - } - - session_save(s); + } else + session_save(s); } session_add_to_gc_queue(s); diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c index 210f7564da..2cc4d8587b 100644 --- a/src/login/logind-session-dbus.c +++ b/src/login/logind-session-dbus.c @@ -592,6 +592,10 @@ int session_send_create_reply(Session *s, DBusError *error) { return log_oom(); } + /* Update the state file before we notify the client about the + * result */ + session_save(s); + if (!dbus_connection_send(s->manager->bus, reply, NULL)) return log_oom(); diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c index 6e1b8f8186..ceab96e078 100644 --- a/src/machine/machine-dbus.c +++ b/src/machine/machine-dbus.c @@ -350,6 +350,10 @@ int machine_send_create_reply(Machine *m, DBusError *error) { return log_oom(); } + /* Update the machine state file before we notify the client + * about the result. */ + machine_save(m); + if (!dbus_connection_send(m->manager->bus, reply, NULL)) return log_oom(); diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c index 6c4d50b3a2..5a016e76bc 100644 --- a/src/machine/machined-dbus.c +++ b/src/machine/machined-dbus.c @@ -551,9 +551,8 @@ DBusHandlerResult bus_message_filter( dbus_set_error(&error, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result); machine_send_create_reply(mm, &error); } - } - - machine_save(mm); + } else + machine_save(mm); } machine_add_to_gc_queue(mm); -- cgit v1.2.1 From d240b2e1baee24e72197fe6fcab7a8271d8433e7 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Fri, 26 Jul 2013 20:01:33 -0400 Subject: systemctl.8: fix typo in SEE ALSO --- man/systemctl.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/systemctl.xml b/man/systemctl.xml index 2a23655cfe..fc1c7f2cf9 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -1242,7 +1242,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service journalctl1, loginctl1, systemd.unit5, - systemd.cgroupq5, + systemd.cgroup5, systemd.special7, wall1, systemd.preset5 -- cgit v1.2.1 From c0e1b502700b2fec6e1b542e861b1bbabca75527 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 27 Jul 2013 19:54:29 +0200 Subject: TODO: remove kernel env var importing fix --- TODO | 8 -------- 1 file changed, 8 deletions(-) diff --git a/TODO b/TODO index 57ff3311c9..37bba4ba0d 100644 --- a/TODO +++ b/TODO @@ -11,14 +11,6 @@ Bugfixes: * properly handle .mount unit state tracking when two mount points are stacked one on top of another on the exact same mount point. -* stop importing kernel exported env variables. The utterly broken logic in - the kernel exports every kernel command line option which is not recognized - as a built-in module option as an env variable. Systemd should not pass-on - that nonsense, a kernel command line option is a command line option not an - env variable: - $ cat /proc/252/environ - initrd=\6a9857a393724b7a981ebb5b8495b9ea\3.10.0-2.fc20.x86_64\initrd - Fedora 20: * external: ps should gain colums for slice and machine -- cgit v1.2.1 From 6f88df575181d029eadc889fd6891dee22016af1 Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Sat, 27 Jul 2013 09:49:58 -0700 Subject: man: systemd.unit: fix volatile path The volatile path was '/run/systemd/systemd' when it should be '/run/systemd/system'. Fix. --- man/systemd.unit.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index f6a0791bf9..2f65ec6dac 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -285,7 +285,7 @@ Local configuration - /run/systemd/systemd + /run/systemd/system Volatile units -- cgit v1.2.1 From e73eebfd993f2fac480bff651adde7d5d99bd9e2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 24 Jul 2013 17:31:17 +0200 Subject: man: link up scope+slice units from systemd.unit(5) --- man/systemd.unit.xml | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index 2f65ec6dac..a577e914fa 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -60,7 +60,9 @@ target.target, path.path, timer.timer, - snapshot.snapshot + snapshot.snapshot, + slice.slice, + scope.scope /etc/systemd/system/* /run/systemd/system/* @@ -81,12 +83,15 @@ A unit configuration file encodes information about a service, a socket, a device, a mount point, an automount point, a swap file or partition, a start-up - target, a file system path, or a timer controlled and - supervised by - systemd1. The - syntax is inspired by systemd1, + a temporary system state snapshot, a resource + management slice or a group of externally created + processes. The syntax is inspired by XDG - Desktop Entry Specification .desktop files, which are in turn + Desktop Entry Specification + .desktop files, which are in turn inspired by Microsoft Windows .ini files. @@ -110,6 +115,8 @@ systemd.path5, systemd.timer5, systemd.snapshot5. + systemd.slice5. + systemd.scope5. Unit files are loaded from a set of paths @@ -1324,6 +1331,8 @@ systemd.path5, systemd.timer5, systemd.snapshot5, + systemd.scope5, + systemd.slice5, systemd.time7, capabilities7, systemd.directives7, -- cgit v1.2.1 From 42539b5e38eebd54173c6064ec394ccc3054a8ad Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 24 Jul 2013 17:31:37 +0200 Subject: man: there is no session mode, only user mode --- man/systemd.unit.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index a577e914fa..1b71538c82 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -317,7 +317,7 @@ - Load path when running in session mode (<option>--user</option>). + Load path when running in user mode (<option>--user</option>). -- cgit v1.2.1 From 6f47d17c3c594bd6b0923ed1801f9ad706966d52 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 24 Jul 2013 17:31:44 +0200 Subject: man: reowrk list of documented unit search paths The generator paths are internal implementation details, they should not be documented explicitly. We should document where private user units are found however. --- man/systemd.unit.xml | 55 ++++++++++++++-------------------------------------- 1 file changed, 15 insertions(+), 40 deletions(-) diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index 1b71538c82..c6325d373a 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -70,7 +70,8 @@ ... - /etc/systemd/user/* + $HOME/.config/systemd/user/* +/etc/systemd/user/* /run/systemd/user/* /usr/lib/systemd/user/* ... @@ -256,10 +257,9 @@ Unit files are loaded from a set of paths determined during compilation, described in the two - tables below. Unit files found in directories higher - in the hierarchy override files with the same name - lower in the hierarchy, thus allowing overrides. - + tables below. Unit files found in directories listed + earlier override files with the same name in + directories lower in the list. When systemd is running in user mode () and the variable @@ -283,33 +283,17 @@ - - /run/systemd/generator.early - Generated units (early) - /etc/systemd/system Local configuration /run/systemd/system - Volatile units - - - /run/systemd/generator - Generated units (middle) - - - /usr/local/lib/systemd/system - Units for local packages + Runtime units /usr/lib/systemd/system - Units for installed packages - - - /run/systemd/generator.late - Generated units (late) + Units of installed packages @@ -331,8 +315,8 @@ - /tmp/systemd-generator.early.XXXXXX - Generated units (early) + $HOME/.config/systemd/user + User configuration /etc/systemd/user @@ -340,23 +324,11 @@ /run/systemd/user - Volatile units - - - /tmp/systemd-generator.XXXXXX - Generated units (middle) - - - /usr/local/lib/systemd/user - Units for local packages + Runtime units /usr/lib/systemd/user - Units for installed packages - - - /tmp/systemd-generator.late.XXXXXX - Generated units (late) + Units of installed packages @@ -365,7 +337,10 @@ Additional units might be loaded into systemd ("linked") from directories not on the unit load path. See the link command for - systemctl1. + systemctl1. Also, + some units are dynamically created via generators + Generators. -- cgit v1.2.1 From afaba0234727db6a82e323665d7d86f971f3090c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 29 Jul 2013 16:39:22 +0200 Subject: update TODO --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index 37bba4ba0d..7bc75d724c 100644 --- a/TODO +++ b/TODO @@ -43,6 +43,8 @@ CGroup Rework Completion: Features: +* session scopes/user unit: add RequiresMountsFor for the home directory of the user + * journalctl: instead --after-cursor= maybe have a --cursor=XYZ+1 syntax? * given that logind/machined now let PID 1 do all nasty work we can -- cgit v1.2.1 From 4c4ae27d4d314d0dc1c42cd6bfc7b9ae31660885 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 29 Jul 2013 18:43:27 +0200 Subject: update TODO --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index 7bc75d724c..feb4944191 100644 --- a/TODO +++ b/TODO @@ -45,6 +45,8 @@ Features: * session scopes/user unit: add RequiresMountsFor for the home directory of the user +* add a man page containing packaging guidelines and recommending usage of things like Documentation=, PrivateTmp=, PrivateNetwork= and ReadOnlyDirectories=/etc /usr. + * journalctl: instead --after-cursor= maybe have a --cursor=XYZ+1 syntax? * given that logind/machined now let PID 1 do all nasty work we can -- cgit v1.2.1 From 5a4555ba6bc8ea086823fb71cb1cb92d4ec087a2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 29 Jul 2013 23:08:31 +0200 Subject: update TODO --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index feb4944191..fe2af675b0 100644 --- a/TODO +++ b/TODO @@ -43,6 +43,8 @@ CGroup Rework Completion: Features: +* logind: when logging out, remove user-owned sysv and posix IPC objects + * session scopes/user unit: add RequiresMountsFor for the home directory of the user * add a man page containing packaging guidelines and recommending usage of things like Documentation=, PrivateTmp=, PrivateNetwork= and ReadOnlyDirectories=/etc /usr. -- cgit v1.2.1 From 82659fd7571bda0f3dce9755b89a23c411d53dda Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 30 Jul 2013 01:54:59 +0200 Subject: core: optionally send SIGHUP in addition to the configured kill signal This is useful to fake session ends for processes like shells. --- man/systemd.kill.xml | 34 +++++++++++--- src/core/dbus-kill.c | 1 + src/core/dbus-kill.h | 6 +-- src/core/kill.c | 7 ++- src/core/kill.h | 1 + src/core/load-fragment-gperf.gperf.m4 | 1 + src/core/unit.c | 84 ++++++++++++++++++++++------------- units/console-getty.service.m4.in | 5 +-- units/console-shell.service.m4.in | 5 +-- units/emergency.service.in | 5 +-- units/getty@.service.m4 | 5 +-- units/rescue.service.m4.in | 6 +-- units/serial-getty@.service.m4 | 5 +-- 13 files changed, 97 insertions(+), 68 deletions(-) diff --git a/man/systemd.kill.xml b/man/systemd.kill.xml index 2a810e257f..517a891777 100644 --- a/man/systemd.kill.xml +++ b/man/systemd.kill.xml @@ -115,16 +115,21 @@ . Processes will first be - terminated via SIGTERM (unless the - signal to send is changed via - KillSignal=). If + terminated via + SIGTERM (unless + the signal to send is changed via + KillSignal=). Optionally, + this is immediately followed by a + SIGHUP (if + enabled with + SendSIGHUP=). If then after a delay (configured via the - TimeoutSec= option) + TimeoutStopSec= option) processes still remain, the termination request is repeated with - the SIGKILL signal (unless this is - disabled via the - SendSIGKILL= + the SIGKILL + signal (unless this is disabled via + the SendSIGKILL= option). See kill2 for more @@ -139,6 +144,20 @@ + + SendSIGHUP= + Specifies whether to + send SIGHUP to + remaining processes immediately after + sending the signal configured with + KillSignal=. This + is useful to indicate to shells and + shell-like programs that their + connection has been severed. Takes a + boolean value. Defaults to "no". + + + SendSIGKILL= Specifies whether to @@ -149,6 +168,7 @@ value. Defaults to "yes". + diff --git a/src/core/dbus-kill.c b/src/core/dbus-kill.c index 165f63074b..e970ea329c 100644 --- a/src/core/dbus-kill.c +++ b/src/core/dbus-kill.c @@ -31,5 +31,6 @@ const BusProperty bus_kill_context_properties[] = { { "KillMode", bus_kill_append_mode, "s", offsetof(KillContext, kill_mode) }, { "KillSignal", bus_property_append_int, "i", offsetof(KillContext, kill_signal) }, { "SendSIGKILL", bus_property_append_bool, "b", offsetof(KillContext, send_sigkill) }, + { "SendSIGHUP", bus_property_append_bool, "b", offsetof(KillContext, send_sighup) }, { NULL, } }; diff --git a/src/core/dbus-kill.h b/src/core/dbus-kill.h index 238fbd36d6..8c8bff5927 100644 --- a/src/core/dbus-kill.h +++ b/src/core/dbus-kill.h @@ -29,10 +29,8 @@ #define BUS_KILL_CONTEXT_INTERFACE \ " \n" \ " \n" \ - " \n" - -#define BUS_KILL_COMMAND_INTERFACE(name) \ - " \n" + " \n" \ + " \n" extern const BusProperty bus_kill_context_properties[]; diff --git a/src/core/kill.c b/src/core/kill.c index 0775653f73..ea947c23ae 100644 --- a/src/core/kill.c +++ b/src/core/kill.c @@ -29,6 +29,7 @@ void kill_context_init(KillContext *c) { c->kill_signal = SIGTERM; c->send_sigkill = true; + c->send_sighup = false; } void kill_context_dump(KillContext *c, FILE *f, const char *prefix) { @@ -40,10 +41,12 @@ void kill_context_dump(KillContext *c, FILE *f, const char *prefix) { fprintf(f, "%sKillMode: %s\n" "%sKillSignal: SIG%s\n" - "%sSendSIGKILL: %s\n", + "%sSendSIGKILL: %s\n" + "%sSendSIGHUP: %s\n", prefix, kill_mode_to_string(c->kill_mode), prefix, signal_to_string(c->kill_signal), - prefix, yes_no(c->send_sigkill)); + prefix, yes_no(c->send_sigkill), + prefix, yes_no(c->send_sighup)); } static const char* const kill_mode_table[_KILL_MODE_MAX] = { diff --git a/src/core/kill.h b/src/core/kill.h index 71a0513e84..41773f07ae 100644 --- a/src/core/kill.h +++ b/src/core/kill.h @@ -41,6 +41,7 @@ struct KillContext { KillMode kill_mode; int kill_signal; bool send_sigkill; + bool send_sighup; }; typedef enum KillWho { diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index 0c337bca9c..2b0106ffe2 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -79,6 +79,7 @@ $1.UtmpIdentifier, config_parse_unit_string_printf, 0, )m4_dnl m4_define(`KILL_CONTEXT_CONFIG_ITEMS', `$1.SendSIGKILL, config_parse_bool, 0, offsetof($1, kill_context.send_sigkill) +$1.SendSIGHUP, config_parse_bool, 0, offsetof($1, kill_context.send_sighup) $1.KillMode, config_parse_kill_mode, 0, offsetof($1, kill_context.kill_mode) $1.KillSignal, config_parse_kill_signal, 0, offsetof($1, kill_context.kill_signal)' )m4_dnl diff --git a/src/core/unit.c b/src/core/unit.c index 0e9329f8c9..b56be83a31 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -2542,6 +2542,34 @@ int unit_kill(Unit *u, KillWho w, int signo, DBusError *error) { return UNIT_VTABLE(u)->kill(u, w, signo, error); } +static Set *unit_pid_set(pid_t main_pid, pid_t control_pid) { + Set *pid_set; + int r; + + pid_set = set_new(trivial_hash_func, trivial_compare_func); + if (!pid_set) + return NULL; + + /* Exclude the main/control pids from being killed via the cgroup */ + if (main_pid > 0) { + r = set_put(pid_set, LONG_TO_PTR(main_pid)); + if (r < 0) + goto fail; + } + + if (control_pid > 0) { + r = set_put(pid_set, LONG_TO_PTR(control_pid)); + if (r < 0) + goto fail; + } + + return pid_set; + +fail: + set_free(pid_set); + return NULL; +} + int unit_kill_common( Unit *u, KillWho who, @@ -2582,23 +2610,11 @@ int unit_kill_common( _cleanup_set_free_ Set *pid_set = NULL; int q; - pid_set = set_new(trivial_hash_func, trivial_compare_func); + /* Exclude the main/control pids from being killed via the cgroup */ + pid_set = unit_pid_set(main_pid, control_pid); if (!pid_set) return -ENOMEM; - /* Exclude the control/main pid from being killed via the cgroup */ - if (control_pid > 0) { - q = set_put(pid_set, LONG_TO_PTR(control_pid)); - if (q < 0) - return q; - } - - if (main_pid > 0) { - q = set_put(pid_set, LONG_TO_PTR(main_pid)); - if (q < 0) - return q; - } - q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, signo, false, true, false, pid_set); if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT) r = q; @@ -2949,8 +2965,12 @@ int unit_kill_context( log_warning_unit(u->id, "Failed to kill main process %li (%s): %s", (long) main_pid, strna(comm), strerror(-r)); - } else + } else { wait_for_exit = !main_pid_alien; + + if (c->send_sighup) + kill(main_pid, SIGHUP); + } } if (control_pid > 0) { @@ -2963,36 +2983,38 @@ int unit_kill_context( log_warning_unit(u->id, "Failed to kill control process %li (%s): %s", (long) control_pid, strna(comm), strerror(-r)); - } else + } else { wait_for_exit = true; + + if (c->send_sighup) + kill(control_pid, SIGHUP); + } } if (c->kill_mode == KILL_CONTROL_GROUP && u->cgroup_path) { _cleanup_set_free_ Set *pid_set = NULL; - pid_set = set_new(trivial_hash_func, trivial_compare_func); + /* Exclude the main/control pids from being killed via the cgroup */ + pid_set = unit_pid_set(main_pid, control_pid); if (!pid_set) return -ENOMEM; - /* Exclude the main/control pids from being killed via the cgroup */ - if (main_pid > 0) { - r = set_put(pid_set, LONG_TO_PTR(main_pid)); - if (r < 0) - return r; - } - - if (control_pid > 0) { - r = set_put(pid_set, LONG_TO_PTR(control_pid)); - if (r < 0) - return r; - } - r = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, sig, true, true, false, pid_set); if (r < 0) { if (r != -EAGAIN && r != -ESRCH && r != -ENOENT) log_warning_unit(u->id, "Failed to kill control group: %s", strerror(-r)); - } else if (r > 0) + } else if (r > 0) { wait_for_exit = true; + if (c->send_sighup) { + set_free(pid_set); + + pid_set = unit_pid_set(main_pid, control_pid); + if (!pid_set) + return -ENOMEM; + + cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, SIGHUP, true, true, false, pid_set); + } + } } return wait_for_exit; diff --git a/units/console-getty.service.m4.in b/units/console-getty.service.m4.in index 0426050ee8..2fd9dd8478 100644 --- a/units/console-getty.service.m4.in +++ b/units/console-getty.service.m4.in @@ -25,10 +25,7 @@ TTYReset=yes TTYVHangup=yes KillMode=process IgnoreSIGPIPE=no - -# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash -# terminates cleanly. -KillSignal=SIGHUP +SendSIGHUP=yes [Install] WantedBy=getty.target diff --git a/units/console-shell.service.m4.in b/units/console-shell.service.m4.in index dac2ac212b..3f4904a0ee 100644 --- a/units/console-shell.service.m4.in +++ b/units/console-shell.service.m4.in @@ -25,10 +25,7 @@ StandardOutput=inherit StandardError=inherit KillMode=process IgnoreSIGPIPE=no - -# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash -# terminates cleanly. -KillSignal=SIGHUP +SendSIGHUP=yes [Install] WantedBy=getty.target diff --git a/units/emergency.service.in b/units/emergency.service.in index 442f0e0ee6..94c090f654 100644 --- a/units/emergency.service.in +++ b/units/emergency.service.in @@ -25,7 +25,4 @@ StandardOutput=inherit StandardError=inherit KillMode=process IgnoreSIGPIPE=no - -# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash -# terminates cleanly. -KillSignal=SIGHUP +SendSIGHUP=yes diff --git a/units/getty@.service.m4 b/units/getty@.service.m4 index 7853652009..253da85f8e 100644 --- a/units/getty@.service.m4 +++ b/units/getty@.service.m4 @@ -38,14 +38,11 @@ TTYVHangup=yes TTYVTDisallocate=yes KillMode=process IgnoreSIGPIPE=no +SendSIGHUP=yes # Unset locale for the console getty since the console has problems # displaying some internationalized messages. Environment=LANG= LANGUAGE= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETARY= LC_MESSAGES= LC_PAPER= LC_NAME= LC_ADDRESS= LC_TELEPHONE= LC_MEASUREMENT= LC_IDENTIFICATION= -# Some login implementations ignore SIGTERM, so we send SIGHUP -# instead, to ensure that login terminates cleanly. -KillSignal=SIGHUP - [Install] WantedBy=getty.target diff --git a/units/rescue.service.m4.in b/units/rescue.service.m4.in index 269797a12e..552ef8981b 100644 --- a/units/rescue.service.m4.in +++ b/units/rescue.service.m4.in @@ -25,7 +25,5 @@ StandardInput=tty-force StandardOutput=inherit StandardError=inherit KillMode=process - -# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash -# terminates cleanly. -KillSignal=SIGHUP +IgnoreSIGPIPE=no +SendSIGHUP=yes diff --git a/units/serial-getty@.service.m4 b/units/serial-getty@.service.m4 index 5e16963e92..e32c6b7aff 100644 --- a/units/serial-getty@.service.m4 +++ b/units/serial-getty@.service.m4 @@ -32,7 +32,4 @@ TTYReset=yes TTYVHangup=yes KillMode=process IgnoreSIGPIPE=no - -# Some login implementations ignore SIGTERM, so we send SIGHUP -# instead, to ensure that login terminates cleanly. -KillSignal=SIGHUP +SendSIGHUP=yes -- cgit v1.2.1 From ce8aba568156f2b9d0d3b023e960cda3d9d7db81 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 30 Jul 2013 02:02:45 +0200 Subject: do not pass-along the environment from the kernel or initrd --- src/core/main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/main.c b/src/core/main.c index 91cbee2e59..8a73ad3cc7 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1776,6 +1776,10 @@ finish: args[i++] = sfd; args[i++] = NULL; + /* do not pass along the environment we inherit from the kernel or initrd */ + if (switch_root_dir) + clearenv(); + assert(i <= args_size); execv(args[0], (char* const*) args); } -- cgit v1.2.1 From fba1ea06bb5b653e9eb0cc1b6004af8da273a4ab Mon Sep 17 00:00:00 2001 From: Shawn Landden Date: Sun, 21 Jul 2013 20:57:35 -0700 Subject: build: do not link everything with -lrt (and therefore -pthread) --- Makefile.am | 3 +++ configure.ac | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 7b4753d300..c81c40c594 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1835,6 +1835,9 @@ libsystemd_daemon_la_LDFLAGS = \ -version-info $(LIBSYSTEMD_DAEMON_CURRENT):$(LIBSYSTEMD_DAEMON_REVISION):$(LIBSYSTEMD_DAEMON_AGE) \ -Wl,--version-script=$(top_srcdir)/src/libsystemd-daemon/libsystemd-daemon.sym +libsystemd_daemon_la_LIBADD = \ + $(RT_LIBS) + pkginclude_HEADERS += \ src/systemd/sd-daemon.h diff --git a/configure.ac b/configure.ac index 4e8c573ab3..76aa2a920a 100644 --- a/configure.ac +++ b/configure.ac @@ -190,7 +190,6 @@ AM_CONDITIONAL([HAVE_PYTHON_DEVEL], [test "$have_python_devel" = "yes"]) # ------------------------------------------------------------------------------ -AC_SEARCH_LIBS([mq_open], [rt], [], [AC_MSG_ERROR([*** POSIX RT library not found])]) AC_SEARCH_LIBS([dlsym], [dl], [], [AC_MSG_ERROR([*** Dynamic linking loader library not found])]) save_LIBS="$LIBS" @@ -198,6 +197,9 @@ LIBS= AC_SEARCH_LIBS([cap_init], [cap], [], [AC_MSG_ERROR([*** POSIX caps library not found])]) AC_CHECK_HEADERS([sys/capability.h], [], [AC_MSG_ERROR([*** POSIX caps headers not found])]) CAP_LIBS="$LIBS" +AC_SEARCH_LIBS([mq_open], [rt], [], [AC_MSG_ERROR([*** POSIX RT library not found])]) +RT_LIBS="$LIBS" +AC_SUBST(RT_LIBS) LIBS="$save_LIBS" AC_SUBST(CAP_LIBS) -- cgit v1.2.1 From a6c0353b9268d5b780fb7ff05a10cb5031446e5d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 30 Jul 2013 02:28:22 +0200 Subject: core: open up SendSIGHUP property for transient units --- man/systemd-run.xml | 12 ++++++++++++ src/core/dbus-kill.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- src/core/dbus-kill.h | 2 +- src/core/dbus-scope.c | 4 ++++ src/core/dbus-service.c | 4 ++++ src/run/run.c | 18 +++++++++++++++--- 6 files changed, 82 insertions(+), 6 deletions(-) diff --git a/man/systemd-run.xml b/man/systemd-run.xml index 707d88d766..e1e885178d 100644 --- a/man/systemd-run.xml +++ b/man/systemd-run.xml @@ -160,6 +160,18 @@ along with systemd; If not, see . + + + + + When terminating the scope unit send a SIGHUP + immediately after SIGTERM. This is useful to indicate to + shells and shell-like processes that the connection has been + sewered. Also see SendSIGHUP= in + systemd.kill5. + + + All command-line arguments after the first non-option diff --git a/src/core/dbus-kill.c b/src/core/dbus-kill.c index e970ea329c..beae7da850 100644 --- a/src/core/dbus-kill.c +++ b/src/core/dbus-kill.c @@ -25,12 +25,56 @@ #include "dbus-kill.h" #include "dbus-common.h" -DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_kill_append_mode, kill_mode, KillMode); +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_kill_append_mode, kill_mode, KillMode); const BusProperty bus_kill_context_properties[] = { { "KillMode", bus_kill_append_mode, "s", offsetof(KillContext, kill_mode) }, { "KillSignal", bus_property_append_int, "i", offsetof(KillContext, kill_signal) }, { "SendSIGKILL", bus_property_append_bool, "b", offsetof(KillContext, send_sigkill) }, { "SendSIGHUP", bus_property_append_bool, "b", offsetof(KillContext, send_sighup) }, - { NULL, } + {} }; + +int bus_kill_context_set_transient_property( + Unit *u, + KillContext *c, + const char *name, + DBusMessageIter *i, + UnitSetPropertiesMode mode, + DBusError *error) { + + assert(u); + assert(c); + assert(name); + assert(i); + + if (streq(name, "SendSIGHUP")) { + + if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_BOOLEAN) + return -EINVAL; + + if (mode != UNIT_CHECK) { + dbus_bool_t b; + dbus_message_iter_get_basic(i, &b); + c->send_sighup = b; + } + + return 1; + + } else if (streq(name, "SendSIGKILL")) { + + if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_BOOLEAN) + return -EINVAL; + + if (mode != UNIT_CHECK) { + dbus_bool_t b; + dbus_message_iter_get_basic(i, &b); + c->send_sigkill = b; + } + + return 1; + + } + + return 0; +} diff --git a/src/core/dbus-kill.h b/src/core/dbus-kill.h index 8c8bff5927..7676d98e91 100644 --- a/src/core/dbus-kill.h +++ b/src/core/dbus-kill.h @@ -34,4 +34,4 @@ extern const BusProperty bus_kill_context_properties[]; -int bus_kill_append_mode(DBusMessageIter *i, const char *property, void *data); +int bus_kill_context_set_transient_property(Unit *u, KillContext *c, const char *name, DBusMessageIter *i, UnitSetPropertiesMode mode, DBusError *error); diff --git a/src/core/dbus-scope.c b/src/core/dbus-scope.c index 771820c2d8..497e4520d1 100644 --- a/src/core/dbus-scope.c +++ b/src/core/dbus-scope.c @@ -170,6 +170,10 @@ int bus_scope_set_property( r = bus_scope_set_transient_property(s, name, i, mode, error); if (r != 0) return r; + + r = bus_kill_context_set_transient_property(u, &s->kill_context, name, i, mode, error); + if (r != 0) + return r; } return 0; diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c index 1a44e1fd1b..85b13f01ef 100644 --- a/src/core/dbus-service.c +++ b/src/core/dbus-service.c @@ -324,6 +324,10 @@ int bus_service_set_property( r = bus_service_set_transient_property(s, name, i, mode, error); if (r != 0) return r; + + r = bus_kill_context_set_transient_property(u, &s->kill_context, name, i, mode, error); + if (r != 0) + return r; } return 0; diff --git a/src/run/run.c b/src/run/run.c index c1a0ffb13f..c5d314bdf1 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -35,6 +35,7 @@ static bool arg_remain_after_exit = false; static const char *arg_unit = NULL; static const char *arg_description = NULL; static const char *arg_slice = NULL; +static bool arg_send_sighup = false; static int help(void) { @@ -47,7 +48,8 @@ static int help(void) { " --unit=UNIT Run under the specified unit name\n" " --description=TEXT Description for unit\n" " --slice=SLICE Run in the specified slice\n" - " -r --remain-after-exit Leave service around until explicitly stopped\n", + " -r --remain-after-exit Leave service around until explicitly stopped\n" + " --send-sighup Send SIGHUP when terminating\n", program_invocation_short_name); return 0; @@ -61,7 +63,8 @@ static int parse_argv(int argc, char *argv[]) { ARG_SCOPE, ARG_UNIT, ARG_DESCRIPTION, - ARG_SLICE + ARG_SLICE, + ARG_SEND_SIGHUP, }; static const struct option options[] = { @@ -72,7 +75,8 @@ static int parse_argv(int argc, char *argv[]) { { "unit", required_argument, NULL, ARG_UNIT }, { "description", required_argument, NULL, ARG_DESCRIPTION }, { "slice", required_argument, NULL, ARG_SLICE }, - { "remain-after-exit", required_argument, NULL, 'r' }, + { "remain-after-exit", no_argument, NULL, 'r' }, + { "send-sighup", no_argument, NULL, ARG_SEND_SIGHUP }, { NULL, 0, NULL, 0 }, }; @@ -114,6 +118,10 @@ static int parse_argv(int argc, char *argv[]) { arg_slice = optarg; break; + case ARG_SEND_SIGHUP: + arg_send_sighup = true; + break; + case 'r': arg_remain_after_exit = true; break; @@ -174,6 +182,10 @@ static int message_start_transient_unit_new(sd_bus *bus, const char *name, sd_bu return r; } + r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", arg_send_sighup); + if (r < 0) + return r; + *ret = m; m = NULL; -- cgit v1.2.1 From c3df8d3dde5a032b382b3f59c016c1d0b7741ae8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 30 Jul 2013 02:50:44 +0200 Subject: core: make sure scope attributes survive a reload --- src/core/dbus-kill.c | 6 ++++++ src/core/dbus-scope.c | 2 ++ src/core/load-fragment-gperf.gperf.m4 | 2 ++ 3 files changed, 10 insertions(+) diff --git a/src/core/dbus-kill.c b/src/core/dbus-kill.c index beae7da850..80e15e3fca 100644 --- a/src/core/dbus-kill.c +++ b/src/core/dbus-kill.c @@ -55,8 +55,11 @@ int bus_kill_context_set_transient_property( if (mode != UNIT_CHECK) { dbus_bool_t b; + dbus_message_iter_get_basic(i, &b); c->send_sighup = b; + + unit_write_drop_in_format(u, mode, name, "[Scope]\nSendSIGHUP=%s\n", yes_no(b)); } return 1; @@ -68,8 +71,11 @@ int bus_kill_context_set_transient_property( if (mode != UNIT_CHECK) { dbus_bool_t b; + dbus_message_iter_get_basic(i, &b); c->send_sigkill = b; + + unit_write_drop_in_format(u, mode, name, "[Scope]\nSendSIGKILL4=%s\n", yes_no(b)); } return 1; diff --git a/src/core/dbus-scope.c b/src/core/dbus-scope.c index 497e4520d1..783a969fb3 100644 --- a/src/core/dbus-scope.c +++ b/src/core/dbus-scope.c @@ -138,6 +138,8 @@ static int bus_scope_set_transient_property( dbus_message_iter_get_basic(i, &t); s->timeout_stop_usec = t; + + unit_write_drop_in_format(UNIT(s), mode, name, "[Scope]\nTimeoutStopSec=%lluus\n", (unsigned long long) t); } return 1; diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index 2b0106ffe2..33c6880b5d 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -263,6 +263,8 @@ m4_dnl CGROUP_CONTEXT_CONFIG_ITEMS(Slice)m4_dnl m4_dnl CGROUP_CONTEXT_CONFIG_ITEMS(Scope)m4_dnl +KILL_CONTEXT_CONFIG_ITEMS(Scope)m4_dnl +Scope.TimeoutStopSec, config_parse_sec, 0, offsetof(Scope, timeout_stop_usec) m4_dnl The [Install] section is ignored here. Install.Alias, NULL, 0, 0 Install.WantedBy, NULL, 0, 0 -- cgit v1.2.1 From 07beec1244817a0e6e9d79798f7c65bd89b23549 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 30 Jul 2013 02:51:07 +0200 Subject: update TODO --- TODO | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index fe2af675b0..99122b5715 100644 --- a/TODO +++ b/TODO @@ -39,10 +39,10 @@ CGroup Rework Completion: * wiki: document new bus APIs of PID 1 (transient units, Reloading signal) -* Send SIGHUP and SIGTERM in session scopes - Features: +* for transient units, instead of writing out drop-ins for all properties consider serializing them in the normal serialization stream + * logind: when logging out, remove user-owned sysv and posix IPC objects * session scopes/user unit: add RequiresMountsFor for the home directory of the user -- cgit v1.2.1 From 743e89454093361653b85ff394d0434c0714a92d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 30 Jul 2013 02:51:12 +0200 Subject: logind: make sure login sessions are terminated with SIGHUP bash ignores SIGTERM, and can only be terminated cleanly via SIGHUP. Hence make sure that we the scope unit for the session is created with SendSIGHUP enabled. --- src/login/logind-dbus.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 7b9bd201b2..ed5d8d888c 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -2526,11 +2526,11 @@ int manager_start_scope( DBusError *error, char **job) { + const char *timeout_stop_property = "TimeoutStopUSec", *send_sighup_property = "SendSIGHUP", *pids_property = "PIDs"; _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL; DBusMessageIter iter, sub, sub2, sub3, sub4; - const char *timeout_stop_property = "TimeoutStopUSec"; - const char *pids_property = "PIDs"; uint64_t timeout = 500 * USEC_PER_MSEC; + dbus_bool_t send_sighup = true; const char *fail = "fail"; uint32_t u; @@ -2607,6 +2607,16 @@ int manager_start_scope( !dbus_message_iter_close_container(&sub, &sub2)) return log_oom(); + /* Make sure that the session shells are terminated with + * SIGHUP since bash and friends tend to ignore SIGTERM */ + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &send_sighup_property) || + !dbus_message_iter_open_container(&sub2, DBUS_TYPE_VARIANT, "b", &sub3) || + !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_BOOLEAN, &send_sighup) || + !dbus_message_iter_close_container(&sub2, &sub3) || + !dbus_message_iter_close_container(&sub, &sub2)) + return log_oom(); + u = pid; if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) || !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &pids_property) || @@ -2615,8 +2625,10 @@ int manager_start_scope( !dbus_message_iter_append_basic(&sub4, DBUS_TYPE_UINT32, &u) || !dbus_message_iter_close_container(&sub3, &sub4) || !dbus_message_iter_close_container(&sub2, &sub3) || - !dbus_message_iter_close_container(&sub, &sub2) || - !dbus_message_iter_close_container(&iter, &sub)) + !dbus_message_iter_close_container(&sub, &sub2)) + return log_oom(); + + if (!dbus_message_iter_close_container(&iter, &sub)) return log_oom(); reply = dbus_connection_send_with_reply_and_block(manager->bus, m, -1, error); -- cgit v1.2.1 From 7959ff9914a6f3a59dbff95c199bcc540b70ac94 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 30 Jul 2013 03:38:55 +0200 Subject: build-sys: support old glibc versions without clock_gettime() --- configure.ac | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 76aa2a920a..f71e15c456 100644 --- a/configure.ac +++ b/configure.ac @@ -191,17 +191,22 @@ AM_CONDITIONAL([HAVE_PYTHON_DEVEL], [test "$have_python_devel" = "yes"]) # ------------------------------------------------------------------------------ AC_SEARCH_LIBS([dlsym], [dl], [], [AC_MSG_ERROR([*** Dynamic linking loader library not found])]) +AC_CHECK_HEADERS([sys/capability.h], [], [AC_MSG_ERROR([*** POSIX caps headers not found])]) + +# unconditionally pull-in librt with old glibc versions +AC_SEARCH_LIBS([clock_gettime], [rt], [], []) save_LIBS="$LIBS" LIBS= AC_SEARCH_LIBS([cap_init], [cap], [], [AC_MSG_ERROR([*** POSIX caps library not found])]) -AC_CHECK_HEADERS([sys/capability.h], [], [AC_MSG_ERROR([*** POSIX caps headers not found])]) CAP_LIBS="$LIBS" +AC_SUBST(CAP_LIBS) + +LIBS= AC_SEARCH_LIBS([mq_open], [rt], [], [AC_MSG_ERROR([*** POSIX RT library not found])]) RT_LIBS="$LIBS" AC_SUBST(RT_LIBS) LIBS="$save_LIBS" -AC_SUBST(CAP_LIBS) AC_CHECK_FUNCS([fanotify_init fanotify_mark]) AC_CHECK_FUNCS([__secure_getenv secure_getenv]) -- cgit v1.2.1 From e736cf3582c03273f95bc6f97245b04783fd626b Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Mon, 29 Jul 2013 18:18:43 -0400 Subject: udev-rules: report rule parsing errors from get_key --- src/udev/udev-rules.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index 769b670b20..e4facd7bd2 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -1066,8 +1066,15 @@ static int add_rule(struct udev_rules *rules, char *line, char *value; enum operation_type op; - if (get_key(rules->udev, &linepos, &key, &op, &value) != 0) + if (get_key(rules->udev, &linepos, &key, &op, &value) != 0) { + /* If we aren't at the end of the line, this is a parsing error. + * Make a best effort to describe where the problem is. */ + if (*linepos != '\n') + log_error("invalid key/value pair in file %s on line %u," + "starting at character %lu\n", + filename, lineno, linepos - line + 1); break; + } if (streq(key, "ACTION")) { if (op > OP_MATCH_MAX) { -- cgit v1.2.1 From e861b62154173b730c3fd8ca040641fba8870bb6 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Mon, 29 Jul 2013 17:48:29 +0200 Subject: simplify bash completion for kernel-install --- shell-completion/bash/kernel-install | 64 +++++++++++++----------------------- 1 file changed, 23 insertions(+), 41 deletions(-) diff --git a/shell-completion/bash/kernel-install b/shell-completion/bash/kernel-install index 1832d4aba4..7cd2494cf7 100644 --- a/shell-completion/bash/kernel-install +++ b/shell-completion/bash/kernel-install @@ -3,6 +3,7 @@ # This file is part of systemd. # # Copyright 2013 Kay Sievers +# Copyright 2013 Harald Hoyer # # systemd is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -17,49 +18,30 @@ # You should have received a copy of the GNU Lesser General Public License # along with systemd; If not, see . -__contains_word () { - local word=$1; shift - for w in $*; do [[ $w = $word ]] && return 0; done - return 1 -} - _kernel_install() { - local i verb comps - local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} - local OPTS='-h --help' - - local -A VERBS=( - [ADD]='add' - [REMOVE]='remove' - ) - - for ((i=0; $i <= $COMP_CWORD; i++)); do - if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} && - ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then - verb=${COMP_WORDS[i]} - break - fi - done - - if [[ -z $verb && $cur = -* ]]; then - COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") ) - return 0 - fi - - if [[ -z $verb ]]; then - comps=${VERBS[*]} - - elif __contains_word "$verb" ${VERBS[ADD]}; then - if [[ $prev = "$verb" ]]; then - comps=$(cd /lib/modules; echo [0-9]*) - elif [[ $prev = [0-9]* ]]; then - comps=$(echo /boot/vmlinuz-$prev*) - fi - - elif __contains_word "$verb" ${VERBS[REMOVE]}; then + local comps + local MACHINE_ID + local cur=${COMP_WORDS[COMP_CWORD]} + + case $COMP_CWORD in + 1) + comps="add remove" + ;; + 2) comps=$(cd /lib/modules; echo [0-9]*) - - fi + if [[ ${COMP_WORDS[1]} == "remove" ]] && [[ -f /etc/machine-id ]]; then + read MACHINE_ID < /etc/machine-id + if [[ $MACHINE_ID ]] && ( [[ -d /boot/$MACHINE_ID ]] || [[ -L /boot/$MACHINE_ID ]] ); then + comps=$(cd "/boot/$MACHINE_ID"; echo [0-9]*) + fi + fi + ;; + 3) + [[ "$cur" ]] || cur=/boot/vmlinuz-${COMP_WORDS[2]} + comps=$(compgen -f -- "$cur") + compopt -o filenames + ;; + esac COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) return 0 -- cgit v1.2.1 From 095b30cbf976b6c82a10c16bef76fa5b4c03f658 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 29 Jul 2013 19:49:55 -0400 Subject: test-fileio: use random name for written file If two instances of test-fileio were run in parallel, they could fail when trying to write the same file. This predictable name in /tmp/ wasn't actually a security issue, because write_env_file would not follow symlinks, so this could be an issue only when running tests in parallel. --- src/test/test-fileio.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c index b08e796b7d..76a43d9b69 100644 --- a/src/test/test-fileio.c +++ b/src/test/test-fileio.c @@ -29,7 +29,8 @@ #include "env-util.h" static void test_parse_env_file(void) { - char t[] = "/tmp/test-parse-env-file-XXXXXX"; + char t[] = "/tmp/test-fileio-in-XXXXXX", + p[] = "/tmp/test-fileio-out-XXXXXX"; int fd, r; FILE *f; _cleanup_free_ char *one = NULL, *two = NULL, *three = NULL, *four = NULL, *five = NULL, @@ -38,6 +39,8 @@ static void test_parse_env_file(void) { char **i; unsigned k; + assert_se(mktemp(p)); + fd = mkostemp(t, O_CLOEXEC); assert_se(fd >= 0); @@ -83,7 +86,7 @@ static void test_parse_env_file(void) { assert_se(streq(a[9], "ten=")); assert_se(a[10] == NULL); - strv_env_clean_log(a, "/tmp/test-fileio"); + strv_env_clean_log(a, "test"); k = 0; STRV_FOREACH(i, b) { @@ -129,14 +132,14 @@ static void test_parse_env_file(void) { assert_se(streq(nine, "nineval")); assert_se(ten == NULL); - r = write_env_file("/tmp/test-fileio", a); + r = write_env_file(p, a); assert_se(r >= 0); - r = load_env_file("/tmp/test-fileio", NULL, &b); + r = load_env_file(p, NULL, &b); assert_se(r >= 0); unlink(t); - unlink("/tmp/test-fileio"); + unlink(p); } static void test_executable_is_script(void) { -- cgit v1.2.1 From 751e75769a0a8a255e1a47656f639768879e9518 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Tue, 30 Jul 2013 09:07:20 -0400 Subject: test-unit-file: return error without dumping core on permission error --- src/test/test-unit-file.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c index a7fe77af24..2075e86115 100644 --- a/src/test/test-unit-file.c +++ b/src/test/test-unit-file.c @@ -36,7 +36,7 @@ #include "strv.h" #include "fileio.h" -static void test_unit_file_get_set(void) { +static int test_unit_file_get_set(void) { int r; Hashmap *h; Iterator i; @@ -46,13 +46,17 @@ static void test_unit_file_get_set(void) { assert(h); r = unit_file_get_list(UNIT_FILE_SYSTEM, NULL, h); - log_info("unit_file_get_list: %s", strerror(-r)); - assert(r >= 0); + log_full(r == 0 ? LOG_INFO : LOG_ERR, + "unit_file_get_list: %s", strerror(-r)); + if (r < 0) + return EXIT_FAILURE; HASHMAP_FOREACH(p, h, i) printf("%s = %s\n", p->path, unit_file_state_to_string(p->state)); unit_file_list_free(h); + + return 0; } static void check_execcommand(ExecCommand *c, @@ -351,11 +355,12 @@ static void test_install_printf(void) { #pragma GCC diagnostic pop int main(int argc, char *argv[]) { + int r; log_parse_environment(); log_open(); - test_unit_file_get_set(); + r = test_unit_file_get_set(); test_config_parse_exec(); test_load_env_file_1(); test_load_env_file_2(); @@ -363,5 +368,5 @@ int main(int argc, char *argv[]) { test_load_env_file_4(); test_install_printf(); - return 0; + return r; } -- cgit v1.2.1 From a72d698d0d9ff9c158155b44cdc77376df31a317 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Tue, 30 Jul 2013 12:46:23 -0400 Subject: bash-completion: use a better definition of __contains_word - scope the iterator var - use the correct, quoted, non-expansion prone positional parameter notation - prevent expansion on RHS of comparison - remove unneeded explicit returns. This really should be defined only once... --- shell-completion/bash/hostnamectl | 7 ++++--- shell-completion/bash/journalctl | 7 ++++--- shell-completion/bash/localectl | 7 ++++--- shell-completion/bash/loginctl | 7 ++++--- shell-completion/bash/systemctl | 7 ++++--- shell-completion/bash/systemd-analyze | 7 ++++--- shell-completion/bash/systemd-coredumpctl | 7 ++++--- shell-completion/bash/timedatectl | 7 ++++--- shell-completion/bash/udevadm | 7 ++++--- 9 files changed, 36 insertions(+), 27 deletions(-) diff --git a/shell-completion/bash/hostnamectl b/shell-completion/bash/hostnamectl index a57bffe15f..38ab1344f3 100644 --- a/shell-completion/bash/hostnamectl +++ b/shell-completion/bash/hostnamectl @@ -18,9 +18,10 @@ # along with systemd; If not, see . __contains_word () { - local word=$1; shift - for w in $*; do [[ $w = $word ]] && return 0; done - return 1 + local w word=$1; shift + for w in "$@"; do + [[ $w = "$word" ]] && return + done } _hostnamectl() { diff --git a/shell-completion/bash/journalctl b/shell-completion/bash/journalctl index 29bf6bca3f..3c40d57a98 100644 --- a/shell-completion/bash/journalctl +++ b/shell-completion/bash/journalctl @@ -18,9 +18,10 @@ # along with systemd; If not, see . __contains_word () { - local word=$1; shift - for w in $*; do [[ $w = $word ]] && return 0; done - return 1 + local w word=$1; shift + for w in "$@"; do + [[ $w = "$word" ]] && return + done } __journal_fields=(MESSAGE{,_ID} PRIORITY CODE_{FILE,LINE,FUNC} diff --git a/shell-completion/bash/localectl b/shell-completion/bash/localectl index ef19f01461..bec9e78c64 100644 --- a/shell-completion/bash/localectl +++ b/shell-completion/bash/localectl @@ -18,9 +18,10 @@ # along with systemd; If not, see . __contains_word () { - local word=$1; shift - for w in $*; do [[ $w = $word ]] && return 0; done - return 1 + local w word=$1; shift + for w in "$@"; do + [[ $w = "$word" ]] && return + done } _localectl() { diff --git a/shell-completion/bash/loginctl b/shell-completion/bash/loginctl index 1844085d49..3104b305fa 100644 --- a/shell-completion/bash/loginctl +++ b/shell-completion/bash/loginctl @@ -18,9 +18,10 @@ # along with systemd; If not, see . __contains_word () { - local word=$1; shift - for w in $*; do [[ $w = $word ]] && return 0; done - return 1 + local w word=$1; shift + for w in "$@"; do + [[ $w = "$word" ]] && return + done } __get_all_sessions () { loginctl list-sessions | { while read -r a b; do printf "%s\n" "$a"; done; } ; } diff --git a/shell-completion/bash/systemctl b/shell-completion/bash/systemctl index ceca3348ed..517b49a6af 100644 --- a/shell-completion/bash/systemctl +++ b/shell-completion/bash/systemctl @@ -32,9 +32,10 @@ __systemd_properties() { } __contains_word () { - local word=$1; shift - for w in $*; do [[ $w = $word ]] && return 0; done - return 1 + local w word=$1; shift + for w in "$@"; do + [[ $w = "$word" ]] && return + done } __filter_units_by_property () { diff --git a/shell-completion/bash/systemd-analyze b/shell-completion/bash/systemd-analyze index 11276ef09c..33833aac10 100644 --- a/shell-completion/bash/systemd-analyze +++ b/shell-completion/bash/systemd-analyze @@ -19,9 +19,10 @@ # along with systemd; If not, see . __contains_word () { - local word=$1; shift - for w in $*; do [[ $w = $word ]] && return 0; done - return 1 + local w word=$1; shift + for w in "$@"; do + [[ $w = "$word" ]] && return + done } _systemd_analyze() { diff --git a/shell-completion/bash/systemd-coredumpctl b/shell-completion/bash/systemd-coredumpctl index 4bbece7347..805e84824e 100644 --- a/shell-completion/bash/systemd-coredumpctl +++ b/shell-completion/bash/systemd-coredumpctl @@ -18,9 +18,10 @@ # along with systemd; If not, see . __contains_word () { - local word=$1; shift - for w in $*; do [[ $w = $word ]] && return 0; done - return 1 + local w word=$1; shift + for w in "$@"; do + [[ $w = "$word" ]] && return + done } __journal_fields=(MESSAGE{,_ID} PRIORITY CODE_{FILE,LINE,FUNC} diff --git a/shell-completion/bash/timedatectl b/shell-completion/bash/timedatectl index 2842b31069..c6a6545257 100644 --- a/shell-completion/bash/timedatectl +++ b/shell-completion/bash/timedatectl @@ -18,9 +18,10 @@ # along with systemd; If not, see . __contains_word () { - local word=$1; shift - for w in $*; do [[ $w = $word ]] && return 0; done - return 1 + local w word=$1; shift + for w in "$@"; do + [[ $w = "$word" ]] && return + done } _timedatectl() { diff --git a/shell-completion/bash/udevadm b/shell-completion/bash/udevadm index e9ad179203..e521a3bbb6 100644 --- a/shell-completion/bash/udevadm +++ b/shell-completion/bash/udevadm @@ -18,9 +18,10 @@ # along with systemd; If not, see . __contains_word () { - local word=$1; shift - for w in $*; do [[ $w = $word ]] && return 0; done - return 1 + local w word=$1; shift + for w in "$@"; do + [[ $w = "$word" ]] && return + done } __get_all_sysdevs() { -- cgit v1.2.1 From b5b7ea750388919eee6087eb63f08903b57447cf Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Tue, 30 Jul 2013 13:00:00 -0400 Subject: bash-completion: simplify udevadm completion The AA is unnecessary and only adds needless complexity. Replace it with a case statement instead of repeatedly calling __contains_word to overglorify string equalities. --- shell-completion/bash/udevadm | 97 ++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 52 deletions(-) diff --git a/shell-completion/bash/udevadm b/shell-completion/bash/udevadm index e521a3bbb6..8ad855060c 100644 --- a/shell-completion/bash/udevadm +++ b/shell-completion/bash/udevadm @@ -34,68 +34,61 @@ _udevadm() { local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} local OPTS='-h --help --version --debug' - local -A VERBS=( - [INFO]='info' - [TRIGGER]='trigger' - [SETTLE]='settle' - [CONTROL]='control' - [MONITOR]='monitor' - [HWDB]='hwdb' - [TESTBUILTIN]='test-builtin' - [TEST]='test' - ) + local verbs=(info trigger settle control monitor hwdb test-builtin test) - for ((i=0; $i <= $COMP_CWORD; i++)); do - if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} && + for ((i=0; i <= COMP_CWORD; i++)); do + if __contains_word "${COMP_WORDS[i]}" "${verbs[@]}" && ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then verb=${COMP_WORDS[i]} break fi done - if [[ -z $verb && $cur = -* ]]; then - COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") ) + if [[ -z $verb ]]; then + COMPREPLY=( $(compgen -W '${OPTS[*]} ${verbs[*]}' -- "$cur") ) return 0 fi - if [[ -z $verb ]]; then - comps=${VERBS[*]} - - elif __contains_word "$verb" ${VERBS[INFO]}; then - if [[ $cur = -* ]]; then - comps='--help --query= --path= --name= --root --attribute-walk --export-db --cleanup-db' - else - comps=$( __get_all_sysdevs ) - fi - - elif __contains_word "$verb" ${VERBS[TRIGGER]}; then - comps='--help --verbose --dry-run --type= --action= --subsystem-match= - --subsystem-nomatch= --attr-match= --attr-nomatch= --property-match= - --tag-match= --sysname-match= --parent-match=' - - elif __contains_word "$verb" ${VERBS[SETTLE]}; then - comps='--help --timeout= --seq-start= --seq-end= --exit-if-exists= --quiet' - - elif __contains_word "$verb" ${VERBS[CONTROL]}; then - comps='--help --exit --log-priority= --stop-exec-queue --start-exec-queue - --reload --property= --children-max= --timeout=' - - elif __contains_word "$verb" ${VERBS[MONITOR]}; then - comps='--help --kernel --udev --property --subsystem-match= --tag-match=' - - elif __contains_word "$verb" ${VERBS[HWDB]}; then - comps='--help --update --test=' - - elif __contains_word "$verb" ${VERBS[TEST]}; then - if [[ $cur = -* ]]; then - comps='--help --action=' - else - comps=$( __get_all_sysdevs ) - fi - - elif __contains_word "$verb" ${VERBS[TESTBUILTIN]}; then - comps='blkid btrfs hwdb input_id keyboard kmod net_id path_id usb_id uaccess' - fi + case $verb in + 'info') + if [[ $cur = -* ]]; then + comps='--help --query= --path= --name= --root --attribute-walk --export-db --cleanup-db' + else + comps=$( __get_all_sysdevs ) + fi + ;; + 'trigger') + comps='--help --verbose --dry-run --type= --action= --subsystem-match= + --subsystem-nomatch= --attr-match= --attr-nomatch= --property-match= + --tag-match= --sysname-match= --parent-match=' + ;; + 'settle') + comps='--help --timeout= --seq-start= --seq-end= --exit-if-exists= --quiet' + ;; + 'control') + comps='--help --exit --log-priority= --stop-exec-queue --start-exec-queue + --reload --property= --children-max= --timeout=' + ;; + 'monitor') + comps='--help --kernel --udev --property --subsystem-match= --tag-match=' + ;; + 'hwdb') + comps='--help --update --test=' + ;; + 'test') + if [[ $cur = -* ]]; then + comps='--help --action=' + else + comps=$( __get_all_sysdevs ) + fi + ;; + 'test-builtin') + comps='blkid btrfs hwdb input_id keyboard kmod net_id path_id usb_id uaccess' + ;; + *) + comps=${VERBS[*]} + ;; + esac COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) return 0 -- cgit v1.2.1 From 4a9e80b3b5d0d3c0cabac01c35db18d95f27c9c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Wed, 31 Jul 2013 23:12:17 +0200 Subject: Add /usr/share/keymaps to localectl supported locations. This is the standard upstream location where kbd installs keymaps. --- src/locale/localectl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/locale/localectl.c b/src/locale/localectl.c index cd7356a1e1..8259c0af5f 100644 --- a/src/locale/localectl.c +++ b/src/locale/localectl.c @@ -538,6 +538,7 @@ static int list_vconsole_keymaps(DBusConnection *bus, char **args, unsigned n) { if (!keymaps) return log_oom(); + nftw("/usr/share/keymaps/", nftw_cb, 20, FTW_MOUNT|FTW_PHYS); nftw("/usr/share/kbd/keymaps/", nftw_cb, 20, FTW_MOUNT|FTW_PHYS); nftw("/usr/lib/kbd/keymaps/", nftw_cb, 20, FTW_MOUNT|FTW_PHYS); nftw("/lib/kbd/keymaps/", nftw_cb, 20, FTW_MOUNT|FTW_PHYS); -- cgit v1.2.1 From 58a6e9039afcb0bf6b712f51fd1f4a9efd0eb1c9 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Thu, 1 Aug 2013 12:31:38 +0200 Subject: 80-net-name-slot.rules: only rename network interfaces on ACTION=="add" Otherwise systemd-udevd will rename on "change" and "move" events, resulting in weird renames in combination with biosdevname systemd-udevd[355]: renamed network interface eth0 to em1 systemd-udevd[355]: renamed network interface eth1 to p3p2 systemd-udevd[357]: renamed network interface eth0 to p3p1 systemd-udevd[429]: renamed network interface p3p2 to ens3f1 systemd-udevd[428]: renamed network interface p3p1 to ens3f0 systemd-udevd[426]: renamed network interface em1 to enp63s0 or systemd-udevd[356]: renamed network interface eth0 to em1 systemd-udevd[356]: renamed network interface eth0 to p3p1 systemd-udevd[420]: renamed network interface p3p1 to ens3f0 systemd-udevd[418]: renamed network interface em1 to enp63s0 systemd-udevd[421]: renamed network interface eth1 to p3p1 --- rules/80-net-name-slot.rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/80-net-name-slot.rules b/rules/80-net-name-slot.rules index 15b5bc4107..c5f1b3885b 100644 --- a/rules/80-net-name-slot.rules +++ b/rules/80-net-name-slot.rules @@ -1,6 +1,6 @@ # do not edit this file, it will be overwritten on update -ACTION=="remove", GOTO="net_name_slot_end" +ACTION!="add", GOTO="net_name_slot_end" SUBSYSTEM!="net", GOTO="net_name_slot_end" NAME!="", GOTO="net_name_slot_end" -- cgit v1.2.1 From 4f87c47b35cf9c1f58872559ae67a2656712fdd6 Mon Sep 17 00:00:00 2001 From: William Giokas <1007380@gmail.com> Date: Thu, 25 Jul 2013 00:57:05 -0500 Subject: zsh_completion: fix zsh completion installation Moved zsh shell completion to shell-completion/zsh/_systemd for automake's sake. Also allow users to specify where the files should go with:: ./configure --with-zshcompletiondir=/path/to/some/where and by default going to `$datadir/zsh/site-functions` --- Makefile.am | 8 +- configure.ac | 6 + shell-completion/systemd-zsh-completion.zsh | 1102 --------------------------- shell-completion/zsh/_systemd | 1102 +++++++++++++++++++++++++++ 4 files changed, 1113 insertions(+), 1105 deletions(-) delete mode 100644 shell-completion/systemd-zsh-completion.zsh create mode 100644 shell-completion/zsh/_systemd diff --git a/Makefile.am b/Makefile.am index c81c40c594..27e03cefad 100644 --- a/Makefile.am +++ b/Makefile.am @@ -68,6 +68,7 @@ pkgconfigdatadir=$(datadir)/pkgconfig pkgconfiglibdir=$(libdir)/pkgconfig polkitpolicydir=$(datadir)/polkit-1/actions bashcompletiondir=@bashcompletiondir@ +zshcompletiondir=@zshcompletiondir@ rpmmacrosdir=$(prefix)/lib/rpm/macros.d sysvinitdir=$(SYSTEM_SYSVINIT_PATH) sysvrcnddir=$(SYSTEM_SYSVRCND_PATH) @@ -342,6 +343,9 @@ dist_bashcompletion_DATA = \ shell-completion/bash/udevadm \ shell-completion/bash/kernel-install +dist_zshcompletion_DATA = \ + shell-completion/zsh/_systemd + dist_sysctl_DATA = \ sysctl.d/50-default.conf @@ -4234,9 +4238,6 @@ EXTRA_DIST += \ docs/sysvinit/README.in \ docs/var-log/README.in -EXTRA_DIST += \ - shell-completion/systemd-zsh-completion.zsh - SOCKETS_TARGET_WANTS += \ systemd-initctl.socket \ systemd-shutdownd.socket @@ -4351,6 +4352,7 @@ DISTCHECK_CONFIGURE_FLAGS = \ --with-dbussystemservicedir=$$dc_install_base/$(dbussystemservicedir) \ --with-dbusinterfacedir=$$dc_install_base/$(dbusinterfacedir) \ --with-bashcompletiondir=$$dc_install_base/$(bashcompletiondir) \ + --with-zshcompletiondir=$$dc_install_base/$(zshcompletiondir) \ --with-pamlibdir=$$dc_install_base/$(pamlibdir) \ --with-rootprefix=$$dc_install_base \ --disable-split-usr diff --git a/configure.ac b/configure.ac index f71e15c456..0ecc71632b 100644 --- a/configure.ac +++ b/configure.ac @@ -915,6 +915,10 @@ AC_ARG_WITH([bashcompletiondir], with_bashcompletiondir=${datadir}/bash-completion/completions ])]) +AC_ARG_WITH([zshcompletiondir], + AS_HELP_STRING([--with-zshcompletiondir=DIR], [Zsh completions directory]), + [], [with_zshcompletiondir=${datadir}/zsh/site-functions]) + AC_ARG_WITH([rootprefix], AS_HELP_STRING([--with-rootprefix=DIR], [rootfs directory prefix for config files and kernel modules]), [], [with_rootprefix=${ac_default_prefix}]) @@ -959,6 +963,7 @@ AC_SUBST([dbussessionservicedir], [$with_dbussessionservicedir]) AC_SUBST([dbussystemservicedir], [$with_dbussystemservicedir]) AC_SUBST([dbusinterfacedir], [$with_dbusinterfacedir]) AC_SUBST([bashcompletiondir], [$with_bashcompletiondir]) +AC_SUBST([zshcompletiondir], [$with_zshcompletiondir]) AC_SUBST([pamlibdir], [$with_pamlibdir]) AC_SUBST([rootprefix], [$with_rootprefix]) AC_SUBST([rootlibdir], [$with_rootlibdir]) @@ -1036,6 +1041,7 @@ AC_MSG_RESULT([ D-Bus system dir: ${with_dbussystemservicedir} D-Bus interfaces dir: ${with_dbusinterfacedir} Bash completions dir: ${with_bashcompletiondir} + Zsh completions dir: ${with_zshcompletiondir} Extra start script: ${RC_LOCAL_SCRIPT_PATH_START} Extra stop script: ${RC_LOCAL_SCRIPT_PATH_STOP} Debug shell: ${SUSHELL} @ ${DEBUGTTY} diff --git a/shell-completion/systemd-zsh-completion.zsh b/shell-completion/systemd-zsh-completion.zsh deleted file mode 100644 index 1ab1311ec1..0000000000 --- a/shell-completion/systemd-zsh-completion.zsh +++ /dev/null @@ -1,1102 +0,0 @@ -#compdef systemctl loginctl journalctl hostnamectl localectl timedatectl systemd-coredumpctl udevadm systemd-analyze systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-inhibit systemd-machine-id-setup systemd-notify systemd-nspawn systemd-tmpfiles systemd-tty-ask-password-agent machinectl - -_ctls() -{ - local curcontext="$curcontext" state lstate line - case "$service" in - systemctl) - # -s for aggregated options like -aP - _arguments -s \ - {-h,--help}'[Show help]' \ - '--version[Show package version]' \ - {-t,--type=}'[List only units of a particular type]:unit type:(automount device mount path service snapshot socket swap target timer)' \ - \*{-p,--property=}'[Show only properties by specific name]:unit property' \ - {-a,--all}'[Show all units/properties, including dead/empty ones]' \ - '--reverse[Show reverse dependencies]' \ - '--after[Show units ordered after]' \ - '--before[Show units ordered before]' \ - '--failed[Show only failed units]' \ - {-l,--full}"[Don't ellipsize unit names on output]" \ - '--fail[When queueing a new job, fail if conflicting jobs are pending]' \ - '--ignore-dependencies[When queueing a new job, ignore all its dependencies]' \ - '--kill-who=[Who to send signal to]:killwho:(main control all)' \ - {-s,--signal=}'[Which signal to send]:signal:_signals' \ - {-H,--host=}'[Show information for remote host]:userathost:_hosts_or_user_at_host' \ - {-P,--privileged}'[Acquire privileges before execution]' \ - {-q,--quiet}'[Suppress output]' \ - '--no-block[Do not wait until operation finished]' \ - "--no-wall[Don't send wall message before halt/power-off/reboot]" \ - "--no-reload[When enabling/disabling unit files, don't reload daemon configuration]" \ - '--no-legend[Do not print a legend, i.e. the column headers and the footer with hints]' \ - '--no-pager[Do not pipe output into a pager]' \ - '--no-ask-password[Do not ask for system passwords]' \ - '--system[Connect to system manager]' \ - '--user[Connect to user service manager]' \ - '--global[Enable/disable unit files globally]' \ - {-f,--force}'[When enabling unit files, override existing symlinks. When shutting down, execute action immediately]' \ - '--root=[Enable unit files in the specified root directory]:directory:_directories' \ - '--runtime[Enable unit files only temporarily until next reboot]' \ - {-n,--lines=}'[Journal entries to show]:number of entries' \ - {-o,--output=}'[Change journal output mode]:modes:_outputmodes' \ - '*::systemctl command:_systemctl_command' - ;; - loginctl) - _arguments -s \ - {-h,--help}'[Show help]' \ - '--version[Show package version]' \ - \*{-p,--property=}'[Show only properties by this name]:unit property' \ - {-a,--all}'[Show all properties, including empty ones]' \ - '--kill-who=[Who to send signal to]:killwho:(main control all)' \ - {-s,--signal=}'[Which signal to send]:signal:_signals' \ - '--no-ask-password[Do not ask for system passwords]' \ - {-H,--host=}'[Show information for remote host]:userathost:_hosts_or_user_at_host' \ - {-P,--privileged}'[Acquire privileges before execution]' \ - '--no-pager[Do not pipe output into a pager]' \ - '*::loginctl command:_loginctl_command' - ;; - - hostnamectl) - _arguments -s \ - {-h,--help}'[Show this help]' \ - '--version[Show package version]' \ - '--transient[Only set transient hostname]' \ - '--static[Only set static hostname]' \ - '--pretty[Only set pretty hostname]' \ - '--no-ask-password[Do not prompt for password]' \ - {-H,--host=}'[Operate on remote host]:userathost:_hosts_or_user_at_host' \ - '*::hostnamectl commands:_hostnamectl_command' - ;; - journalctl) - _arguments -s \ - '--since=[Start showing entries newer or of the specified date]:YYYY-MM-DD HH\:MM\:SS' \ - '--until=[Stop showing entries older or of the specified date]:YYYY-MM-DD HH\:MM\:SS' \ - {-c,--cursor=}'[Start showing entries from specified cursor]:cursors:_journal_fields __CURSORS' \ - '--system[Show system and kernel messages]' \ - '--user[Show messages from user services]' \ - {-b,--this-boot}'[Show data only from current boot]' \ - {-u,--unit=}'[Show data only from the specified unit]:units:_journal_fields _SYSTEMD_UNIT' \ - '--user-unit[Show data only from the specified user session unit]:units:_journal_fields _SYSTEMD_USER_UNIT' \ - {-p,--priority=}'[Show only messages within the specified priority range]:priority:_journal_fields PRIORITY' \ - {-f,--follow}'[Follow journal]' \ - {-n,--lines=}'[Number of journal entries to show]:integer' \ - '--no-tail[Show all lines, even in follow mode]' \ - {-o,--output=}'[Change journal output mode]:output modes:_outputmodes' \ - {-l,--full}'[Show long fields in full]' \ - {-a,--all}'[Show all fields, including long and unprintable]' \ - {-q,--quiet}"[Don't show privilege warning]" \ - '--no-pager[Do not pipe output into a pager]' \ - {-m,--merge}'[Show entries from all available journals]' \ - {-D,--directory=}'[Show journal files from directory]:directories:_directories' \ - '--interval=[Time interval for changing the FSS sealing key]:time interval' \ - '--verify-key=[Specify FSS verification key]:FSS key' \ - {-h,--help}'[Show this help]' \ - '--version[Show package version]' \ - '--new-id128[Generate a new 128 Bit ID]' \ - '--header[Show journal header information]' \ - '--disk-usage[Show total disk usage]' \ - {-F,--field=}'[List all values a certain field takes]:Fields:_list_fields' \ - '--setup-keys[Generate new FSS key pair]' \ - '--verify[Verify journal file consistency]' \ - '--list-catalog[List messages in catalog]' \ - '--update-catalog[Update binary catalog database]' \ - '*::default: _journal_none' - ;; - localectl) - _arguments \ - {-h,--help}'[Show this help]' \ - '--version[Show package version]' \ - "--no-convert[Don't convert keyboard mappings]" \ - '--no-pager[Do not pipe output into a pager]' \ - '--no-ask-password[Do not prompt for password]' \ - {-H,--host=}'[Operate on remote host]:userathost:_hosts_or_user_at_host' \ - '*::localectl commands:_localectl_command' - ;; - systemd-coredumpctl) - _arguments \ - {-o,--output=}'[Write output to FILE]:output file:_files' \ - '--no-pager[Do not pipe output into a pager]' \ - {-h,--help}'[Show this help]' \ - '--version[Show package version]' \ - '*::systemd-coredumpctl commands:_systemd-coredumpctl_command' - - ;; - timedatectl) - _arguments -s \ - {-h,--help}'[Show this help]' \ - '--version[Show package version]' \ - '--adjust-system-clock[Adjust system clock when changing local RTC mode]' \ - '--no-pager[Do not pipe output into a pager]' \ - '--no-ask-password[Do not prompt for password]' \ - {-H,--host=}'[Operate on remote host]:userathost:_hosts_or_user_at_host' \ - '*::timedatectl commands:_timedatectl_command' - ;; - udevadm) - _arguments \ - '--debug[Print debug messages to stderr]' \ - '--version[Print version number]' \ - '--help[Print help text]' \ - '*::udevadm commands:_udevadm_command' - ;; - systemd-analyze) - _arguments \ - {-h,--help}'[Show help text.]' \ - '--user[Shows performance data of user sessions instead of the system manager.]' \ - '--order[When generating graph for dot, show only order]' \ - '--require[When generating graph for dot, show only requirement]' \ - '*::systemd-analyze commands:_systemd_analyze_command' - ;; - systemd-ask-password) - _arguments \ - {-h,--help}'[Show this help]' \ - '--icon=[Icon name]' \ - '--timeout=[Timeout in sec]' \ - '--no-tty[Ask question via agent even on TTY]' \ - '--accept-cached[Accept cached passwords]' \ - '--multiple[List multiple passwords if available]' - ;; - systemd-cat) - _arguments \ - {-h,--help}'[Show this help]' \ - '--version[Show package version.]' \ - {-t,--identifier=}'[Set syslog identifier.]' \ - {-p,--priority=}'[Set priority value.]:value:({0..7})' \ - '--level-prefix=[Control whether level prefix shall be parsed.]:boolean:(1 0)' \ - ':Message' - ;; - systemd-cgls) - _arguments \ - {-h,--help}'[Show this help]' \ - '--version[Show package version]' \ - '--no-pager[Do not pipe output into a pager]' \ - {-a,--all}'[Show all groups, including empty]' \ - '-k[Include kernel threads in output]' \ - ':cgroups:(cpuset cpu cpuacct memory devices freezer net_cls blkio)' - ;; - systemd-cgtop) - _arguments \ - {-h,--help}'[Show this help]' \ - '--version[Print version and exit]' \ - '(-c -m -i -t)-p[Order by path]' \ - '(-c -p -m -i)-t[Order by number of tasks]' \ - '(-m -p -i -t)-c[Order by CPU load]' \ - '(-c -p -i -t)-m[Order by memory load]' \ - '(-c -m -p -t)-i[Order by IO load]' \ - {-d,--delay=}'[Specify delay]' \ - {-n,--iterations=}'[Run for N iterations before exiting]' \ - {-b,--batch}'[Run in batch mode, accepting no input]' \ - '--depth=[Maximum traversal depth]' - ;; - systemd-delta) - _arguments \ - {-h,--help}'[Show this help]' \ - '--version[Show package version]' \ - '--no-pager[Do not pipe output into a pager]' \ - '--diff=[Show a diff when overridden files differ]:boolean:(1 0)' \ - {-t,--type=}'[Only display a selected set of override types]:types:(masked equivalent redirected overridden unchanged)' \ - ':SUFFIX:(tmpfiles.d sysctl.d systemd/system)' - ;; - systemd-detect-virt) - _arguments \ - {-h,--help}'[Show this help]' \ - '--version[Show package version]' \ - {-c,--container}'[Only detect whether we are run in a container]' \ - {-v,--vm}'[Only detect whether we are run in a VM]' \ - {-q,--quiet}"[Don't output anything, just set return value]" - ;; - systemd-inhibit) - _arguments \ - {-h,--help}'[Show this help]' \ - '--version[Show package version]' \ - '--what=[Operations to inhibit]:options:(shutdown sleep idle handle-power-key handle-suspend-key handle-hibernate-key handle-lid-switch)' \ - '--who=[A descriptive string who is inhibiting]' \ - '--why=[A descriptive string why is being inhibited]' \ - '--mode=[One of block or delay]' \ - '--list[List active inhibitors]' \ - '*:commands:_systemd_inhibit_command' - ;; - systemd-machine-id-setup) - _arguments \ - {-h,--help}'[Show this help]' \ - '--version[Show package version]' - ;; - systemd-notify) - _arguments \ - {-h,--help}'[Show this help]' \ - '--version[Show package version]' \ - '--ready[Inform the init system about service start-up completion.]' \ - '--pid=[Inform the init system about the main PID of the daemon]' \ - '--status=[Send a free-form status string for the daemon to the init systemd]' \ - '--booted[Returns 0 if the system was booted up with systemd]' \ - '--readahead=[Controls disk read-ahead operations]:arguments:(cancel done noreply)' - ;; - systemd-nspawn) - _arguments \ - {-h,--help}'[Show this help]' \ - {--directory=,-D}'[Directory to use as file system root for the namespace container. If omitted the current directory will be used.]:directories:_directories' \ - {--boot,-b}'[Automatically search for an init binary and invoke it instead of a shell or a user supplied program.]' \ - {--user=,-u}'[Run the command under specified user, create home directory and cd into it.]' \ - '--uuid=[Set the specified uuid for the container.]' \ - {--controllers=,-C}'[Makes the container appear in other hierarchies than the name=systemd:/ one. Takes a comma-separated list of controllers.]' \ - '--private-network[Turn off networking in the container. This makes all network interfaces unavailable in the container, with the exception of the loopback device.]' \ - '--read-only[Mount the root file system read only for the container.]' \ - '--capability=[List one or more additional capabilities to grant the container.]:capabilities:_systemd-nspawn' \ - "--link-journal=[Control whether the container's journal shall be made visible to the host system.]:options:(no, host, guest, auto)" \ - '-j[Equivalent to --link-journal=guest.]' - ;; - systemd-tmpfiles) - _arguments \ - '--create[Create, set ownership/permissions based on the config files.]' \ - '--clean[Clean up all files and directories with an age parameter configured.]' \ - '--remove[All files and directories marked with r, R in the configuration files are removed.]' \ - '--prefix=[Only apply rules that apply to paths with the specified prefix.]' \ - '--exclude-prefix=[Ignore rules that apply to paths with the specified prefix.]' \ - '--help[Prints a short help text and exits.]' \ - '*::files:_files' - ;; - systemd-tty-ask-password-agent) - _arguments \ - {-h,--help}'[Prints a short help text and exits.]' \ - '--version[Prints a short version string and exits.]' \ - '--list[Lists all currently pending system password requests.]' \ - '--query[Process all currently pending system password requests by querying the user on the calling TTY.]' \ - '--watch[Continuously process password requests.]' \ - '--wall[Forward password requests to wall(1).]' \ - '--plymouth[Ask question with plymouth(8).]' \ - '--console[Ask question on /dev/console.]' - ;; - machinectl) - _arguments \ - {-h,--help}'[Prints a short help text and exits.]' \ - '--version[Prints a short version string and exits.]' \ - {-p,--property=}'[Limit output to specified property.]:property:(Name Id Timestamp TimestampMonotonic Service Scope Leader Class State RootDirectory)' \ - {-a,--all}'[Show all proerties]' \ - (-l,--full)'[Do not ellipsize cgroup members]' \ - '--no-pager[Do not pipe output into a pager]' \ - '--no-ask-password[Do not ask for system passwords]' \ - '--kill-who=[Who to send signal to]:killwho:(leader all)' \ - {-s,--signal=}'[Which signal to send]:signal:_signals' \ - {-H,--host=}'[Show information for remote host]:userathost:_hosts_or_user_at_host' \ - {-P,--privileged}'[Acquire privileges before execution]' \ - '*::machinectl command:_machinectl_command' - ;; - *) _message 'eh?' ;; - esac -} - -_systemd-nspawn(){ - local -a _caps - _caps=( CAP_CHOWN CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH - CAP_FOWNER CAP_FSETID CAP_IPC_OWNER CAP_KILL CAP_LEASE CAP_LINUX_IMMUTABLE - CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET_RAW CAP_SETGID CAP_SETFCAP CAP_SETPCAP - CAP_SETUID CAP_SYS_ADMIN CAP_SYS_CHROOT CAP_SYS_NICE CAP_SYS_PTRACE CAP_SYS_TTY_CONFIG - CAP_SYS_RESOURCE CAP_SYS_BOOT ) - _values -s , 'capabilities' "$_caps[@]" -} - -_systemd_inhibit_command(){ - if (( CURRENT == 1 )); then - compset -q - _normal - else - local n=${words[(b:2:i)[^-]*]} - if (( n <= CURRENT )); then - compset -n $n - _alternative \ - 'files:file:_files' \ - 'commands:command:_normal' && return 0 - fi - _default - fi - -} - -_systemd_analyze_command(){ - local -a _systemd_analyze_cmds - # Descriptions taken from systemd-analyze --help. - _systemd_analyze_cmds=( - 'time:Print time spent in the kernel before reaching userspace' - 'blame:Print list of running units ordered by time to init' - 'critical-chain:Print a tree of the time critical chain of units' - 'plot:Output SVG graphic showing service initialization' - 'dot:Dump dependency graph (in dot(1) format)' - ) - - if (( CURRENT == 1 )); then - _describe "options" _systemd_analyze_cmds - else - _message "no more options" - fi -} - -_hosts_or_user_at_host() -{ - _alternative \ - 'users-hosts:: _user_at_host' \ - 'hosts:: _hosts' -} - -_outputmodes() { - local -a _output_opts - _output_opts=(short short-monotonic verbose export json json-pretty json-see cat) - _describe -t output 'output mode' _output_opts || compadd "$@" -} - - -(( $+functions[_systemctl_command] )) || _systemctl_command() -{ - local -a _systemctl_cmds - _systemctl_cmds=( - "list-units:List units" - "start:Start (activate) one or more units" - "stop:Stop (deactivate) one or more units" - "reload:Reload one or more units" - "restart:Start or restart one or more units" - "condrestart:Restart one or more units if active" - "try-restart:Restart one or more units if active" - "reload-or-restart:Reload one or more units if possible, otherwise start or restart" - "force-reload:Reload one or more units if possible, otherwise restart if active" - "hibernate:Hibernate the system" - "hybrid-sleep:Hibernate and suspend the system" - "reload-or-try-restart:Reload one or more units if possible, otherwise restart if active" - "isolate:Start one unit and stop all others" - "kill:Send signal to processes of a unit" - "is-active:Check whether units are active" - "is-failed:Check whether units are failed" - "status:Show runtime status of one or more units" - "show:Show properties of one or more units/jobs or the manager" - "reset-failed:Reset failed state for all, one, or more units" - "load:Load one or more units" - "list-unit-files:List installed unit files" - "enable:Enable one or more unit files" - "disable:Disable one or more unit files" - "reenable:Reenable one or more unit files" - "preset:Enable/disable one or more unit files based on preset configuration" - "help:Show documentation for specified units" - "list-dependencies:Show unit dependency tree" - "mask:Mask one or more units" - "unmask:Unmask one or more units" - "link:Link one or more units files into the search path" - "is-enabled:Check whether unit files are enabled" - "list-jobs:List jobs" - "cancel:Cancel all, one, or more jobs" - "dump:Dump server status" - "snapshot:Create a snapshot" - "delete:Remove one or more snapshots" - "show-environment:Dump environment" - "set-environment:Set one or more environment variables" - "unset-environment:Unset one or more environment variables" - "daemon-reload:Reload systemd manager configuration" - "daemon-reexec:Reexecute systemd manager" - "default:Enter system default mode" - "rescue:Enter system rescue mode" - "emergency:Enter system emergency mode" - "halt:Shut down and halt the system" - "suspend:Suspend the system" - "poweroff:Shut down and power-off the system" - "reboot:Shut down and reboot the system" - "kexec:Shut down and reboot the system with kexec" - "exit:Ask for user instance termination" - ) - - if (( CURRENT == 1 )); then - _describe -t commands 'systemctl command' _systemctl_cmds || compadd "$@" - else - local curcontext="$curcontext" - - cmd="${${_systemctl_cmds[(r)$words[1]:*]%%:*}}" - # Deal with any aliases - case $cmd in - condrestart) cmd="try-restart";; - force-reload) cmd="reload-or-try-restart";; - esac - - if (( $#cmd )); then - curcontext="${curcontext%:*:*}:systemctl-${cmd}:" - - local update_policy - zstyle -s ":completion:${curcontext}:" cache-policy update_policy - if [[ -z "$update_policy" ]]; then - zstyle ":completion:${curcontext}:" cache-policy _systemctl_caching_policy - fi - - _call_function ret _systemctl_$cmd || _message 'no more arguments' - else - _message "unknown systemctl command: $words[1]" - fi - return ret - fi -} - -__systemctl() -{ - local -a _modes - _modes=("--user" "--system") - systemctl ${words:*_modes} --full --no-legend --no-pager "$@" -} - - -# Fills the unit list -_systemctl_all_units() -{ - if ( [[ ${+_sys_all_units} -eq 0 ]] || _cache_invalid SYS_ALL_UNITS ) && - ! _retrieve_cache SYS_ALL_UNITS; - then - _sys_all_units=( $(__systemctl list-units --all | { while read a b; do echo " $a"; done; }) ) - _store_cache SYS_ALL_UNITS _sys_all_units - fi -} - -# Fills the unit list including all file units -_systemctl_really_all_units() -{ - local -a all_unit_files; - local -a really_all_units; - if ( [[ ${+_sys_really_all_units} -eq 0 ]] || _cache_invalid SYS_REALLY_ALL_UNITS ) && - ! _retrieve_cache SYS_REALLY_ALL_UNITS; - then - all_unit_files=( $(__systemctl list-unit-files | { while read a b; do echo " $a"; done; }) ) - _systemctl_all_units - really_all_units=($_sys_all_units $all_unit_files) - _sys_really_all_units=(${(u)really_all_units}) - _store_cache SYS_REALLY_ALL_UNITS _sys_really_all_units - fi -} - -_filter_units_by_property() { - local property=$1 value=$2 ; shift ; shift - local -a units ; units=($*) - local prop unit - for ((i=1; $i <= ${#units[*]}; i++)); do - # FIXME: "Failed to issue method call: Unknown unit" errors are ignored for - # now (related to DBUS_ERROR_UNKNOWN_OBJECT). in the future, we need to - # revert to calling 'systemctl show' once for all units, which is way - # faster - unit=${units[i]} - prop=${(f)"$(_call_program units "$service show --no-pager --property="$property" ${unit} 2>/dev/null")"} - if [[ "${prop}" = "$property=$value" ]]; then - echo " ${unit}" - fi - done -} - -_systemctl_active_units() {_sys_active_units=( $(__systemctl list-units | { while read a b; do echo " $a"; done; }) )} -_systemctl_inactive_units(){_sys_inactive_units=($(__systemctl list-units --all | { while read a b c d; do [[ $c == "inactive" || $c == "failed" ]] && echo " $a"; done; }) )} -_systemctl_failed_units() {_sys_failed_units=( $(__systemctl list-units --failed | { while read a b; do echo " $a"; done; }) )} -_systemctl_enabled_units() {_sys_enabled_units=( $(__systemctl list-unit-files | { while read a b; do [[ $b == "enabled" ]] && echo " $a"; done; }) )} -_systemctl_disabled_units(){_sys_disabled_units=($(__systemctl list-unit-files | { while read a b; do [[ $b == "disabled" ]] && echo " $a"; done; }) )} -_systemctl_masked_units() {_sys_masked_units=( $(__systemctl list-unit-files | { while read a b; do [[ $b == "masked" ]] && echo " $a"; done; }) )} - -# Completion functions for ALL_UNITS -for fun in is-active is-failed is-enabled status show mask preset help list-dependencies ; do - (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() - { - _systemctl_really_all_units - compadd "$@" -a - _sys_really_all_units - } -done - -# Completion functions for ENABLED_UNITS -for fun in disable reenable ; do - (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() - { - _systemctl_enabled_units - _systemctl_disabled_units - compadd "$@" -a - _sys_enabled_units _sys_disabled_units - } -done - -# Completion functions for DISABLED_UNITS -(( $+functions[_systemctl_enable] )) || _systemctl_enable() -{ - _systemctl_disabled_units - compadd "$@" -a - _sys_disabled_units -} - -# Completion functions for FAILED_UNITS -(( $+functions[_systemctl_reset-failed] )) || _systemctl_reset-failed() -{ - _systemctl_failed_units - compadd "$@" -a - _sys_failed_units || _message "no failed unit found" -} - -# Completion functions for STARTABLE_UNITS -(( $+functions[_systemctl_start] )) || _systemctl_start() -{ - _systemctl_inactive_units - compadd "$@" -a - _sys_inactive_units -} - -# Completion functions for STOPPABLE_UNITS -for fun in stop kill try-restart condrestart ; do - (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() - { - _systemctl_active_units - compadd "$@" - $( _filter_units_by_property CanStop yes \ - ${_sys_active_units[*]} ) - } -done - -# Completion functions for ISOLATABLE_UNITS -(( $+functions[_systemctl_isolate] )) || _systemctl_isolate() -{ - _systemctl_all_units - compadd "$@" - $( _filter_units_by_property AllowIsolate yes \ - ${_sys_all_units[*]} ) -} - -# Completion functions for RELOADABLE_UNITS -for fun in reload reload-or-try-restart force-reload ; do - (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() - { - _systemctl_active_units - compadd "$@" - $( _filter_units_by_property CanReload yes \ - ${_sys_active_units[*]} ) - } -done - -# Completion functions for RESTARTABLE_UNITS -for fun in restart reload-or-restart ; do - (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() - { - _systemctl_all_units - compadd "$@" - $( _filter_units_by_property CanStart yes \ - ${_sys_all_units[*]} | while read line; do \ - [[ "$line" =~ \.device$ ]] || echo " $line"; \ - done ) - } -done - -# Completion functions for MASKED_UNITS -(( $+functions[_systemctl_unmask] )) || _systemctl_unmask() -{ - _systemctl_masked_units - compadd "$@" -a - _sys_masked_units || _message "no masked unit found" -} - -# Completion functions for JOBS -(( $+functions[_systemctl_cancel] )) || _systemctl_cancel() -{ - compadd "$@" - $(__systemctl list-jobs \ - | cut -d' ' -f1 2>/dev/null ) || _message "no job found" -} - -# Completion functions for SNAPSHOTS -(( $+functions[_systemctl_delete] )) || _systemctl_delete() -{ - compadd "$@" - $(__systemctl list-units --type snapshot --all \ - | cut -d' ' -f1 2>/dev/null ) || _message "no snapshot found" -} - -# Completion functions for ENVS -for fun in set-environment unset-environment ; do - (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() - { - local fun=$0 ; fun=${fun##_systemctl_} - local suf - if [[ "${fun}" = "set-environment" ]]; then - suf='-S=' - fi - - compadd "$@" ${suf} - $(systemctl show-environment \ - | while read line; do echo " ${line%%\=}";done ) - } -done - -(( $+functions[_systemctl_link] )) || _systemctl_link() { _files } - -# no systemctl completion for: -# [STANDALONE]='daemon-reexec daemon-reload default dump -# emergency exit halt kexec list-jobs list-units -# list-unit-files poweroff reboot rescue show-environment' -# [NAME]='snapshot load' - -_systemctl_caching_policy() -{ - local _sysunits - local -a oldcache - - # rebuild if cache is more than a day old - oldcache=( "$1"(mh+1) ) - (( $#oldcache )) && return 0 - - _sysunits=($(__systemctl --all | cut -d' ' -f1)) - - if (( $#_sysunits )); then - for unit in $_sysunits; do - [[ "$unit" -nt "$1" ]] && return 0 - done - fi - - return 1 -} - -_list_fields() { - local -a journal_fields - journal_fields=(MESSAGE{,_ID} PRIORITY CODE_{FILE,LINE,FUNC} - ERRNO SYSLOG_{FACILITY,IDENTIFIER,PID} - _{P,U,G}ID _COMM _EXE _CMDLINE - _AUDIT_{SESSION,LOGINUID} - _SYSTEMD_{CGROUP,SESSION,UNIT,OWNER_UID} - _SYSTEMD_USER_UNIT - _SELINUX_CONTEXT _SOURCE_REALTIME_TIMESTAMP - _{BOOT,MACHINE}_ID _HOSTNAME _TRANSPORT - _KERNEL_{DEVICE,SUBSYSTEM} - _UDEV_{SYSNAME,DEVNODE,DEVLINK} - __CURSOR __{REALTIME,MONOTONIC}_TIMESTAMP) - _describe 'possible fields' journal_fields -} - -_journal_none() { - local -a _commands _files - _commands=( ${(f)"$(_call_program commands "$service" -F _EXE 2>/dev/null)"} ) - _alternative : \ - 'files:/dev files:_files -W /dev -P /dev/' \ - "commands:commands:($_commands[@])" \ - 'fields:fields:_list_fields' -} - -_journal_fields() { - local -a _fields cmd - cmd=("journalctl" "-F ${@[-1]}" "2>/dev/null" ) - _fields=( ${(f)"$(_call_program fields $cmd[@])"} ) - typeset -U _fields - _describe 'possible values' _fields -} - - -_loginctl_all_sessions(){_sys_all_sessions=($(loginctl list-sessions | { while read a b; do echo " $a"; done; }) )} -_loginctl_all_users() {_sys_all_users=( $(loginctl list-users | { while read a b; do echo " $a"; done; }) )} -_loginctl_all_seats() {_sys_all_seats=( $(loginctl list-seats | { while read a b; do echo " $a"; done; }) )} - -# Completion functions for SESSIONS -for fun in session-status show-session activate lock-session unlock-session terminate-session kill-session ; do - (( $+functions[_loginctl_$fun] )) || _loginctl_$fun() - { - _loginctl_all_sessions - compadd "$@" -a - _sys_all_sessions - } -done - -# Completion functions for USERS -for fun in user-status show-user enable-linger disable-linger terminate-user kill-user ; do - (( $+functions[_loginctl_$fun] )) || _loginctl_$fun() - { - _loginctl_all_users - compadd "$@" -a - _sys_all_users - } -done - -# Completion functions for SEATS -(( $+functions[_loginctl_seats] )) || _loginctl_seats() -{ - _loginctl_all_seats - compadd "$@" -a - _sys_all_seats -} -for fun in seat-status show-seat terminate-seat ; do - (( $+functions[_loginctl_$fun] )) || _loginctl_$fun() - { _loginctl_seats } -done - -# Completion functions for ATTACH -(( $+functions[_loginctl_attach] )) || _loginctl_attach() -{ - _loginctl_all_seats - - _arguments -w -C -S -s \ - ':seat:_loginctl_seats' \ - '*:device:_files' -} - -# no loginctl completion for: -# [STANDALONE]='list-sessions list-users list-seats flush-devices' - -(( $+functions[_loginctl_command] )) || _loginctl_command() -{ - local -a _loginctl_cmds - _loginctl_cmds=( - "list-sessions:List sessions" - "session-status:Show session status" - "show-session:Show properties of one or more sessions" - "activate:Activate a session" - "lock-session:Screen lock one or more sessions" - "unlock-session:Screen unlock one or more sessions" - "terminate-session:Terminate one or more sessions" - "kill-session:Send signal to processes of a session" - "list-users:List users" - "user-status:Show user status" - "show-user:Show properties of one or more users" - "enable-linger:Enable linger state of one or more users" - "disable-linger:Disable linger state of one or more users" - "terminate-user:Terminate all sessions of one or more users" - "kill-user:Send signal to processes of a user" - "list-seats:List seats" - "seat-status:Show seat status" - "show-seat:Show properties of one or more seats" - "attach:Attach one or more devices to a seat" - "flush-devices:Flush all device associations" - "terminate-seat:Terminate all sessions on one or more seats" - ) - - if (( CURRENT == 1 )); then - _describe -t commands 'loginctl command' _loginctl_cmds || compadd "$@" - else - local curcontext="$curcontext" - - cmd="${${_loginctl_cmds[(r)$words[1]:*]%%:*}}" - - if (( $#cmd )); then - curcontext="${curcontext%:*:*}:loginctl-${cmd}:" - - _call_function ret _loginctl_$cmd || _message 'no more arguments' - else - _message "unknown loginctl command: $words[1]" - fi - return ret - fi -} - -_hostnamectl_command() { - local -a _hostnamectl_cmds - _hostnamectl_cmds=( - "status:Show current hostname settings" - "set-hostname:Set system hostname" - "set-icon-name:Set icon name for host" - ) - if (( CURRENT == 1 )); then - _describe -t commands 'hostnamectl commands' _hostnamectl_cmds || compadd "$@" - else - local curcontext="$curcontext" - cmd="${${_hostnamectl_cmds[(r)$words[1]:*]%%:*}}" - if (( $#cmd )); then - [[ $cmd == status ]] && msg="no options" || msg="options for $cmd" - _message "$msg" - else - _message "unknown hostnamectl command: $words[1]" - fi - fi -} - -_localectl_set-locale() { - local -a _confs _locales - local expl suf - _locales=( ${(f)"$(_call_program locales "$service" list-locales)"} ) - _confs=( ${${(f)"$(_call_program confs "locale 2>/dev/null")"}%\=*} ) - if [[ -prefix 1 *\= ]]; then - local conf=${PREFIX%%\=*} - compset -P1 '*=' - _wanted locales expl "locales configs" \ - _combination localeconfs confs=$conf locales "$@" - - else - compadd -S '=' $_confs - fi -} - -_localectl_set-keymap() { - local -a _keymaps - _keymaps=( ${(f)"$(_call_program locales "$service" list-keymaps)"} ) - if (( CURRENT <= 3 )); then - _describe keymaps _keymaps - else - _message "no more options" - fi -} - -_localectl_set-x11-keymap() { - if (( $+commands[pkg-config] )); then - local -a _file _layout _model _variant _options - local _xorg_lst - _xorg_lst=${"$($commands[pkg-config] xkeyboard-config --variable=xkb_base)"} - _file=( ${(ps:\n\!:)"$(<$_xorg_lst/rules/xorg.lst)"} ) - _layout=( ${${${(M)${(f)_file[1]}:# *}# }%% *} ) - _model=( ${${${(M)${(f)_file[2]}:# *}# }%% *} ) - _variant=( ${${${(M)${(f)_file[3]}:# *}# }%% *} ) - _options=( ${${${(M)${(f)_file[4]}:# *}# }%% *} ) - #_layout=( ${(f)"$( echo $_file[1] | awk '/^ / {print $1}' )"} ) - #_model=( ${(f)"$(echo $_file[2] | awk '/^ / {print $1}')"} ) - #_variant=( ${(f)"$(echo $_file[3] | awk '/^ / {print $1}')"} ) - #_options=( ${(f)"$(echo ${_file[4]//:/\\:} | awk '/^ / {print $1}')"} ) - - case $CURRENT in - 2) _describe layouts _layout ;; - 3) _describe models _model;; - 4) _describe variants _variant;; - 5) _describe options _options;; - *) _message "no more options" - esac - fi -} - - -_localectl_command() { - local -a _localectl_cmds - _localectl_cmds=( - 'status:Show current locale settings' - 'set-locale:Set system locale' - 'list-locales:Show known locales' - 'set-keymap:Set virtual console keyboard mapping' - 'list-keymaps:Show known virtual console keyboard mappings' - 'set-x11-keymap:Set X11 keyboard mapping' - ) - if (( CURRENT == 1 )); then - _describe -t commands 'localectl command' _localectl_cmds - else - local curcontext="$curcontext" - cmd="${${_localectl_cmds[(r)$words[1]:*]%%:*}}" - if (( $+functions[_localectl_$cmd] )); then - _localectl_$cmd - else - _message "no more options" - fi - fi -} - -_timedatectl_set-timezone(){ - local -a _timezones - _timezones=( ${(f)"$(_call_program timezones "${service}" list-timezones)"} ) - compadd "$_timezones[@]" -} - -_timedatectl_set-time(){ - _message "YYYY-MM-DD HH:MM:SS" -} - -_timedatectl_set-local-rtc(){ - local -a _options - _options=( - '0:Maintain RTC in universal time' - '1:Maintain RTC in local time' - ) - _describe options _options -} - -_timedatectl_set-ntp(){ - local -a _options - _options=( - '0:Disable NTP based network time configuration' - '1:Enable NTP based network time configuration' - ) - _describe options _options -} - -_timedatectl_command(){ - local -a _timedatectl_cmds - _timedatectl_cmds=( - 'status:Show current time settings' - 'set-time:Set system time' - 'set-timezone:Set system timezone' - 'list-timezones:Show known timezones' - 'set-local-rtc:Control whether RTC is in local time' - 'set-ntp:Control whether NTP is enabled' - ) - if (( CURRENT == 1 )); then - _describe -t commands 'timedatectl command' _timedatectl_cmds - else - local curcontext="$curcontext" - cmd="${${_timedatectl_cmds[(r)$words[1]:*]%%:*}}" - if (( $#cmd )); then - if (( $+functions[_timedatectl_$cmd] )); then - _timedatectl_$cmd - else - _message "no more options" - fi - else - _message "unknown timedatectl command: $words[1]" - fi - fi -} -_systemd-coredumpctl_command(){ - local -a _systemd_coredumpctl_cmds - _systemd_coredumpctl_cmds=( - 'list:List available coredumps' - 'dump:Print coredump to std' - ) - if (( CURRENT == 1 )); then - _describe -t commands 'systemd-coredumpctl command' _systemd_coredumpctl_cmds - else - local curcontext="$curcontext" - local -a _dumps - cmd="${${_systemd_coredumpctl_cmds[(r)$words[1]:*]%%:*}}" - if (( $#cmd )); then - # user can set zstyle ':completion:*:*:systemd-coredumpctl:*' sort no for coredumps to be ordered by date, otherwise they get ordered by pid - _dumps=( "${(foa)$(systemd-coredumpctl list | awk 'BEGIN{OFS=":"} /^\s/ {sub(/[[ \t]+/, ""); print $5,$0}' 2>/dev/null)}" ) - if [[ -n "$_dumps" ]]; then - _describe -t pids 'coredumps' _dumps - else - _message "no coredumps" - fi - else - _message "no more options" - fi - - fi - -} - -(( $+functions[_machinectl_command] )) || _machinectl_command() -{ - local -a _machinectl_cmds - _machinectl_cmds=( - "list:List currently running VMs/containers" - "status:Show VM/container status" - "show:Show properties of one or more VMs/containers" - "terminate:Terminate one or more VMs/containers" - "kill:Send signal to process or a VM/container" - ) - if (( CURRENT == 1 )); then - _describe -t commands 'machinectl command' _machinectl_cmds || compadd "$@" - else - local curcontext="$curcontext" - cmd="${${_machinectl_cmds[(r)$words[1]:*]%%:*}}" - if (( $#cmd )); then - case $cmd in - list) msg="no options" ;; - *) - _machines=( "${(foa)$(machinectl list | awk '{print $1}')}" ) - if [[ -n "$_machines" ]]; then - _describe 'machines' _machines - else - _message 'no machines' - fi - esac - else - _message "no more options" - fi - fi -} - -_udevadm_info(){ - _arguments \ - '--query=[Query the database for specified type of device data. It needs the --path or --name to identify the specified device.]:type:(name symlink path property all)' \ - '--path=[The devpath of the device to query.]:sys files:_files -P /sys/ -W /sys' \ - '--name=[The name of the device node or a symlink to query]:device files:_files -P /dev/ -W /dev' \ - '--root[Print absolute paths in name or symlink query.]' \ - '--attribute-walk[Print all sysfs properties of the specified device that can be used in udev rules to match the specified device]' \ - '--export[Print output as key/value pairs.]' \ - '--export-prefix=[Add a prefix to the key name of exported values.]:prefix' \ - '--device-id-of-file=[Print major/minor numbers of the underlying device, where the file lives on.]:files:_udevadm_mounts' \ - '--export-db[Export the content of the udev database.]' \ - '--cleanup-db[Cleanup the udev database.]' -} - -_udevadm_trigger(){ - _arguments \ - '--verbose[Print the list of devices which will be triggered.]' \ - '--dry-run[Do not actually trigger the event.]' \ - '--type=[Trigger a specific type of devices.]:types:(devices subsystems failed)' \ - '--action=[Type of event to be triggered.]:actions:(add change remove)' \ - '--subsystem-match=[Trigger events for devices which belong to a matching subsystem.]' \ - '--subsystem-nomatch=[Do not trigger events for devices which belong to a matching subsystem.]' \ - '--attr-match=attribute=[Trigger events for devices with a matching sysfs attribute.]' \ - '--attr-nomatch=attribute=[Do not trigger events for devices with a matching sysfs attribute.]' \ - '--property-match=[Trigger events for devices with a matching property value.]' \ - '--tag-match=property[Trigger events for devices with a matching tag.]' \ - '--sysname-match=[Trigger events for devices with a matching sys device name.]' \ - '--parent-match=[Trigger events for all children of a given device.]' -} - -_udevadm_settle(){ - _arguments \ - '--timeout=[Maximum number of seconds to wait for the event queue to become empty.]' \ - '--seq-start=[Wait only for events after the given sequence number.]' \ - '--seq-end=[Wait only for events before the given sequence number.]' \ - '--exit-if-exists=[Stop waiting if file exists.]:files:_files' \ - '--quiet[Do not print any output, like the remaining queue entries when reaching the timeout.]' \ - '--help[Print help text.]' -} - -_udevadm_control(){ - _arguments \ - '--exit[Signal and wait for systemd-udevd to exit.]' \ - '--log-priority=[Set the internal log level of systemd-udevd.]:priorities:(err info debug)' \ - '--stop-exec-queue[Signal systemd-udevd to stop executing new events. Incoming events will be queued.]' \ - '--start-exec-queue[Signal systemd-udevd to enable the execution of events.]' \ - '--reload[Signal systemd-udevd to reload the rules files and other databases like the kernel module index.]' \ - '--property=[Set a global property for all events.]' \ - '--children-max=[Set the maximum number of events.]' \ - '--timeout=[The maximum number of seconds to wait for a reply from systemd-udevd.]' \ - '--help[Print help text.]' -} - -_udevadm_monitor(){ - _arguments \ - '--kernel[Print the kernel uevents.]' \ - '--udev[Print the udev event after the rule processing.]' \ - '--property[Also print the properties of the event.]' \ - '--subsystem-match=[Filter events by subsystem/\[devtype\].]' \ - '--tag-match=[Filter events by property.]' \ - '--help[Print help text.]' -} - -_udevadm_test(){ - _arguments \ - '--action=[The action string.]:actions:(add change remove)' \ - '--subsystem=[The subsystem string.]' \ - '--help[Print help text.]' \ - '*::devpath:_files -P /sys/ -W /sys' -} - -_udevadm_test-builtin(){ - if (( CURRENT == 2 )); then - _arguments \ - '--help[Print help text]' \ - '*::builtins:(blkid btrfs hwdb input_id kmod path_id usb_id uaccess)' - elif (( CURRENT == 3 )); then - _arguments \ - '--help[Print help text]' \ - '*::syspath:_files -P /sys -W /sys' - else - _arguments \ - '--help[Print help text]' - fi -} - -_udevadm_mounts(){ - local dev_tmp dpath_tmp mp_tmp mline - - tmp=( "${(@f)$(< /etc/mtab)}" ) - dev_tmp=( "${(@)${(@)tmp%% *}:#none}" ) - mp_tmp=( "${(@)${(@)tmp#* }%% *}" ) - - local MATCH - mp_tmp=("${(@q)mp_tmp//(#m)\\[0-7](#c3)/${(#)$(( 8#${MATCH[2,-1]} ))}}") - dpath_tmp=( "${(@Mq)dev_tmp:#/*}" ) - dev_tmp=( "${(@q)dev_tmp:#/*}" ) - - _alternative \ - 'device-paths: device path:compadd -a dpath_tmp' \ - 'directories:mount point:compadd -a mp_tmp' -} - - -_udevadm_command(){ - local -a _udevadm_cmds - _udevadm_cmds=( - 'info:query sysfs or the udev database' - 'trigger:request events from the kernel' - 'settle:wait for the event queue to finish' - 'control:control the udev daemon' - 'monitor:listen to kernel and udev events' - 'test:test an event run' - 'test-builtin:test a built-in command' - ) - - if ((CURRENT == 1)); then - _describe -t commands 'udevadm commands' _udevadm_cmds - else - local curcontext="$curcontext" - cmd="${${_udevadm_cmds[(r)$words[1]:*]%%:*}}" - if (($#cmd)); then - if (( $+functions[_udevadm_$cmd] )); then - _udevadm_$cmd - else - _message "no options for $cmd" - fi - else - _message "no more options" - fi - fi -} - -_ctls "$@" - -#vim: set ft=zsh sw=4 ts=4 et diff --git a/shell-completion/zsh/_systemd b/shell-completion/zsh/_systemd new file mode 100644 index 0000000000..1ab1311ec1 --- /dev/null +++ b/shell-completion/zsh/_systemd @@ -0,0 +1,1102 @@ +#compdef systemctl loginctl journalctl hostnamectl localectl timedatectl systemd-coredumpctl udevadm systemd-analyze systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-inhibit systemd-machine-id-setup systemd-notify systemd-nspawn systemd-tmpfiles systemd-tty-ask-password-agent machinectl + +_ctls() +{ + local curcontext="$curcontext" state lstate line + case "$service" in + systemctl) + # -s for aggregated options like -aP + _arguments -s \ + {-h,--help}'[Show help]' \ + '--version[Show package version]' \ + {-t,--type=}'[List only units of a particular type]:unit type:(automount device mount path service snapshot socket swap target timer)' \ + \*{-p,--property=}'[Show only properties by specific name]:unit property' \ + {-a,--all}'[Show all units/properties, including dead/empty ones]' \ + '--reverse[Show reverse dependencies]' \ + '--after[Show units ordered after]' \ + '--before[Show units ordered before]' \ + '--failed[Show only failed units]' \ + {-l,--full}"[Don't ellipsize unit names on output]" \ + '--fail[When queueing a new job, fail if conflicting jobs are pending]' \ + '--ignore-dependencies[When queueing a new job, ignore all its dependencies]' \ + '--kill-who=[Who to send signal to]:killwho:(main control all)' \ + {-s,--signal=}'[Which signal to send]:signal:_signals' \ + {-H,--host=}'[Show information for remote host]:userathost:_hosts_or_user_at_host' \ + {-P,--privileged}'[Acquire privileges before execution]' \ + {-q,--quiet}'[Suppress output]' \ + '--no-block[Do not wait until operation finished]' \ + "--no-wall[Don't send wall message before halt/power-off/reboot]" \ + "--no-reload[When enabling/disabling unit files, don't reload daemon configuration]" \ + '--no-legend[Do not print a legend, i.e. the column headers and the footer with hints]' \ + '--no-pager[Do not pipe output into a pager]' \ + '--no-ask-password[Do not ask for system passwords]' \ + '--system[Connect to system manager]' \ + '--user[Connect to user service manager]' \ + '--global[Enable/disable unit files globally]' \ + {-f,--force}'[When enabling unit files, override existing symlinks. When shutting down, execute action immediately]' \ + '--root=[Enable unit files in the specified root directory]:directory:_directories' \ + '--runtime[Enable unit files only temporarily until next reboot]' \ + {-n,--lines=}'[Journal entries to show]:number of entries' \ + {-o,--output=}'[Change journal output mode]:modes:_outputmodes' \ + '*::systemctl command:_systemctl_command' + ;; + loginctl) + _arguments -s \ + {-h,--help}'[Show help]' \ + '--version[Show package version]' \ + \*{-p,--property=}'[Show only properties by this name]:unit property' \ + {-a,--all}'[Show all properties, including empty ones]' \ + '--kill-who=[Who to send signal to]:killwho:(main control all)' \ + {-s,--signal=}'[Which signal to send]:signal:_signals' \ + '--no-ask-password[Do not ask for system passwords]' \ + {-H,--host=}'[Show information for remote host]:userathost:_hosts_or_user_at_host' \ + {-P,--privileged}'[Acquire privileges before execution]' \ + '--no-pager[Do not pipe output into a pager]' \ + '*::loginctl command:_loginctl_command' + ;; + + hostnamectl) + _arguments -s \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + '--transient[Only set transient hostname]' \ + '--static[Only set static hostname]' \ + '--pretty[Only set pretty hostname]' \ + '--no-ask-password[Do not prompt for password]' \ + {-H,--host=}'[Operate on remote host]:userathost:_hosts_or_user_at_host' \ + '*::hostnamectl commands:_hostnamectl_command' + ;; + journalctl) + _arguments -s \ + '--since=[Start showing entries newer or of the specified date]:YYYY-MM-DD HH\:MM\:SS' \ + '--until=[Stop showing entries older or of the specified date]:YYYY-MM-DD HH\:MM\:SS' \ + {-c,--cursor=}'[Start showing entries from specified cursor]:cursors:_journal_fields __CURSORS' \ + '--system[Show system and kernel messages]' \ + '--user[Show messages from user services]' \ + {-b,--this-boot}'[Show data only from current boot]' \ + {-u,--unit=}'[Show data only from the specified unit]:units:_journal_fields _SYSTEMD_UNIT' \ + '--user-unit[Show data only from the specified user session unit]:units:_journal_fields _SYSTEMD_USER_UNIT' \ + {-p,--priority=}'[Show only messages within the specified priority range]:priority:_journal_fields PRIORITY' \ + {-f,--follow}'[Follow journal]' \ + {-n,--lines=}'[Number of journal entries to show]:integer' \ + '--no-tail[Show all lines, even in follow mode]' \ + {-o,--output=}'[Change journal output mode]:output modes:_outputmodes' \ + {-l,--full}'[Show long fields in full]' \ + {-a,--all}'[Show all fields, including long and unprintable]' \ + {-q,--quiet}"[Don't show privilege warning]" \ + '--no-pager[Do not pipe output into a pager]' \ + {-m,--merge}'[Show entries from all available journals]' \ + {-D,--directory=}'[Show journal files from directory]:directories:_directories' \ + '--interval=[Time interval for changing the FSS sealing key]:time interval' \ + '--verify-key=[Specify FSS verification key]:FSS key' \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + '--new-id128[Generate a new 128 Bit ID]' \ + '--header[Show journal header information]' \ + '--disk-usage[Show total disk usage]' \ + {-F,--field=}'[List all values a certain field takes]:Fields:_list_fields' \ + '--setup-keys[Generate new FSS key pair]' \ + '--verify[Verify journal file consistency]' \ + '--list-catalog[List messages in catalog]' \ + '--update-catalog[Update binary catalog database]' \ + '*::default: _journal_none' + ;; + localectl) + _arguments \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + "--no-convert[Don't convert keyboard mappings]" \ + '--no-pager[Do not pipe output into a pager]' \ + '--no-ask-password[Do not prompt for password]' \ + {-H,--host=}'[Operate on remote host]:userathost:_hosts_or_user_at_host' \ + '*::localectl commands:_localectl_command' + ;; + systemd-coredumpctl) + _arguments \ + {-o,--output=}'[Write output to FILE]:output file:_files' \ + '--no-pager[Do not pipe output into a pager]' \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + '*::systemd-coredumpctl commands:_systemd-coredumpctl_command' + + ;; + timedatectl) + _arguments -s \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + '--adjust-system-clock[Adjust system clock when changing local RTC mode]' \ + '--no-pager[Do not pipe output into a pager]' \ + '--no-ask-password[Do not prompt for password]' \ + {-H,--host=}'[Operate on remote host]:userathost:_hosts_or_user_at_host' \ + '*::timedatectl commands:_timedatectl_command' + ;; + udevadm) + _arguments \ + '--debug[Print debug messages to stderr]' \ + '--version[Print version number]' \ + '--help[Print help text]' \ + '*::udevadm commands:_udevadm_command' + ;; + systemd-analyze) + _arguments \ + {-h,--help}'[Show help text.]' \ + '--user[Shows performance data of user sessions instead of the system manager.]' \ + '--order[When generating graph for dot, show only order]' \ + '--require[When generating graph for dot, show only requirement]' \ + '*::systemd-analyze commands:_systemd_analyze_command' + ;; + systemd-ask-password) + _arguments \ + {-h,--help}'[Show this help]' \ + '--icon=[Icon name]' \ + '--timeout=[Timeout in sec]' \ + '--no-tty[Ask question via agent even on TTY]' \ + '--accept-cached[Accept cached passwords]' \ + '--multiple[List multiple passwords if available]' + ;; + systemd-cat) + _arguments \ + {-h,--help}'[Show this help]' \ + '--version[Show package version.]' \ + {-t,--identifier=}'[Set syslog identifier.]' \ + {-p,--priority=}'[Set priority value.]:value:({0..7})' \ + '--level-prefix=[Control whether level prefix shall be parsed.]:boolean:(1 0)' \ + ':Message' + ;; + systemd-cgls) + _arguments \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + '--no-pager[Do not pipe output into a pager]' \ + {-a,--all}'[Show all groups, including empty]' \ + '-k[Include kernel threads in output]' \ + ':cgroups:(cpuset cpu cpuacct memory devices freezer net_cls blkio)' + ;; + systemd-cgtop) + _arguments \ + {-h,--help}'[Show this help]' \ + '--version[Print version and exit]' \ + '(-c -m -i -t)-p[Order by path]' \ + '(-c -p -m -i)-t[Order by number of tasks]' \ + '(-m -p -i -t)-c[Order by CPU load]' \ + '(-c -p -i -t)-m[Order by memory load]' \ + '(-c -m -p -t)-i[Order by IO load]' \ + {-d,--delay=}'[Specify delay]' \ + {-n,--iterations=}'[Run for N iterations before exiting]' \ + {-b,--batch}'[Run in batch mode, accepting no input]' \ + '--depth=[Maximum traversal depth]' + ;; + systemd-delta) + _arguments \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + '--no-pager[Do not pipe output into a pager]' \ + '--diff=[Show a diff when overridden files differ]:boolean:(1 0)' \ + {-t,--type=}'[Only display a selected set of override types]:types:(masked equivalent redirected overridden unchanged)' \ + ':SUFFIX:(tmpfiles.d sysctl.d systemd/system)' + ;; + systemd-detect-virt) + _arguments \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + {-c,--container}'[Only detect whether we are run in a container]' \ + {-v,--vm}'[Only detect whether we are run in a VM]' \ + {-q,--quiet}"[Don't output anything, just set return value]" + ;; + systemd-inhibit) + _arguments \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + '--what=[Operations to inhibit]:options:(shutdown sleep idle handle-power-key handle-suspend-key handle-hibernate-key handle-lid-switch)' \ + '--who=[A descriptive string who is inhibiting]' \ + '--why=[A descriptive string why is being inhibited]' \ + '--mode=[One of block or delay]' \ + '--list[List active inhibitors]' \ + '*:commands:_systemd_inhibit_command' + ;; + systemd-machine-id-setup) + _arguments \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' + ;; + systemd-notify) + _arguments \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + '--ready[Inform the init system about service start-up completion.]' \ + '--pid=[Inform the init system about the main PID of the daemon]' \ + '--status=[Send a free-form status string for the daemon to the init systemd]' \ + '--booted[Returns 0 if the system was booted up with systemd]' \ + '--readahead=[Controls disk read-ahead operations]:arguments:(cancel done noreply)' + ;; + systemd-nspawn) + _arguments \ + {-h,--help}'[Show this help]' \ + {--directory=,-D}'[Directory to use as file system root for the namespace container. If omitted the current directory will be used.]:directories:_directories' \ + {--boot,-b}'[Automatically search for an init binary and invoke it instead of a shell or a user supplied program.]' \ + {--user=,-u}'[Run the command under specified user, create home directory and cd into it.]' \ + '--uuid=[Set the specified uuid for the container.]' \ + {--controllers=,-C}'[Makes the container appear in other hierarchies than the name=systemd:/ one. Takes a comma-separated list of controllers.]' \ + '--private-network[Turn off networking in the container. This makes all network interfaces unavailable in the container, with the exception of the loopback device.]' \ + '--read-only[Mount the root file system read only for the container.]' \ + '--capability=[List one or more additional capabilities to grant the container.]:capabilities:_systemd-nspawn' \ + "--link-journal=[Control whether the container's journal shall be made visible to the host system.]:options:(no, host, guest, auto)" \ + '-j[Equivalent to --link-journal=guest.]' + ;; + systemd-tmpfiles) + _arguments \ + '--create[Create, set ownership/permissions based on the config files.]' \ + '--clean[Clean up all files and directories with an age parameter configured.]' \ + '--remove[All files and directories marked with r, R in the configuration files are removed.]' \ + '--prefix=[Only apply rules that apply to paths with the specified prefix.]' \ + '--exclude-prefix=[Ignore rules that apply to paths with the specified prefix.]' \ + '--help[Prints a short help text and exits.]' \ + '*::files:_files' + ;; + systemd-tty-ask-password-agent) + _arguments \ + {-h,--help}'[Prints a short help text and exits.]' \ + '--version[Prints a short version string and exits.]' \ + '--list[Lists all currently pending system password requests.]' \ + '--query[Process all currently pending system password requests by querying the user on the calling TTY.]' \ + '--watch[Continuously process password requests.]' \ + '--wall[Forward password requests to wall(1).]' \ + '--plymouth[Ask question with plymouth(8).]' \ + '--console[Ask question on /dev/console.]' + ;; + machinectl) + _arguments \ + {-h,--help}'[Prints a short help text and exits.]' \ + '--version[Prints a short version string and exits.]' \ + {-p,--property=}'[Limit output to specified property.]:property:(Name Id Timestamp TimestampMonotonic Service Scope Leader Class State RootDirectory)' \ + {-a,--all}'[Show all proerties]' \ + (-l,--full)'[Do not ellipsize cgroup members]' \ + '--no-pager[Do not pipe output into a pager]' \ + '--no-ask-password[Do not ask for system passwords]' \ + '--kill-who=[Who to send signal to]:killwho:(leader all)' \ + {-s,--signal=}'[Which signal to send]:signal:_signals' \ + {-H,--host=}'[Show information for remote host]:userathost:_hosts_or_user_at_host' \ + {-P,--privileged}'[Acquire privileges before execution]' \ + '*::machinectl command:_machinectl_command' + ;; + *) _message 'eh?' ;; + esac +} + +_systemd-nspawn(){ + local -a _caps + _caps=( CAP_CHOWN CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH + CAP_FOWNER CAP_FSETID CAP_IPC_OWNER CAP_KILL CAP_LEASE CAP_LINUX_IMMUTABLE + CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET_RAW CAP_SETGID CAP_SETFCAP CAP_SETPCAP + CAP_SETUID CAP_SYS_ADMIN CAP_SYS_CHROOT CAP_SYS_NICE CAP_SYS_PTRACE CAP_SYS_TTY_CONFIG + CAP_SYS_RESOURCE CAP_SYS_BOOT ) + _values -s , 'capabilities' "$_caps[@]" +} + +_systemd_inhibit_command(){ + if (( CURRENT == 1 )); then + compset -q + _normal + else + local n=${words[(b:2:i)[^-]*]} + if (( n <= CURRENT )); then + compset -n $n + _alternative \ + 'files:file:_files' \ + 'commands:command:_normal' && return 0 + fi + _default + fi + +} + +_systemd_analyze_command(){ + local -a _systemd_analyze_cmds + # Descriptions taken from systemd-analyze --help. + _systemd_analyze_cmds=( + 'time:Print time spent in the kernel before reaching userspace' + 'blame:Print list of running units ordered by time to init' + 'critical-chain:Print a tree of the time critical chain of units' + 'plot:Output SVG graphic showing service initialization' + 'dot:Dump dependency graph (in dot(1) format)' + ) + + if (( CURRENT == 1 )); then + _describe "options" _systemd_analyze_cmds + else + _message "no more options" + fi +} + +_hosts_or_user_at_host() +{ + _alternative \ + 'users-hosts:: _user_at_host' \ + 'hosts:: _hosts' +} + +_outputmodes() { + local -a _output_opts + _output_opts=(short short-monotonic verbose export json json-pretty json-see cat) + _describe -t output 'output mode' _output_opts || compadd "$@" +} + + +(( $+functions[_systemctl_command] )) || _systemctl_command() +{ + local -a _systemctl_cmds + _systemctl_cmds=( + "list-units:List units" + "start:Start (activate) one or more units" + "stop:Stop (deactivate) one or more units" + "reload:Reload one or more units" + "restart:Start or restart one or more units" + "condrestart:Restart one or more units if active" + "try-restart:Restart one or more units if active" + "reload-or-restart:Reload one or more units if possible, otherwise start or restart" + "force-reload:Reload one or more units if possible, otherwise restart if active" + "hibernate:Hibernate the system" + "hybrid-sleep:Hibernate and suspend the system" + "reload-or-try-restart:Reload one or more units if possible, otherwise restart if active" + "isolate:Start one unit and stop all others" + "kill:Send signal to processes of a unit" + "is-active:Check whether units are active" + "is-failed:Check whether units are failed" + "status:Show runtime status of one or more units" + "show:Show properties of one or more units/jobs or the manager" + "reset-failed:Reset failed state for all, one, or more units" + "load:Load one or more units" + "list-unit-files:List installed unit files" + "enable:Enable one or more unit files" + "disable:Disable one or more unit files" + "reenable:Reenable one or more unit files" + "preset:Enable/disable one or more unit files based on preset configuration" + "help:Show documentation for specified units" + "list-dependencies:Show unit dependency tree" + "mask:Mask one or more units" + "unmask:Unmask one or more units" + "link:Link one or more units files into the search path" + "is-enabled:Check whether unit files are enabled" + "list-jobs:List jobs" + "cancel:Cancel all, one, or more jobs" + "dump:Dump server status" + "snapshot:Create a snapshot" + "delete:Remove one or more snapshots" + "show-environment:Dump environment" + "set-environment:Set one or more environment variables" + "unset-environment:Unset one or more environment variables" + "daemon-reload:Reload systemd manager configuration" + "daemon-reexec:Reexecute systemd manager" + "default:Enter system default mode" + "rescue:Enter system rescue mode" + "emergency:Enter system emergency mode" + "halt:Shut down and halt the system" + "suspend:Suspend the system" + "poweroff:Shut down and power-off the system" + "reboot:Shut down and reboot the system" + "kexec:Shut down and reboot the system with kexec" + "exit:Ask for user instance termination" + ) + + if (( CURRENT == 1 )); then + _describe -t commands 'systemctl command' _systemctl_cmds || compadd "$@" + else + local curcontext="$curcontext" + + cmd="${${_systemctl_cmds[(r)$words[1]:*]%%:*}}" + # Deal with any aliases + case $cmd in + condrestart) cmd="try-restart";; + force-reload) cmd="reload-or-try-restart";; + esac + + if (( $#cmd )); then + curcontext="${curcontext%:*:*}:systemctl-${cmd}:" + + local update_policy + zstyle -s ":completion:${curcontext}:" cache-policy update_policy + if [[ -z "$update_policy" ]]; then + zstyle ":completion:${curcontext}:" cache-policy _systemctl_caching_policy + fi + + _call_function ret _systemctl_$cmd || _message 'no more arguments' + else + _message "unknown systemctl command: $words[1]" + fi + return ret + fi +} + +__systemctl() +{ + local -a _modes + _modes=("--user" "--system") + systemctl ${words:*_modes} --full --no-legend --no-pager "$@" +} + + +# Fills the unit list +_systemctl_all_units() +{ + if ( [[ ${+_sys_all_units} -eq 0 ]] || _cache_invalid SYS_ALL_UNITS ) && + ! _retrieve_cache SYS_ALL_UNITS; + then + _sys_all_units=( $(__systemctl list-units --all | { while read a b; do echo " $a"; done; }) ) + _store_cache SYS_ALL_UNITS _sys_all_units + fi +} + +# Fills the unit list including all file units +_systemctl_really_all_units() +{ + local -a all_unit_files; + local -a really_all_units; + if ( [[ ${+_sys_really_all_units} -eq 0 ]] || _cache_invalid SYS_REALLY_ALL_UNITS ) && + ! _retrieve_cache SYS_REALLY_ALL_UNITS; + then + all_unit_files=( $(__systemctl list-unit-files | { while read a b; do echo " $a"; done; }) ) + _systemctl_all_units + really_all_units=($_sys_all_units $all_unit_files) + _sys_really_all_units=(${(u)really_all_units}) + _store_cache SYS_REALLY_ALL_UNITS _sys_really_all_units + fi +} + +_filter_units_by_property() { + local property=$1 value=$2 ; shift ; shift + local -a units ; units=($*) + local prop unit + for ((i=1; $i <= ${#units[*]}; i++)); do + # FIXME: "Failed to issue method call: Unknown unit" errors are ignored for + # now (related to DBUS_ERROR_UNKNOWN_OBJECT). in the future, we need to + # revert to calling 'systemctl show' once for all units, which is way + # faster + unit=${units[i]} + prop=${(f)"$(_call_program units "$service show --no-pager --property="$property" ${unit} 2>/dev/null")"} + if [[ "${prop}" = "$property=$value" ]]; then + echo " ${unit}" + fi + done +} + +_systemctl_active_units() {_sys_active_units=( $(__systemctl list-units | { while read a b; do echo " $a"; done; }) )} +_systemctl_inactive_units(){_sys_inactive_units=($(__systemctl list-units --all | { while read a b c d; do [[ $c == "inactive" || $c == "failed" ]] && echo " $a"; done; }) )} +_systemctl_failed_units() {_sys_failed_units=( $(__systemctl list-units --failed | { while read a b; do echo " $a"; done; }) )} +_systemctl_enabled_units() {_sys_enabled_units=( $(__systemctl list-unit-files | { while read a b; do [[ $b == "enabled" ]] && echo " $a"; done; }) )} +_systemctl_disabled_units(){_sys_disabled_units=($(__systemctl list-unit-files | { while read a b; do [[ $b == "disabled" ]] && echo " $a"; done; }) )} +_systemctl_masked_units() {_sys_masked_units=( $(__systemctl list-unit-files | { while read a b; do [[ $b == "masked" ]] && echo " $a"; done; }) )} + +# Completion functions for ALL_UNITS +for fun in is-active is-failed is-enabled status show mask preset help list-dependencies ; do + (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() + { + _systemctl_really_all_units + compadd "$@" -a - _sys_really_all_units + } +done + +# Completion functions for ENABLED_UNITS +for fun in disable reenable ; do + (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() + { + _systemctl_enabled_units + _systemctl_disabled_units + compadd "$@" -a - _sys_enabled_units _sys_disabled_units + } +done + +# Completion functions for DISABLED_UNITS +(( $+functions[_systemctl_enable] )) || _systemctl_enable() +{ + _systemctl_disabled_units + compadd "$@" -a - _sys_disabled_units +} + +# Completion functions for FAILED_UNITS +(( $+functions[_systemctl_reset-failed] )) || _systemctl_reset-failed() +{ + _systemctl_failed_units + compadd "$@" -a - _sys_failed_units || _message "no failed unit found" +} + +# Completion functions for STARTABLE_UNITS +(( $+functions[_systemctl_start] )) || _systemctl_start() +{ + _systemctl_inactive_units + compadd "$@" -a - _sys_inactive_units +} + +# Completion functions for STOPPABLE_UNITS +for fun in stop kill try-restart condrestart ; do + (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() + { + _systemctl_active_units + compadd "$@" - $( _filter_units_by_property CanStop yes \ + ${_sys_active_units[*]} ) + } +done + +# Completion functions for ISOLATABLE_UNITS +(( $+functions[_systemctl_isolate] )) || _systemctl_isolate() +{ + _systemctl_all_units + compadd "$@" - $( _filter_units_by_property AllowIsolate yes \ + ${_sys_all_units[*]} ) +} + +# Completion functions for RELOADABLE_UNITS +for fun in reload reload-or-try-restart force-reload ; do + (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() + { + _systemctl_active_units + compadd "$@" - $( _filter_units_by_property CanReload yes \ + ${_sys_active_units[*]} ) + } +done + +# Completion functions for RESTARTABLE_UNITS +for fun in restart reload-or-restart ; do + (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() + { + _systemctl_all_units + compadd "$@" - $( _filter_units_by_property CanStart yes \ + ${_sys_all_units[*]} | while read line; do \ + [[ "$line" =~ \.device$ ]] || echo " $line"; \ + done ) + } +done + +# Completion functions for MASKED_UNITS +(( $+functions[_systemctl_unmask] )) || _systemctl_unmask() +{ + _systemctl_masked_units + compadd "$@" -a - _sys_masked_units || _message "no masked unit found" +} + +# Completion functions for JOBS +(( $+functions[_systemctl_cancel] )) || _systemctl_cancel() +{ + compadd "$@" - $(__systemctl list-jobs \ + | cut -d' ' -f1 2>/dev/null ) || _message "no job found" +} + +# Completion functions for SNAPSHOTS +(( $+functions[_systemctl_delete] )) || _systemctl_delete() +{ + compadd "$@" - $(__systemctl list-units --type snapshot --all \ + | cut -d' ' -f1 2>/dev/null ) || _message "no snapshot found" +} + +# Completion functions for ENVS +for fun in set-environment unset-environment ; do + (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() + { + local fun=$0 ; fun=${fun##_systemctl_} + local suf + if [[ "${fun}" = "set-environment" ]]; then + suf='-S=' + fi + + compadd "$@" ${suf} - $(systemctl show-environment \ + | while read line; do echo " ${line%%\=}";done ) + } +done + +(( $+functions[_systemctl_link] )) || _systemctl_link() { _files } + +# no systemctl completion for: +# [STANDALONE]='daemon-reexec daemon-reload default dump +# emergency exit halt kexec list-jobs list-units +# list-unit-files poweroff reboot rescue show-environment' +# [NAME]='snapshot load' + +_systemctl_caching_policy() +{ + local _sysunits + local -a oldcache + + # rebuild if cache is more than a day old + oldcache=( "$1"(mh+1) ) + (( $#oldcache )) && return 0 + + _sysunits=($(__systemctl --all | cut -d' ' -f1)) + + if (( $#_sysunits )); then + for unit in $_sysunits; do + [[ "$unit" -nt "$1" ]] && return 0 + done + fi + + return 1 +} + +_list_fields() { + local -a journal_fields + journal_fields=(MESSAGE{,_ID} PRIORITY CODE_{FILE,LINE,FUNC} + ERRNO SYSLOG_{FACILITY,IDENTIFIER,PID} + _{P,U,G}ID _COMM _EXE _CMDLINE + _AUDIT_{SESSION,LOGINUID} + _SYSTEMD_{CGROUP,SESSION,UNIT,OWNER_UID} + _SYSTEMD_USER_UNIT + _SELINUX_CONTEXT _SOURCE_REALTIME_TIMESTAMP + _{BOOT,MACHINE}_ID _HOSTNAME _TRANSPORT + _KERNEL_{DEVICE,SUBSYSTEM} + _UDEV_{SYSNAME,DEVNODE,DEVLINK} + __CURSOR __{REALTIME,MONOTONIC}_TIMESTAMP) + _describe 'possible fields' journal_fields +} + +_journal_none() { + local -a _commands _files + _commands=( ${(f)"$(_call_program commands "$service" -F _EXE 2>/dev/null)"} ) + _alternative : \ + 'files:/dev files:_files -W /dev -P /dev/' \ + "commands:commands:($_commands[@])" \ + 'fields:fields:_list_fields' +} + +_journal_fields() { + local -a _fields cmd + cmd=("journalctl" "-F ${@[-1]}" "2>/dev/null" ) + _fields=( ${(f)"$(_call_program fields $cmd[@])"} ) + typeset -U _fields + _describe 'possible values' _fields +} + + +_loginctl_all_sessions(){_sys_all_sessions=($(loginctl list-sessions | { while read a b; do echo " $a"; done; }) )} +_loginctl_all_users() {_sys_all_users=( $(loginctl list-users | { while read a b; do echo " $a"; done; }) )} +_loginctl_all_seats() {_sys_all_seats=( $(loginctl list-seats | { while read a b; do echo " $a"; done; }) )} + +# Completion functions for SESSIONS +for fun in session-status show-session activate lock-session unlock-session terminate-session kill-session ; do + (( $+functions[_loginctl_$fun] )) || _loginctl_$fun() + { + _loginctl_all_sessions + compadd "$@" -a - _sys_all_sessions + } +done + +# Completion functions for USERS +for fun in user-status show-user enable-linger disable-linger terminate-user kill-user ; do + (( $+functions[_loginctl_$fun] )) || _loginctl_$fun() + { + _loginctl_all_users + compadd "$@" -a - _sys_all_users + } +done + +# Completion functions for SEATS +(( $+functions[_loginctl_seats] )) || _loginctl_seats() +{ + _loginctl_all_seats + compadd "$@" -a - _sys_all_seats +} +for fun in seat-status show-seat terminate-seat ; do + (( $+functions[_loginctl_$fun] )) || _loginctl_$fun() + { _loginctl_seats } +done + +# Completion functions for ATTACH +(( $+functions[_loginctl_attach] )) || _loginctl_attach() +{ + _loginctl_all_seats + + _arguments -w -C -S -s \ + ':seat:_loginctl_seats' \ + '*:device:_files' +} + +# no loginctl completion for: +# [STANDALONE]='list-sessions list-users list-seats flush-devices' + +(( $+functions[_loginctl_command] )) || _loginctl_command() +{ + local -a _loginctl_cmds + _loginctl_cmds=( + "list-sessions:List sessions" + "session-status:Show session status" + "show-session:Show properties of one or more sessions" + "activate:Activate a session" + "lock-session:Screen lock one or more sessions" + "unlock-session:Screen unlock one or more sessions" + "terminate-session:Terminate one or more sessions" + "kill-session:Send signal to processes of a session" + "list-users:List users" + "user-status:Show user status" + "show-user:Show properties of one or more users" + "enable-linger:Enable linger state of one or more users" + "disable-linger:Disable linger state of one or more users" + "terminate-user:Terminate all sessions of one or more users" + "kill-user:Send signal to processes of a user" + "list-seats:List seats" + "seat-status:Show seat status" + "show-seat:Show properties of one or more seats" + "attach:Attach one or more devices to a seat" + "flush-devices:Flush all device associations" + "terminate-seat:Terminate all sessions on one or more seats" + ) + + if (( CURRENT == 1 )); then + _describe -t commands 'loginctl command' _loginctl_cmds || compadd "$@" + else + local curcontext="$curcontext" + + cmd="${${_loginctl_cmds[(r)$words[1]:*]%%:*}}" + + if (( $#cmd )); then + curcontext="${curcontext%:*:*}:loginctl-${cmd}:" + + _call_function ret _loginctl_$cmd || _message 'no more arguments' + else + _message "unknown loginctl command: $words[1]" + fi + return ret + fi +} + +_hostnamectl_command() { + local -a _hostnamectl_cmds + _hostnamectl_cmds=( + "status:Show current hostname settings" + "set-hostname:Set system hostname" + "set-icon-name:Set icon name for host" + ) + if (( CURRENT == 1 )); then + _describe -t commands 'hostnamectl commands' _hostnamectl_cmds || compadd "$@" + else + local curcontext="$curcontext" + cmd="${${_hostnamectl_cmds[(r)$words[1]:*]%%:*}}" + if (( $#cmd )); then + [[ $cmd == status ]] && msg="no options" || msg="options for $cmd" + _message "$msg" + else + _message "unknown hostnamectl command: $words[1]" + fi + fi +} + +_localectl_set-locale() { + local -a _confs _locales + local expl suf + _locales=( ${(f)"$(_call_program locales "$service" list-locales)"} ) + _confs=( ${${(f)"$(_call_program confs "locale 2>/dev/null")"}%\=*} ) + if [[ -prefix 1 *\= ]]; then + local conf=${PREFIX%%\=*} + compset -P1 '*=' + _wanted locales expl "locales configs" \ + _combination localeconfs confs=$conf locales "$@" - + else + compadd -S '=' $_confs + fi +} + +_localectl_set-keymap() { + local -a _keymaps + _keymaps=( ${(f)"$(_call_program locales "$service" list-keymaps)"} ) + if (( CURRENT <= 3 )); then + _describe keymaps _keymaps + else + _message "no more options" + fi +} + +_localectl_set-x11-keymap() { + if (( $+commands[pkg-config] )); then + local -a _file _layout _model _variant _options + local _xorg_lst + _xorg_lst=${"$($commands[pkg-config] xkeyboard-config --variable=xkb_base)"} + _file=( ${(ps:\n\!:)"$(<$_xorg_lst/rules/xorg.lst)"} ) + _layout=( ${${${(M)${(f)_file[1]}:# *}# }%% *} ) + _model=( ${${${(M)${(f)_file[2]}:# *}# }%% *} ) + _variant=( ${${${(M)${(f)_file[3]}:# *}# }%% *} ) + _options=( ${${${(M)${(f)_file[4]}:# *}# }%% *} ) + #_layout=( ${(f)"$( echo $_file[1] | awk '/^ / {print $1}' )"} ) + #_model=( ${(f)"$(echo $_file[2] | awk '/^ / {print $1}')"} ) + #_variant=( ${(f)"$(echo $_file[3] | awk '/^ / {print $1}')"} ) + #_options=( ${(f)"$(echo ${_file[4]//:/\\:} | awk '/^ / {print $1}')"} ) + + case $CURRENT in + 2) _describe layouts _layout ;; + 3) _describe models _model;; + 4) _describe variants _variant;; + 5) _describe options _options;; + *) _message "no more options" + esac + fi +} + + +_localectl_command() { + local -a _localectl_cmds + _localectl_cmds=( + 'status:Show current locale settings' + 'set-locale:Set system locale' + 'list-locales:Show known locales' + 'set-keymap:Set virtual console keyboard mapping' + 'list-keymaps:Show known virtual console keyboard mappings' + 'set-x11-keymap:Set X11 keyboard mapping' + ) + if (( CURRENT == 1 )); then + _describe -t commands 'localectl command' _localectl_cmds + else + local curcontext="$curcontext" + cmd="${${_localectl_cmds[(r)$words[1]:*]%%:*}}" + if (( $+functions[_localectl_$cmd] )); then + _localectl_$cmd + else + _message "no more options" + fi + fi +} + +_timedatectl_set-timezone(){ + local -a _timezones + _timezones=( ${(f)"$(_call_program timezones "${service}" list-timezones)"} ) + compadd "$_timezones[@]" +} + +_timedatectl_set-time(){ + _message "YYYY-MM-DD HH:MM:SS" +} + +_timedatectl_set-local-rtc(){ + local -a _options + _options=( + '0:Maintain RTC in universal time' + '1:Maintain RTC in local time' + ) + _describe options _options +} + +_timedatectl_set-ntp(){ + local -a _options + _options=( + '0:Disable NTP based network time configuration' + '1:Enable NTP based network time configuration' + ) + _describe options _options +} + +_timedatectl_command(){ + local -a _timedatectl_cmds + _timedatectl_cmds=( + 'status:Show current time settings' + 'set-time:Set system time' + 'set-timezone:Set system timezone' + 'list-timezones:Show known timezones' + 'set-local-rtc:Control whether RTC is in local time' + 'set-ntp:Control whether NTP is enabled' + ) + if (( CURRENT == 1 )); then + _describe -t commands 'timedatectl command' _timedatectl_cmds + else + local curcontext="$curcontext" + cmd="${${_timedatectl_cmds[(r)$words[1]:*]%%:*}}" + if (( $#cmd )); then + if (( $+functions[_timedatectl_$cmd] )); then + _timedatectl_$cmd + else + _message "no more options" + fi + else + _message "unknown timedatectl command: $words[1]" + fi + fi +} +_systemd-coredumpctl_command(){ + local -a _systemd_coredumpctl_cmds + _systemd_coredumpctl_cmds=( + 'list:List available coredumps' + 'dump:Print coredump to std' + ) + if (( CURRENT == 1 )); then + _describe -t commands 'systemd-coredumpctl command' _systemd_coredumpctl_cmds + else + local curcontext="$curcontext" + local -a _dumps + cmd="${${_systemd_coredumpctl_cmds[(r)$words[1]:*]%%:*}}" + if (( $#cmd )); then + # user can set zstyle ':completion:*:*:systemd-coredumpctl:*' sort no for coredumps to be ordered by date, otherwise they get ordered by pid + _dumps=( "${(foa)$(systemd-coredumpctl list | awk 'BEGIN{OFS=":"} /^\s/ {sub(/[[ \t]+/, ""); print $5,$0}' 2>/dev/null)}" ) + if [[ -n "$_dumps" ]]; then + _describe -t pids 'coredumps' _dumps + else + _message "no coredumps" + fi + else + _message "no more options" + fi + + fi + +} + +(( $+functions[_machinectl_command] )) || _machinectl_command() +{ + local -a _machinectl_cmds + _machinectl_cmds=( + "list:List currently running VMs/containers" + "status:Show VM/container status" + "show:Show properties of one or more VMs/containers" + "terminate:Terminate one or more VMs/containers" + "kill:Send signal to process or a VM/container" + ) + if (( CURRENT == 1 )); then + _describe -t commands 'machinectl command' _machinectl_cmds || compadd "$@" + else + local curcontext="$curcontext" + cmd="${${_machinectl_cmds[(r)$words[1]:*]%%:*}}" + if (( $#cmd )); then + case $cmd in + list) msg="no options" ;; + *) + _machines=( "${(foa)$(machinectl list | awk '{print $1}')}" ) + if [[ -n "$_machines" ]]; then + _describe 'machines' _machines + else + _message 'no machines' + fi + esac + else + _message "no more options" + fi + fi +} + +_udevadm_info(){ + _arguments \ + '--query=[Query the database for specified type of device data. It needs the --path or --name to identify the specified device.]:type:(name symlink path property all)' \ + '--path=[The devpath of the device to query.]:sys files:_files -P /sys/ -W /sys' \ + '--name=[The name of the device node or a symlink to query]:device files:_files -P /dev/ -W /dev' \ + '--root[Print absolute paths in name or symlink query.]' \ + '--attribute-walk[Print all sysfs properties of the specified device that can be used in udev rules to match the specified device]' \ + '--export[Print output as key/value pairs.]' \ + '--export-prefix=[Add a prefix to the key name of exported values.]:prefix' \ + '--device-id-of-file=[Print major/minor numbers of the underlying device, where the file lives on.]:files:_udevadm_mounts' \ + '--export-db[Export the content of the udev database.]' \ + '--cleanup-db[Cleanup the udev database.]' +} + +_udevadm_trigger(){ + _arguments \ + '--verbose[Print the list of devices which will be triggered.]' \ + '--dry-run[Do not actually trigger the event.]' \ + '--type=[Trigger a specific type of devices.]:types:(devices subsystems failed)' \ + '--action=[Type of event to be triggered.]:actions:(add change remove)' \ + '--subsystem-match=[Trigger events for devices which belong to a matching subsystem.]' \ + '--subsystem-nomatch=[Do not trigger events for devices which belong to a matching subsystem.]' \ + '--attr-match=attribute=[Trigger events for devices with a matching sysfs attribute.]' \ + '--attr-nomatch=attribute=[Do not trigger events for devices with a matching sysfs attribute.]' \ + '--property-match=[Trigger events for devices with a matching property value.]' \ + '--tag-match=property[Trigger events for devices with a matching tag.]' \ + '--sysname-match=[Trigger events for devices with a matching sys device name.]' \ + '--parent-match=[Trigger events for all children of a given device.]' +} + +_udevadm_settle(){ + _arguments \ + '--timeout=[Maximum number of seconds to wait for the event queue to become empty.]' \ + '--seq-start=[Wait only for events after the given sequence number.]' \ + '--seq-end=[Wait only for events before the given sequence number.]' \ + '--exit-if-exists=[Stop waiting if file exists.]:files:_files' \ + '--quiet[Do not print any output, like the remaining queue entries when reaching the timeout.]' \ + '--help[Print help text.]' +} + +_udevadm_control(){ + _arguments \ + '--exit[Signal and wait for systemd-udevd to exit.]' \ + '--log-priority=[Set the internal log level of systemd-udevd.]:priorities:(err info debug)' \ + '--stop-exec-queue[Signal systemd-udevd to stop executing new events. Incoming events will be queued.]' \ + '--start-exec-queue[Signal systemd-udevd to enable the execution of events.]' \ + '--reload[Signal systemd-udevd to reload the rules files and other databases like the kernel module index.]' \ + '--property=[Set a global property for all events.]' \ + '--children-max=[Set the maximum number of events.]' \ + '--timeout=[The maximum number of seconds to wait for a reply from systemd-udevd.]' \ + '--help[Print help text.]' +} + +_udevadm_monitor(){ + _arguments \ + '--kernel[Print the kernel uevents.]' \ + '--udev[Print the udev event after the rule processing.]' \ + '--property[Also print the properties of the event.]' \ + '--subsystem-match=[Filter events by subsystem/\[devtype\].]' \ + '--tag-match=[Filter events by property.]' \ + '--help[Print help text.]' +} + +_udevadm_test(){ + _arguments \ + '--action=[The action string.]:actions:(add change remove)' \ + '--subsystem=[The subsystem string.]' \ + '--help[Print help text.]' \ + '*::devpath:_files -P /sys/ -W /sys' +} + +_udevadm_test-builtin(){ + if (( CURRENT == 2 )); then + _arguments \ + '--help[Print help text]' \ + '*::builtins:(blkid btrfs hwdb input_id kmod path_id usb_id uaccess)' + elif (( CURRENT == 3 )); then + _arguments \ + '--help[Print help text]' \ + '*::syspath:_files -P /sys -W /sys' + else + _arguments \ + '--help[Print help text]' + fi +} + +_udevadm_mounts(){ + local dev_tmp dpath_tmp mp_tmp mline + + tmp=( "${(@f)$(< /etc/mtab)}" ) + dev_tmp=( "${(@)${(@)tmp%% *}:#none}" ) + mp_tmp=( "${(@)${(@)tmp#* }%% *}" ) + + local MATCH + mp_tmp=("${(@q)mp_tmp//(#m)\\[0-7](#c3)/${(#)$(( 8#${MATCH[2,-1]} ))}}") + dpath_tmp=( "${(@Mq)dev_tmp:#/*}" ) + dev_tmp=( "${(@q)dev_tmp:#/*}" ) + + _alternative \ + 'device-paths: device path:compadd -a dpath_tmp' \ + 'directories:mount point:compadd -a mp_tmp' +} + + +_udevadm_command(){ + local -a _udevadm_cmds + _udevadm_cmds=( + 'info:query sysfs or the udev database' + 'trigger:request events from the kernel' + 'settle:wait for the event queue to finish' + 'control:control the udev daemon' + 'monitor:listen to kernel and udev events' + 'test:test an event run' + 'test-builtin:test a built-in command' + ) + + if ((CURRENT == 1)); then + _describe -t commands 'udevadm commands' _udevadm_cmds + else + local curcontext="$curcontext" + cmd="${${_udevadm_cmds[(r)$words[1]:*]%%:*}}" + if (($#cmd)); then + if (( $+functions[_udevadm_$cmd] )); then + _udevadm_$cmd + else + _message "no options for $cmd" + fi + else + _message "no more options" + fi + fi +} + +_ctls "$@" + +#vim: set ft=zsh sw=4 ts=4 et -- cgit v1.2.1 From ff7a0685a9aaa621f14bfe7cd36010a3236f775a Mon Sep 17 00:00:00 2001 From: William Giokas <1007380@gmail.com> Date: Mon, 29 Jul 2013 14:02:01 -0500 Subject: zsh_completion: Split out zsh _systemctl --- Makefile.am | 1 + shell-completion/zsh/_systemctl | 340 ++++++++++++++++++++++++++++++++++++++++ shell-completion/zsh/_systemd | 327 +------------------------------------- 3 files changed, 342 insertions(+), 326 deletions(-) create mode 100644 shell-completion/zsh/_systemctl diff --git a/Makefile.am b/Makefile.am index 27e03cefad..bfb70b18cb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -344,6 +344,7 @@ dist_bashcompletion_DATA = \ shell-completion/bash/kernel-install dist_zshcompletion_DATA = \ + shell-completion/zsh/_systemctl \ shell-completion/zsh/_systemd dist_sysctl_DATA = \ diff --git a/shell-completion/zsh/_systemctl b/shell-completion/zsh/_systemctl new file mode 100644 index 0000000000..70d6f3394a --- /dev/null +++ b/shell-completion/zsh/_systemctl @@ -0,0 +1,340 @@ +#compdef systemctl + +(( $+functions[_systemctl_command] )) || _systemctl_command() +{ + local -a _systemctl_cmds + _systemctl_cmds=( + "list-units:List units" + "start:Start (activate) one or more units" + "stop:Stop (deactivate) one or more units" + "reload:Reload one or more units" + "restart:Start or restart one or more units" + "condrestart:Restart one or more units if active" + "try-restart:Restart one or more units if active" + "reload-or-restart:Reload one or more units if possible, otherwise start or restart" + "force-reload:Reload one or more units if possible, otherwise restart if active" + "hibernate:Hibernate the system" + "hybrid-sleep:Hibernate and suspend the system" + "reload-or-try-restart:Reload one or more units if possible, otherwise restart if active" + "isolate:Start one unit and stop all others" + "kill:Send signal to processes of a unit" + "is-active:Check whether units are active" + "is-failed:Check whether units are failed" + "status:Show runtime status of one or more units" + "show:Show properties of one or more units/jobs or the manager" + "reset-failed:Reset failed state for all, one, or more units" + "load:Load one or more units" + "list-unit-files:List installed unit files" + "enable:Enable one or more unit files" + "disable:Disable one or more unit files" + "reenable:Reenable one or more unit files" + "preset:Enable/disable one or more unit files based on preset configuration" + "help:Show documentation for specified units" + "list-dependencies:Show unit dependency tree" + "mask:Mask one or more units" + "unmask:Unmask one or more units" + "link:Link one or more units files into the search path" + "is-enabled:Check whether unit files are enabled" + "list-jobs:List jobs" + "cancel:Cancel all, one, or more jobs" + "dump:Dump server status" + "snapshot:Create a snapshot" + "delete:Remove one or more snapshots" + "show-environment:Dump environment" + "set-environment:Set one or more environment variables" + "unset-environment:Unset one or more environment variables" + "daemon-reload:Reload systemd manager configuration" + "daemon-reexec:Reexecute systemd manager" + "default:Enter system default mode" + "rescue:Enter system rescue mode" + "emergency:Enter system emergency mode" + "halt:Shut down and halt the system" + "suspend:Suspend the system" + "poweroff:Shut down and power-off the system" + "reboot:Shut down and reboot the system" + "kexec:Shut down and reboot the system with kexec" + "exit:Ask for user instance termination" + ) + + if (( CURRENT == 1 )); then + _describe -t commands 'systemctl command' _systemctl_cmds || compadd "$@" + else + local curcontext="$curcontext" + + cmd="${${_systemctl_cmds[(r)$words[1]:*]%%:*}}" + # Deal with any aliases + case $cmd in + condrestart) cmd="try-restart";; + force-reload) cmd="reload-or-try-restart";; + esac + + if (( $#cmd )); then + curcontext="${curcontext%:*:*}:systemctl-${cmd}:" + + local update_policy + zstyle -s ":completion:${curcontext}:" cache-policy update_policy + if [[ -z "$update_policy" ]]; then + zstyle ":completion:${curcontext}:" cache-policy _systemctl_caching_policy + fi + + _call_function ret _systemctl_$cmd || _message 'no more arguments' + else + _message "unknown systemctl command: $words[1]" + fi + return ret + fi +} + +__systemctl() +{ + local -a _modes + _modes=("--user" "--system") + systemctl ${words:*_modes} --full --no-legend --no-pager "$@" +} + + +# Fills the unit list +_systemctl_all_units() +{ + if ( [[ ${+_sys_all_units} -eq 0 ]] || _cache_invalid SYS_ALL_UNITS ) && + ! _retrieve_cache SYS_ALL_UNITS; + then + _sys_all_units=( $(__systemctl list-units --all | { while read a b; do echo " $a"; done; }) ) + _store_cache SYS_ALL_UNITS _sys_all_units + fi +} + +# Fills the unit list including all file units +_systemctl_really_all_units() +{ + local -a all_unit_files; + local -a really_all_units; + if ( [[ ${+_sys_really_all_units} -eq 0 ]] || _cache_invalid SYS_REALLY_ALL_UNITS ) && + ! _retrieve_cache SYS_REALLY_ALL_UNITS; + then + all_unit_files=( $(__systemctl list-unit-files | { while read a b; do echo " $a"; done; }) ) + _systemctl_all_units + really_all_units=($_sys_all_units $all_unit_files) + _sys_really_all_units=(${(u)really_all_units}) + _store_cache SYS_REALLY_ALL_UNITS _sys_really_all_units + fi +} + +_filter_units_by_property() { + local property=$1 value=$2 ; shift ; shift + local -a units ; units=($*) + local prop unit + for ((i=1; $i <= ${#units[*]}; i++)); do + # FIXME: "Failed to issue method call: Unknown unit" errors are ignored for + # now (related to DBUS_ERROR_UNKNOWN_OBJECT). in the future, we need to + # revert to calling 'systemctl show' once for all units, which is way + # faster + unit=${units[i]} + prop=${(f)"$(_call_program units "$service show --no-pager --property="$property" ${unit} 2>/dev/null")"} + if [[ "${prop}" = "$property=$value" ]]; then + echo " ${unit}" + fi + done +} + +_systemctl_active_units() {_sys_active_units=( $(__systemctl list-units | { while read a b; do echo " $a"; done; }) )} +_systemctl_inactive_units(){_sys_inactive_units=($(__systemctl list-units --all | { while read a b c d; do [[ $c == "inactive" || $c == "failed" ]] && echo " $a"; done; }) )} +_systemctl_failed_units() {_sys_failed_units=( $(__systemctl list-units --failed | { while read a b; do echo " $a"; done; }) )} +_systemctl_enabled_units() {_sys_enabled_units=( $(__systemctl list-unit-files | { while read a b; do [[ $b == "enabled" ]] && echo " $a"; done; }) )} +_systemctl_disabled_units(){_sys_disabled_units=($(__systemctl list-unit-files | { while read a b; do [[ $b == "disabled" ]] && echo " $a"; done; }) )} +_systemctl_masked_units() {_sys_masked_units=( $(__systemctl list-unit-files | { while read a b; do [[ $b == "masked" ]] && echo " $a"; done; }) )} + +# Completion functions for ALL_UNITS +for fun in is-active is-failed is-enabled status show mask preset help list-dependencies ; do + (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() + { + _systemctl_really_all_units + compadd "$@" -a - _sys_really_all_units + } +done + +# Completion functions for ENABLED_UNITS +for fun in disable reenable ; do + (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() + { + _systemctl_enabled_units + _systemctl_disabled_units + compadd "$@" -a - _sys_enabled_units _sys_disabled_units + } +done + +# Completion functions for DISABLED_UNITS +(( $+functions[_systemctl_enable] )) || _systemctl_enable() +{ + _systemctl_disabled_units + compadd "$@" -a - _sys_disabled_units +} + +# Completion functions for FAILED_UNITS +(( $+functions[_systemctl_reset-failed] )) || _systemctl_reset-failed() +{ + _systemctl_failed_units + compadd "$@" -a - _sys_failed_units || _message "no failed unit found" +} + +# Completion functions for STARTABLE_UNITS +(( $+functions[_systemctl_start] )) || _systemctl_start() +{ + _systemctl_inactive_units + compadd "$@" -a - _sys_inactive_units +} + +# Completion functions for STOPPABLE_UNITS +for fun in stop kill try-restart condrestart ; do + (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() + { + _systemctl_active_units + compadd "$@" - $( _filter_units_by_property CanStop yes \ + ${_sys_active_units[*]} ) + } +done + +# Completion functions for ISOLATABLE_UNITS +(( $+functions[_systemctl_isolate] )) || _systemctl_isolate() +{ + _systemctl_all_units + compadd "$@" - $( _filter_units_by_property AllowIsolate yes \ + ${_sys_all_units[*]} ) +} + +# Completion functions for RELOADABLE_UNITS +for fun in reload reload-or-try-restart force-reload ; do + (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() + { + _systemctl_active_units + compadd "$@" - $( _filter_units_by_property CanReload yes \ + ${_sys_active_units[*]} ) + } +done + +# Completion functions for RESTARTABLE_UNITS +for fun in restart reload-or-restart ; do + (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() + { + _systemctl_all_units + compadd "$@" - $( _filter_units_by_property CanStart yes \ + ${_sys_all_units[*]} | while read line; do \ + [[ "$line" =~ \.device$ ]] || echo " $line"; \ + done ) + } +done + +# Completion functions for MASKED_UNITS +(( $+functions[_systemctl_unmask] )) || _systemctl_unmask() +{ + _systemctl_masked_units + compadd "$@" -a - _sys_masked_units || _message "no masked unit found" +} + +# Completion functions for JOBS +(( $+functions[_systemctl_cancel] )) || _systemctl_cancel() +{ + compadd "$@" - $(__systemctl list-jobs \ + | cut -d' ' -f1 2>/dev/null ) || _message "no job found" +} + +# Completion functions for SNAPSHOTS +(( $+functions[_systemctl_delete] )) || _systemctl_delete() +{ + compadd "$@" - $(__systemctl list-units --type snapshot --all \ + | cut -d' ' -f1 2>/dev/null ) || _message "no snapshot found" +} + +# Completion functions for ENVS +for fun in set-environment unset-environment ; do + (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() + { + local fun=$0 ; fun=${fun##_systemctl_} + local suf + if [[ "${fun}" = "set-environment" ]]; then + suf='-S=' + fi + + compadd "$@" ${suf} - $(systemctl show-environment \ + | while read line; do echo " ${line%%\=}";done ) + } +done + +(( $+functions[_systemctl_link] )) || _systemctl_link() { _files } + +# no systemctl completion for: +# [STANDALONE]='daemon-reexec daemon-reload default dump +# emergency exit halt kexec list-jobs list-units +# list-unit-files poweroff reboot rescue show-environment' +# [NAME]='snapshot load' + +_systemctl_caching_policy() +{ + local _sysunits + local -a oldcache + + # rebuild if cache is more than a day old + oldcache=( "$1"(mh+1) ) + (( $#oldcache )) && return 0 + + _sysunits=($(__systemctl --all | cut -d' ' -f1)) + + if (( $#_sysunits )); then + for unit in $_sysunits; do + [[ "$unit" -nt "$1" ]] && return 0 + done + fi + + return 1 +} + +_hosts_or_user_at_host() { + _alternative \ + 'users-hosts:: _user_at_host' \ + 'hosts:: _hosts' +} + +_outputmodes() { + local -a _output_opts + _output_opts=(short short-monotonic verbose export json json-pretty json-see cat) + _describe -t output 'output mode' _output_opts || compadd "$@" +} + +_arguments -s \ + {-h,--help}'[Show help]' \ + '--version[Show package version]' \ + {-t,--type=}'[List only units of a particular type]:unit type:(automount device mount path service snapshot socket swap target timer)' \ + '--state=[Display units in the specifyied state]:unit state:(loaded failed active inactive not-found listening running waiting plugged mounted exited dead masked)' \ + \*{-p,--property=}'[Show only properties by specific name]:unit property' \ + {-a,--all}'[Show all units/properties, including dead/empty ones]' \ + '--reverse[Show reverse dependencies]' \ + '--after[Show units ordered after]' \ + '--before[Show units ordered before]' \ + '--failed[Show only failed units]' \ + {-l,--full}"[Don't ellipsize unit names on output]" \ + '--fail[When queueing a new job, fail if conflicting jobs are pending]' \ + '--show-types[When showing sockets, show socket type]' \ + '--irreversible[Mark transactions as irreversible]' \ + '--ignore-dependencies[When queueing a new job, ignore all its dependencies]' \ + {-i,--ignore-inhibitors}'[When executing a job, ignore jobs dependencies]' \ + {-q,--quiet}'[Suppress output]' \ + '--no-block[Do not wait until operation finished]' \ + '--no-legend[Do not print a legend, i.e. the column headers and the footer with hints]' \ + '--no-pager[Do not pipe output into a pager]' \ + '--system[Connect to system manager]' \ + '--user[Connect to user service manager]' \ + "--no-wall[Don't send wall message before halt/power-off/reboot]" \ + '--global[Enable/disable unit files globally]' \ + "--no-reload[When enabling/disabling unit files, don't reload daemon configuration]" \ + '--no-ask-password[Do not ask for system passwords]' \ + '--kill-who=[Who to send signal to]:killwho:(main control all)' \ + {-s,--signal=}'[Which signal to send]:signal:_signals' \ + {-f,--force}'[When enabling unit files, override existing symlinks. When shutting down, execute action immediately]' \ + '--root=[Enable unit files in the specified root directory]:directory:_directories' \ + '--runtime[Enable unit files only temporarily until next reboot]' \ + {-H,--host=}'[Show information for remote host]:userathost:_hosts_or_user_at_host' \ + {-P,--privileged}'[Acquire privileges before execution]' \ + {-n,--lines=}'[Journal entries to show]:number of entries' \ + {-o,--output=}'[Change journal output mode]:modes:_outputmodes' \ + '--plain[When used with list-dependencies, print output as a list]' \ + '*::systemctl command:_systemctl_command' diff --git a/shell-completion/zsh/_systemd b/shell-completion/zsh/_systemd index 1ab1311ec1..64e0994dd8 100644 --- a/shell-completion/zsh/_systemd +++ b/shell-completion/zsh/_systemd @@ -1,45 +1,9 @@ -#compdef systemctl loginctl journalctl hostnamectl localectl timedatectl systemd-coredumpctl udevadm systemd-analyze systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-inhibit systemd-machine-id-setup systemd-notify systemd-nspawn systemd-tmpfiles systemd-tty-ask-password-agent machinectl +#compdef loginctl journalctl hostnamectl localectl timedatectl systemd-coredumpctl udevadm systemd-analyze systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-inhibit systemd-machine-id-setup systemd-notify systemd-nspawn systemd-tmpfiles systemd-tty-ask-password-agent machinectl _ctls() { local curcontext="$curcontext" state lstate line case "$service" in - systemctl) - # -s for aggregated options like -aP - _arguments -s \ - {-h,--help}'[Show help]' \ - '--version[Show package version]' \ - {-t,--type=}'[List only units of a particular type]:unit type:(automount device mount path service snapshot socket swap target timer)' \ - \*{-p,--property=}'[Show only properties by specific name]:unit property' \ - {-a,--all}'[Show all units/properties, including dead/empty ones]' \ - '--reverse[Show reverse dependencies]' \ - '--after[Show units ordered after]' \ - '--before[Show units ordered before]' \ - '--failed[Show only failed units]' \ - {-l,--full}"[Don't ellipsize unit names on output]" \ - '--fail[When queueing a new job, fail if conflicting jobs are pending]' \ - '--ignore-dependencies[When queueing a new job, ignore all its dependencies]' \ - '--kill-who=[Who to send signal to]:killwho:(main control all)' \ - {-s,--signal=}'[Which signal to send]:signal:_signals' \ - {-H,--host=}'[Show information for remote host]:userathost:_hosts_or_user_at_host' \ - {-P,--privileged}'[Acquire privileges before execution]' \ - {-q,--quiet}'[Suppress output]' \ - '--no-block[Do not wait until operation finished]' \ - "--no-wall[Don't send wall message before halt/power-off/reboot]" \ - "--no-reload[When enabling/disabling unit files, don't reload daemon configuration]" \ - '--no-legend[Do not print a legend, i.e. the column headers and the footer with hints]' \ - '--no-pager[Do not pipe output into a pager]' \ - '--no-ask-password[Do not ask for system passwords]' \ - '--system[Connect to system manager]' \ - '--user[Connect to user service manager]' \ - '--global[Enable/disable unit files globally]' \ - {-f,--force}'[When enabling unit files, override existing symlinks. When shutting down, execute action immediately]' \ - '--root=[Enable unit files in the specified root directory]:directory:_directories' \ - '--runtime[Enable unit files only temporarily until next reboot]' \ - {-n,--lines=}'[Journal entries to show]:number of entries' \ - {-o,--output=}'[Change journal output mode]:modes:_outputmodes' \ - '*::systemctl command:_systemctl_command' - ;; loginctl) _arguments -s \ {-h,--help}'[Show help]' \ @@ -341,295 +305,6 @@ _outputmodes() { _describe -t output 'output mode' _output_opts || compadd "$@" } - -(( $+functions[_systemctl_command] )) || _systemctl_command() -{ - local -a _systemctl_cmds - _systemctl_cmds=( - "list-units:List units" - "start:Start (activate) one or more units" - "stop:Stop (deactivate) one or more units" - "reload:Reload one or more units" - "restart:Start or restart one or more units" - "condrestart:Restart one or more units if active" - "try-restart:Restart one or more units if active" - "reload-or-restart:Reload one or more units if possible, otherwise start or restart" - "force-reload:Reload one or more units if possible, otherwise restart if active" - "hibernate:Hibernate the system" - "hybrid-sleep:Hibernate and suspend the system" - "reload-or-try-restart:Reload one or more units if possible, otherwise restart if active" - "isolate:Start one unit and stop all others" - "kill:Send signal to processes of a unit" - "is-active:Check whether units are active" - "is-failed:Check whether units are failed" - "status:Show runtime status of one or more units" - "show:Show properties of one or more units/jobs or the manager" - "reset-failed:Reset failed state for all, one, or more units" - "load:Load one or more units" - "list-unit-files:List installed unit files" - "enable:Enable one or more unit files" - "disable:Disable one or more unit files" - "reenable:Reenable one or more unit files" - "preset:Enable/disable one or more unit files based on preset configuration" - "help:Show documentation for specified units" - "list-dependencies:Show unit dependency tree" - "mask:Mask one or more units" - "unmask:Unmask one or more units" - "link:Link one or more units files into the search path" - "is-enabled:Check whether unit files are enabled" - "list-jobs:List jobs" - "cancel:Cancel all, one, or more jobs" - "dump:Dump server status" - "snapshot:Create a snapshot" - "delete:Remove one or more snapshots" - "show-environment:Dump environment" - "set-environment:Set one or more environment variables" - "unset-environment:Unset one or more environment variables" - "daemon-reload:Reload systemd manager configuration" - "daemon-reexec:Reexecute systemd manager" - "default:Enter system default mode" - "rescue:Enter system rescue mode" - "emergency:Enter system emergency mode" - "halt:Shut down and halt the system" - "suspend:Suspend the system" - "poweroff:Shut down and power-off the system" - "reboot:Shut down and reboot the system" - "kexec:Shut down and reboot the system with kexec" - "exit:Ask for user instance termination" - ) - - if (( CURRENT == 1 )); then - _describe -t commands 'systemctl command' _systemctl_cmds || compadd "$@" - else - local curcontext="$curcontext" - - cmd="${${_systemctl_cmds[(r)$words[1]:*]%%:*}}" - # Deal with any aliases - case $cmd in - condrestart) cmd="try-restart";; - force-reload) cmd="reload-or-try-restart";; - esac - - if (( $#cmd )); then - curcontext="${curcontext%:*:*}:systemctl-${cmd}:" - - local update_policy - zstyle -s ":completion:${curcontext}:" cache-policy update_policy - if [[ -z "$update_policy" ]]; then - zstyle ":completion:${curcontext}:" cache-policy _systemctl_caching_policy - fi - - _call_function ret _systemctl_$cmd || _message 'no more arguments' - else - _message "unknown systemctl command: $words[1]" - fi - return ret - fi -} - -__systemctl() -{ - local -a _modes - _modes=("--user" "--system") - systemctl ${words:*_modes} --full --no-legend --no-pager "$@" -} - - -# Fills the unit list -_systemctl_all_units() -{ - if ( [[ ${+_sys_all_units} -eq 0 ]] || _cache_invalid SYS_ALL_UNITS ) && - ! _retrieve_cache SYS_ALL_UNITS; - then - _sys_all_units=( $(__systemctl list-units --all | { while read a b; do echo " $a"; done; }) ) - _store_cache SYS_ALL_UNITS _sys_all_units - fi -} - -# Fills the unit list including all file units -_systemctl_really_all_units() -{ - local -a all_unit_files; - local -a really_all_units; - if ( [[ ${+_sys_really_all_units} -eq 0 ]] || _cache_invalid SYS_REALLY_ALL_UNITS ) && - ! _retrieve_cache SYS_REALLY_ALL_UNITS; - then - all_unit_files=( $(__systemctl list-unit-files | { while read a b; do echo " $a"; done; }) ) - _systemctl_all_units - really_all_units=($_sys_all_units $all_unit_files) - _sys_really_all_units=(${(u)really_all_units}) - _store_cache SYS_REALLY_ALL_UNITS _sys_really_all_units - fi -} - -_filter_units_by_property() { - local property=$1 value=$2 ; shift ; shift - local -a units ; units=($*) - local prop unit - for ((i=1; $i <= ${#units[*]}; i++)); do - # FIXME: "Failed to issue method call: Unknown unit" errors are ignored for - # now (related to DBUS_ERROR_UNKNOWN_OBJECT). in the future, we need to - # revert to calling 'systemctl show' once for all units, which is way - # faster - unit=${units[i]} - prop=${(f)"$(_call_program units "$service show --no-pager --property="$property" ${unit} 2>/dev/null")"} - if [[ "${prop}" = "$property=$value" ]]; then - echo " ${unit}" - fi - done -} - -_systemctl_active_units() {_sys_active_units=( $(__systemctl list-units | { while read a b; do echo " $a"; done; }) )} -_systemctl_inactive_units(){_sys_inactive_units=($(__systemctl list-units --all | { while read a b c d; do [[ $c == "inactive" || $c == "failed" ]] && echo " $a"; done; }) )} -_systemctl_failed_units() {_sys_failed_units=( $(__systemctl list-units --failed | { while read a b; do echo " $a"; done; }) )} -_systemctl_enabled_units() {_sys_enabled_units=( $(__systemctl list-unit-files | { while read a b; do [[ $b == "enabled" ]] && echo " $a"; done; }) )} -_systemctl_disabled_units(){_sys_disabled_units=($(__systemctl list-unit-files | { while read a b; do [[ $b == "disabled" ]] && echo " $a"; done; }) )} -_systemctl_masked_units() {_sys_masked_units=( $(__systemctl list-unit-files | { while read a b; do [[ $b == "masked" ]] && echo " $a"; done; }) )} - -# Completion functions for ALL_UNITS -for fun in is-active is-failed is-enabled status show mask preset help list-dependencies ; do - (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() - { - _systemctl_really_all_units - compadd "$@" -a - _sys_really_all_units - } -done - -# Completion functions for ENABLED_UNITS -for fun in disable reenable ; do - (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() - { - _systemctl_enabled_units - _systemctl_disabled_units - compadd "$@" -a - _sys_enabled_units _sys_disabled_units - } -done - -# Completion functions for DISABLED_UNITS -(( $+functions[_systemctl_enable] )) || _systemctl_enable() -{ - _systemctl_disabled_units - compadd "$@" -a - _sys_disabled_units -} - -# Completion functions for FAILED_UNITS -(( $+functions[_systemctl_reset-failed] )) || _systemctl_reset-failed() -{ - _systemctl_failed_units - compadd "$@" -a - _sys_failed_units || _message "no failed unit found" -} - -# Completion functions for STARTABLE_UNITS -(( $+functions[_systemctl_start] )) || _systemctl_start() -{ - _systemctl_inactive_units - compadd "$@" -a - _sys_inactive_units -} - -# Completion functions for STOPPABLE_UNITS -for fun in stop kill try-restart condrestart ; do - (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() - { - _systemctl_active_units - compadd "$@" - $( _filter_units_by_property CanStop yes \ - ${_sys_active_units[*]} ) - } -done - -# Completion functions for ISOLATABLE_UNITS -(( $+functions[_systemctl_isolate] )) || _systemctl_isolate() -{ - _systemctl_all_units - compadd "$@" - $( _filter_units_by_property AllowIsolate yes \ - ${_sys_all_units[*]} ) -} - -# Completion functions for RELOADABLE_UNITS -for fun in reload reload-or-try-restart force-reload ; do - (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() - { - _systemctl_active_units - compadd "$@" - $( _filter_units_by_property CanReload yes \ - ${_sys_active_units[*]} ) - } -done - -# Completion functions for RESTARTABLE_UNITS -for fun in restart reload-or-restart ; do - (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() - { - _systemctl_all_units - compadd "$@" - $( _filter_units_by_property CanStart yes \ - ${_sys_all_units[*]} | while read line; do \ - [[ "$line" =~ \.device$ ]] || echo " $line"; \ - done ) - } -done - -# Completion functions for MASKED_UNITS -(( $+functions[_systemctl_unmask] )) || _systemctl_unmask() -{ - _systemctl_masked_units - compadd "$@" -a - _sys_masked_units || _message "no masked unit found" -} - -# Completion functions for JOBS -(( $+functions[_systemctl_cancel] )) || _systemctl_cancel() -{ - compadd "$@" - $(__systemctl list-jobs \ - | cut -d' ' -f1 2>/dev/null ) || _message "no job found" -} - -# Completion functions for SNAPSHOTS -(( $+functions[_systemctl_delete] )) || _systemctl_delete() -{ - compadd "$@" - $(__systemctl list-units --type snapshot --all \ - | cut -d' ' -f1 2>/dev/null ) || _message "no snapshot found" -} - -# Completion functions for ENVS -for fun in set-environment unset-environment ; do - (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() - { - local fun=$0 ; fun=${fun##_systemctl_} - local suf - if [[ "${fun}" = "set-environment" ]]; then - suf='-S=' - fi - - compadd "$@" ${suf} - $(systemctl show-environment \ - | while read line; do echo " ${line%%\=}";done ) - } -done - -(( $+functions[_systemctl_link] )) || _systemctl_link() { _files } - -# no systemctl completion for: -# [STANDALONE]='daemon-reexec daemon-reload default dump -# emergency exit halt kexec list-jobs list-units -# list-unit-files poweroff reboot rescue show-environment' -# [NAME]='snapshot load' - -_systemctl_caching_policy() -{ - local _sysunits - local -a oldcache - - # rebuild if cache is more than a day old - oldcache=( "$1"(mh+1) ) - (( $#oldcache )) && return 0 - - _sysunits=($(__systemctl --all | cut -d' ' -f1)) - - if (( $#_sysunits )); then - for unit in $_sysunits; do - [[ "$unit" -nt "$1" ]] && return 0 - done - fi - - return 1 -} - _list_fields() { local -a journal_fields journal_fields=(MESSAGE{,_ID} PRIORITY CODE_{FILE,LINE,FUNC} -- cgit v1.2.1 From 799d54be0b681c0329539fca604261994e7f8c0e Mon Sep 17 00:00:00 2001 From: William Giokas <1007380@gmail.com> Date: Mon, 29 Jul 2013 14:03:43 -0500 Subject: zsh_completion: Split out zsh _loginctl --- Makefile.am | 3 ++ shell-completion/zsh/_loginctl | 112 +++++++++++++++++++++++++++++++++++++++++ shell-completion/zsh/_systemd | 109 +-------------------------------------- 3 files changed, 116 insertions(+), 108 deletions(-) create mode 100644 shell-completion/zsh/_loginctl diff --git a/Makefile.am b/Makefile.am index bfb70b18cb..9fa7944f37 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3714,6 +3714,9 @@ rootbin_PROGRAMS += \ dist_bashcompletion_DATA += \ shell-completion/bash/loginctl +dist_zshcompletion_DATA += \ + shell-completion/zsh/_loginctl + systemd_inhibit_SOURCES = \ src/login/inhibit.c diff --git a/shell-completion/zsh/_loginctl b/shell-completion/zsh/_loginctl new file mode 100644 index 0000000000..d121a2550c --- /dev/null +++ b/shell-completion/zsh/_loginctl @@ -0,0 +1,112 @@ +#compdef loginctl + +_hosts_or_user_at_host() { + _alternative \ + 'users-hosts:: _user_at_host' \ + 'hosts:: _hosts' +} + +_loginctl_all_sessions(){_sys_all_sessions=($(loginctl list-sessions | { while read a b; do echo " $a"; done; }) )} +_loginctl_all_users() {_sys_all_users=( $(loginctl list-users | { while read a b; do echo " $a"; done; }) )} +_loginctl_all_seats() {_sys_all_seats=( $(loginctl list-seats | { while read a b; do echo " $a"; done; }) )} + +# Completion functions for SESSIONS +for fun in session-status show-session activate lock-session unlock-session terminate-session kill-session ; do + (( $+functions[_loginctl_$fun] )) || _loginctl_$fun() + { + _loginctl_all_sessions + compadd "$@" -a - _sys_all_sessions + } +done + +# Completion functions for USERS +for fun in user-status show-user enable-linger disable-linger terminate-user kill-user ; do + (( $+functions[_loginctl_$fun] )) || _loginctl_$fun() + { + _loginctl_all_users + compadd "$@" -a - _sys_all_users + } +done + +# Completion functions for SEATS +(( $+functions[_loginctl_seats] )) || _loginctl_seats() +{ + _loginctl_all_seats + compadd "$@" -a - _sys_all_seats +} +for fun in seat-status show-seat terminate-seat ; do + (( $+functions[_loginctl_$fun] )) || _loginctl_$fun() + { _loginctl_seats } +done + +# Completion functions for ATTACH +(( $+functions[_loginctl_attach] )) || _loginctl_attach() +{ + _loginctl_all_seats + + _arguments -w -C -S -s \ + ':seat:_loginctl_seats' \ + '*:device:_files' +} + +# no loginctl completion for: +# [STANDALONE]='list-sessions list-users list-seats flush-devices' + +(( $+functions[_loginctl_command] )) || _loginctl_command() +{ + local -a _loginctl_cmds + _loginctl_cmds=( + "list-sessions:List sessions" + "session-status:Show session status" + "show-session:Show properties of one or more sessions" + "activate:Activate a session" + "lock-session:Screen lock one or more sessions" + "unlock-session:Screen unlock one or more sessions" + "terminate-session:Terminate one or more sessions" + "kill-session:Send signal to processes of a session" + "list-users:List users" + "user-status:Show user status" + "show-user:Show properties of one or more users" + "enable-linger:Enable linger state of one or more users" + "disable-linger:Disable linger state of one or more users" + "terminate-user:Terminate all sessions of one or more users" + "kill-user:Send signal to processes of a user" + "list-seats:List seats" + "seat-status:Show seat status" + "show-seat:Show properties of one or more seats" + "attach:Attach one or more devices to a seat" + "flush-devices:Flush all device associations" + "terminate-seat:Terminate all sessions on one or more seats" + ) + + if (( CURRENT == 1 )); then + _describe -t commands 'loginctl command' _loginctl_cmds || compadd "$@" + else + local curcontext="$curcontext" + + cmd="${${_loginctl_cmds[(r)$words[1]:*]%%:*}}" + + if (( $#cmd )); then + curcontext="${curcontext%:*:*}:loginctl-${cmd}:" + + _call_function ret _loginctl_$cmd || _message 'no more arguments' + else + _message "unknown loginctl command: $words[1]" + fi + return ret + fi +} + + +_arguments -s \ + {-h,--help}'[Show help]' \ + '--version[Show package version]' \ + \*{-p,--property=}'[Show only properties by this name]:unit property' \ + {-a,--all}'[Show all properties, including empty ones]' \ + '--kill-who=[Who to send signal to]:killwho:(main control all)' \ + {-s,--signal=}'[Which signal to send]:signal:_signals' \ + '--no-ask-password[Do not ask for system passwords]' \ + {-H,--host=}'[Show information for remote host]:userathost:_hosts_or_user_at_host' \ + {-P,--privileged}'[Acquire privileges before execution]' \ + '--no-pager[Do not pipe output into a pager]' \ + '*::loginctl command:_loginctl_command' diff --git a/shell-completion/zsh/_systemd b/shell-completion/zsh/_systemd index 64e0994dd8..80a14acb99 100644 --- a/shell-completion/zsh/_systemd +++ b/shell-completion/zsh/_systemd @@ -1,24 +1,9 @@ -#compdef loginctl journalctl hostnamectl localectl timedatectl systemd-coredumpctl udevadm systemd-analyze systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-inhibit systemd-machine-id-setup systemd-notify systemd-nspawn systemd-tmpfiles systemd-tty-ask-password-agent machinectl +#compdef journalctl hostnamectl localectl timedatectl systemd-coredumpctl udevadm systemd-analyze systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-inhibit systemd-machine-id-setup systemd-notify systemd-nspawn systemd-tmpfiles systemd-tty-ask-password-agent machinectl _ctls() { local curcontext="$curcontext" state lstate line case "$service" in - loginctl) - _arguments -s \ - {-h,--help}'[Show help]' \ - '--version[Show package version]' \ - \*{-p,--property=}'[Show only properties by this name]:unit property' \ - {-a,--all}'[Show all properties, including empty ones]' \ - '--kill-who=[Who to send signal to]:killwho:(main control all)' \ - {-s,--signal=}'[Which signal to send]:signal:_signals' \ - '--no-ask-password[Do not ask for system passwords]' \ - {-H,--host=}'[Show information for remote host]:userathost:_hosts_or_user_at_host' \ - {-P,--privileged}'[Acquire privileges before execution]' \ - '--no-pager[Do not pipe output into a pager]' \ - '*::loginctl command:_loginctl_command' - ;; - hostnamectl) _arguments -s \ {-h,--help}'[Show this help]' \ @@ -338,98 +323,6 @@ _journal_fields() { _describe 'possible values' _fields } - -_loginctl_all_sessions(){_sys_all_sessions=($(loginctl list-sessions | { while read a b; do echo " $a"; done; }) )} -_loginctl_all_users() {_sys_all_users=( $(loginctl list-users | { while read a b; do echo " $a"; done; }) )} -_loginctl_all_seats() {_sys_all_seats=( $(loginctl list-seats | { while read a b; do echo " $a"; done; }) )} - -# Completion functions for SESSIONS -for fun in session-status show-session activate lock-session unlock-session terminate-session kill-session ; do - (( $+functions[_loginctl_$fun] )) || _loginctl_$fun() - { - _loginctl_all_sessions - compadd "$@" -a - _sys_all_sessions - } -done - -# Completion functions for USERS -for fun in user-status show-user enable-linger disable-linger terminate-user kill-user ; do - (( $+functions[_loginctl_$fun] )) || _loginctl_$fun() - { - _loginctl_all_users - compadd "$@" -a - _sys_all_users - } -done - -# Completion functions for SEATS -(( $+functions[_loginctl_seats] )) || _loginctl_seats() -{ - _loginctl_all_seats - compadd "$@" -a - _sys_all_seats -} -for fun in seat-status show-seat terminate-seat ; do - (( $+functions[_loginctl_$fun] )) || _loginctl_$fun() - { _loginctl_seats } -done - -# Completion functions for ATTACH -(( $+functions[_loginctl_attach] )) || _loginctl_attach() -{ - _loginctl_all_seats - - _arguments -w -C -S -s \ - ':seat:_loginctl_seats' \ - '*:device:_files' -} - -# no loginctl completion for: -# [STANDALONE]='list-sessions list-users list-seats flush-devices' - -(( $+functions[_loginctl_command] )) || _loginctl_command() -{ - local -a _loginctl_cmds - _loginctl_cmds=( - "list-sessions:List sessions" - "session-status:Show session status" - "show-session:Show properties of one or more sessions" - "activate:Activate a session" - "lock-session:Screen lock one or more sessions" - "unlock-session:Screen unlock one or more sessions" - "terminate-session:Terminate one or more sessions" - "kill-session:Send signal to processes of a session" - "list-users:List users" - "user-status:Show user status" - "show-user:Show properties of one or more users" - "enable-linger:Enable linger state of one or more users" - "disable-linger:Disable linger state of one or more users" - "terminate-user:Terminate all sessions of one or more users" - "kill-user:Send signal to processes of a user" - "list-seats:List seats" - "seat-status:Show seat status" - "show-seat:Show properties of one or more seats" - "attach:Attach one or more devices to a seat" - "flush-devices:Flush all device associations" - "terminate-seat:Terminate all sessions on one or more seats" - ) - - if (( CURRENT == 1 )); then - _describe -t commands 'loginctl command' _loginctl_cmds || compadd "$@" - else - local curcontext="$curcontext" - - cmd="${${_loginctl_cmds[(r)$words[1]:*]%%:*}}" - - if (( $#cmd )); then - curcontext="${curcontext%:*:*}:loginctl-${cmd}:" - - _call_function ret _loginctl_$cmd || _message 'no more arguments' - else - _message "unknown loginctl command: $words[1]" - fi - return ret - fi -} - _hostnamectl_command() { local -a _hostnamectl_cmds _hostnamectl_cmds=( -- cgit v1.2.1 From db456cd0c65d0e7375b09b72ae6fb60f09e2eb6e Mon Sep 17 00:00:00 2001 From: William Giokas <1007380@gmail.com> Date: Mon, 29 Jul 2013 14:05:48 -0500 Subject: zsh_completion: Split out zsh _hostnamectl --- Makefile.am | 3 +++ shell-completion/zsh/_hostnamectl | 38 ++++++++++++++++++++++++++++++++++++++ shell-completion/zsh/_systemd | 34 +--------------------------------- 3 files changed, 42 insertions(+), 33 deletions(-) create mode 100644 shell-completion/zsh/_hostnamectl diff --git a/Makefile.am b/Makefile.am index 9fa7944f37..ba4035072c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3363,6 +3363,9 @@ bin_PROGRAMS += \ dist_bashcompletion_DATA += \ shell-completion/bash/hostnamectl +dist_zshcompletion_DATA += \ + shell-completion/zsh/_hostnamectl + endif polkitpolicy_in_files += \ diff --git a/shell-completion/zsh/_hostnamectl b/shell-completion/zsh/_hostnamectl new file mode 100644 index 0000000000..bc4441d560 --- /dev/null +++ b/shell-completion/zsh/_hostnamectl @@ -0,0 +1,38 @@ +#compdef hostnamectl + +_hosts_or_user_at_host() { + _alternative \ + 'users-hosts:: _user_at_host' \ + 'hosts:: _hosts' +} + +_hostnamectl_command() { + local -a _hostnamectl_cmds + _hostnamectl_cmds=( + "status:Show current hostname settings" + "set-hostname:Set system hostname" + "set-icon-name:Set icon name for host" + ) + if (( CURRENT == 1 )); then + _describe -t commands 'hostnamectl commands' _hostnamectl_cmds || compadd "$@" + else + local curcontext="$curcontext" + cmd="${${_hostnamectl_cmds[(r)$words[1]:*]%%:*}}" + if (( $#cmd )); then + [[ $cmd == status ]] && msg="no options" || msg="options for $cmd" + _message "$msg" + else + _message "unknown hostnamectl command: $words[1]" + fi + fi +} + +_arguments -s \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + '--transient[Only set transient hostname]' \ + '--static[Only set static hostname]' \ + '--pretty[Only set pretty hostname]' \ + '--no-ask-password[Do not prompt for password]' \ + {-H,--host=}'[Operate on remote host]:userathost:_hosts_or_user_at_host' \ + '*::hostnamectl commands:_hostnamectl_command' diff --git a/shell-completion/zsh/_systemd b/shell-completion/zsh/_systemd index 80a14acb99..ce7ea1ad4d 100644 --- a/shell-completion/zsh/_systemd +++ b/shell-completion/zsh/_systemd @@ -1,20 +1,9 @@ -#compdef journalctl hostnamectl localectl timedatectl systemd-coredumpctl udevadm systemd-analyze systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-inhibit systemd-machine-id-setup systemd-notify systemd-nspawn systemd-tmpfiles systemd-tty-ask-password-agent machinectl +#compdef journalctl localectl timedatectl systemd-coredumpctl udevadm systemd-analyze systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-inhibit systemd-machine-id-setup systemd-notify systemd-nspawn systemd-tmpfiles systemd-tty-ask-password-agent machinectl _ctls() { local curcontext="$curcontext" state lstate line case "$service" in - hostnamectl) - _arguments -s \ - {-h,--help}'[Show this help]' \ - '--version[Show package version]' \ - '--transient[Only set transient hostname]' \ - '--static[Only set static hostname]' \ - '--pretty[Only set pretty hostname]' \ - '--no-ask-password[Do not prompt for password]' \ - {-H,--host=}'[Operate on remote host]:userathost:_hosts_or_user_at_host' \ - '*::hostnamectl commands:_hostnamectl_command' - ;; journalctl) _arguments -s \ '--since=[Start showing entries newer or of the specified date]:YYYY-MM-DD HH\:MM\:SS' \ @@ -323,27 +312,6 @@ _journal_fields() { _describe 'possible values' _fields } -_hostnamectl_command() { - local -a _hostnamectl_cmds - _hostnamectl_cmds=( - "status:Show current hostname settings" - "set-hostname:Set system hostname" - "set-icon-name:Set icon name for host" - ) - if (( CURRENT == 1 )); then - _describe -t commands 'hostnamectl commands' _hostnamectl_cmds || compadd "$@" - else - local curcontext="$curcontext" - cmd="${${_hostnamectl_cmds[(r)$words[1]:*]%%:*}}" - if (( $#cmd )); then - [[ $cmd == status ]] && msg="no options" || msg="options for $cmd" - _message "$msg" - else - _message "unknown hostnamectl command: $words[1]" - fi - fi -} - _localectl_set-locale() { local -a _confs _locales local expl suf -- cgit v1.2.1 From 7e83c0e03fbf397167822e170d97c3a210658768 Mon Sep 17 00:00:00 2001 From: William Giokas <1007380@gmail.com> Date: Mon, 29 Jul 2013 14:07:21 -0500 Subject: zsh_completion: Split out zsh _journalctl Re-ordered some of the options and added a few that were missing previously as well. --- Makefile.am | 1 + shell-completion/zsh/_journalctl | 83 ++++++++++++++++++++++++++++++++++++++++ shell-completion/zsh/_systemd | 70 +-------------------------------- 3 files changed, 85 insertions(+), 69 deletions(-) create mode 100644 shell-completion/zsh/_journalctl diff --git a/Makefile.am b/Makefile.am index ba4035072c..e331e67285 100644 --- a/Makefile.am +++ b/Makefile.am @@ -345,6 +345,7 @@ dist_bashcompletion_DATA = \ dist_zshcompletion_DATA = \ shell-completion/zsh/_systemctl \ + shell-completion/zsh/_journalctl \ shell-completion/zsh/_systemd dist_sysctl_DATA = \ diff --git a/shell-completion/zsh/_journalctl b/shell-completion/zsh/_journalctl new file mode 100644 index 0000000000..440e35d05b --- /dev/null +++ b/shell-completion/zsh/_journalctl @@ -0,0 +1,83 @@ +#compdef journalctl + +_outputmodes() { + local -a _output_opts + _output_opts=(short short-monotonic verbose export json json-pretty json-see cat) + _describe -t output 'output mode' _output_opts || compadd "$@" +} + +_list_fields() { + local -a journal_fields + journal_fields=(MESSAGE{,_ID} PRIORITY CODE_{FILE,LINE,FUNC} + ERRNO SYSLOG_{FACILITY,IDENTIFIER,PID} + _{P,U,G}ID _COMM _EXE _CMDLINE + _AUDIT_{SESSION,LOGINUID} + _SYSTEMD_{CGROUP,SESSION,UNIT,OWNER_UID} + _SYSTEMD_USER_UNIT + _SELINUX_CONTEXT _SOURCE_REALTIME_TIMESTAMP + _{BOOT,MACHINE}_ID _HOSTNAME _TRANSPORT + _KERNEL_{DEVICE,SUBSYSTEM} + _UDEV_{SYSNAME,DEVNODE,DEVLINK} + __CURSOR __{REALTIME,MONOTONIC}_TIMESTAMP) + _describe 'possible fields' journal_fields +} + +_journal_none() { + local -a _commands _files + _commands=( ${(f)"$(_call_program commands "$service" -F _EXE 2>/dev/null)"} ) + _alternative : \ + 'files:/dev files:_files -W /dev -P /dev/' \ + "commands:commands:($_commands[@])" \ + 'fields:fields:_list_fields' +} + +_journal_fields() { + local -a _fields cmd + cmd=("journalctl" "-F ${@[-1]}" "2>/dev/null" ) + _fields=( ${(f)"$(_call_program fields $cmd[@])"} ) + typeset -U _fields + _describe 'possible values' _fields +} + +_arguments -s \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + '--no-pager[Do not pipe output into a pager]' \ + {-l,--full}'[Show long fields in full]' \ + {-a,--all}'[Show all fields, including long and unprintable]' \ + {-f,--follow}'[Follow journal]' \ + {-e,--pager-end}'[Jump to the end of the journal in the pager]' \ + {-n,--lines=}'[Number of journal entries to show]:integer' \ + '--no-tail[Show all lines, even in follow mode]' \ + {-r,--reverse}'[Reverse output]' \ + {-o,--output=}'[Change journal output mode]:output modes:_outputmodes' \ + {-x,--catalog}'[Show explanatory texts with each log line]' \ + {-q,--quiet}"[Don't show privilege warning]" \ + {-m,--merge}'[Show entries from all available journals]' \ + {-b,--boot}'[Show entries from the specified boot only]' \ + {-k,--dmesg}'[Show only kernel messages, Implies -b]' \ + {-u,--unit=}'[Show data only from the specified unit]:units:_journal_fields _SYSTEMD_UNIT' \ + '--user-unit[Show data only from the specified user session unit]:units:_journal_fields _SYSTEMD_USER_UNIT' \ + {-p,--priority=}'[Show only messages within the specified priority range]:priority:_journal_fields PRIORITY' \ + {-c,--cursor=}'[Start showing entries from specified cursor]:cursors:_journal_fields __CURSORS' \ + '--after-cursor=[Start showing entries from the location in the journal after the cursor]:cursors:_journal_fields __CURSORS' \ + '--since=[Start showing entries newer or of the specified date]:YYYY-MM-DD HH\:MM\:SS' \ + '--until=[Stop showing entries older or of the specified date]:YYYY-MM-DD HH\:MM\:SS' \ + {-F,--field=}'[List all values a certain field takes]:Fields:_list_fields' \ + '--system[Show system and kernel messages]' \ + '--user[Show messages from user services]' \ + {-D,--directory=}'[Show journal files from directory]:directories:_directories' \ + '--file=[Operate on specified journal files]:file:_files' \ + '--root=[Operate on catalog hierarchy under specified directory]:directories:_directories' \ + '--new-id128[Generate a new 128 Bit ID]' \ + '--header[Show journal header information]' \ + '--disk-usage[Show total disk usage]' \ + '--list-catalog[List messages in catalog]' \ + '--dump-catalog[Dump messages in catalog]' \ + '--update-catalog[Update binary catalog database]' \ + '--setup-keys[Generate new FSS key pair]' \ + '--force[Force recreation of FSS keys]' \ + '--interval=[Time interval for changing the FSS sealing key]:time interval' \ + '--verify[Verify journal file consistency]' \ + '--verify-key=[Specify FSS verification key]:FSS key' \ + '*::default: _journal_none' diff --git a/shell-completion/zsh/_systemd b/shell-completion/zsh/_systemd index ce7ea1ad4d..488d460142 100644 --- a/shell-completion/zsh/_systemd +++ b/shell-completion/zsh/_systemd @@ -1,44 +1,9 @@ -#compdef journalctl localectl timedatectl systemd-coredumpctl udevadm systemd-analyze systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-inhibit systemd-machine-id-setup systemd-notify systemd-nspawn systemd-tmpfiles systemd-tty-ask-password-agent machinectl +#compdef localectl timedatectl systemd-coredumpctl udevadm systemd-analyze systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-inhibit systemd-machine-id-setup systemd-notify systemd-nspawn systemd-tmpfiles systemd-tty-ask-password-agent machinectl _ctls() { local curcontext="$curcontext" state lstate line case "$service" in - journalctl) - _arguments -s \ - '--since=[Start showing entries newer or of the specified date]:YYYY-MM-DD HH\:MM\:SS' \ - '--until=[Stop showing entries older or of the specified date]:YYYY-MM-DD HH\:MM\:SS' \ - {-c,--cursor=}'[Start showing entries from specified cursor]:cursors:_journal_fields __CURSORS' \ - '--system[Show system and kernel messages]' \ - '--user[Show messages from user services]' \ - {-b,--this-boot}'[Show data only from current boot]' \ - {-u,--unit=}'[Show data only from the specified unit]:units:_journal_fields _SYSTEMD_UNIT' \ - '--user-unit[Show data only from the specified user session unit]:units:_journal_fields _SYSTEMD_USER_UNIT' \ - {-p,--priority=}'[Show only messages within the specified priority range]:priority:_journal_fields PRIORITY' \ - {-f,--follow}'[Follow journal]' \ - {-n,--lines=}'[Number of journal entries to show]:integer' \ - '--no-tail[Show all lines, even in follow mode]' \ - {-o,--output=}'[Change journal output mode]:output modes:_outputmodes' \ - {-l,--full}'[Show long fields in full]' \ - {-a,--all}'[Show all fields, including long and unprintable]' \ - {-q,--quiet}"[Don't show privilege warning]" \ - '--no-pager[Do not pipe output into a pager]' \ - {-m,--merge}'[Show entries from all available journals]' \ - {-D,--directory=}'[Show journal files from directory]:directories:_directories' \ - '--interval=[Time interval for changing the FSS sealing key]:time interval' \ - '--verify-key=[Specify FSS verification key]:FSS key' \ - {-h,--help}'[Show this help]' \ - '--version[Show package version]' \ - '--new-id128[Generate a new 128 Bit ID]' \ - '--header[Show journal header information]' \ - '--disk-usage[Show total disk usage]' \ - {-F,--field=}'[List all values a certain field takes]:Fields:_list_fields' \ - '--setup-keys[Generate new FSS key pair]' \ - '--verify[Verify journal file consistency]' \ - '--list-catalog[List messages in catalog]' \ - '--update-catalog[Update binary catalog database]' \ - '*::default: _journal_none' - ;; localectl) _arguments \ {-h,--help}'[Show this help]' \ @@ -279,39 +244,6 @@ _outputmodes() { _describe -t output 'output mode' _output_opts || compadd "$@" } -_list_fields() { - local -a journal_fields - journal_fields=(MESSAGE{,_ID} PRIORITY CODE_{FILE,LINE,FUNC} - ERRNO SYSLOG_{FACILITY,IDENTIFIER,PID} - _{P,U,G}ID _COMM _EXE _CMDLINE - _AUDIT_{SESSION,LOGINUID} - _SYSTEMD_{CGROUP,SESSION,UNIT,OWNER_UID} - _SYSTEMD_USER_UNIT - _SELINUX_CONTEXT _SOURCE_REALTIME_TIMESTAMP - _{BOOT,MACHINE}_ID _HOSTNAME _TRANSPORT - _KERNEL_{DEVICE,SUBSYSTEM} - _UDEV_{SYSNAME,DEVNODE,DEVLINK} - __CURSOR __{REALTIME,MONOTONIC}_TIMESTAMP) - _describe 'possible fields' journal_fields -} - -_journal_none() { - local -a _commands _files - _commands=( ${(f)"$(_call_program commands "$service" -F _EXE 2>/dev/null)"} ) - _alternative : \ - 'files:/dev files:_files -W /dev -P /dev/' \ - "commands:commands:($_commands[@])" \ - 'fields:fields:_list_fields' -} - -_journal_fields() { - local -a _fields cmd - cmd=("journalctl" "-F ${@[-1]}" "2>/dev/null" ) - _fields=( ${(f)"$(_call_program fields $cmd[@])"} ) - typeset -U _fields - _describe 'possible values' _fields -} - _localectl_set-locale() { local -a _confs _locales local expl suf -- cgit v1.2.1 From c4c12f133e22af6e3e193f3312e7cad61fa1b881 Mon Sep 17 00:00:00 2001 From: William Giokas <1007380@gmail.com> Date: Mon, 29 Jul 2013 14:08:07 -0500 Subject: zsh_completion: Split out zsh _localectl --- Makefile.am | 3 ++ shell-completion/zsh/_localectl | 89 +++++++++++++++++++++++++++++++++++++++++ shell-completion/zsh/_systemd | 86 +-------------------------------------- 3 files changed, 93 insertions(+), 85 deletions(-) create mode 100644 shell-completion/zsh/_localectl diff --git a/Makefile.am b/Makefile.am index e331e67285..64d4785db3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3443,6 +3443,9 @@ bin_PROGRAMS += \ dist_bashcompletion_DATA += \ shell-completion/bash/localectl +dist_zshcompletion_DATA += \ + shell-completion/zsh/_localectl + endif polkitpolicy_in_files += \ diff --git a/shell-completion/zsh/_localectl b/shell-completion/zsh/_localectl new file mode 100644 index 0000000000..0beed4f5c4 --- /dev/null +++ b/shell-completion/zsh/_localectl @@ -0,0 +1,89 @@ +#compdef localectl + +_localectl_set-locale() { + local -a _confs _locales + local expl suf + _locales=( ${(f)"$(_call_program locales "$service" list-locales)"} ) + _confs=( ${${(f)"$(_call_program confs "locale 2>/dev/null")"}%\=*} ) + if [[ -prefix 1 *\= ]]; then + local conf=${PREFIX%%\=*} + compset -P1 '*=' + _wanted locales expl "locales configs" \ + _combination localeconfs confs=$conf locales "$@" - + else + compadd -S '=' $_confs + fi +} + +_localectl_set-keymap() { + local -a _keymaps + _keymaps=( ${(f)"$(_call_program locales "$service" list-keymaps)"} ) + if (( CURRENT <= 3 )); then + _describe keymaps _keymaps + else + _message "no more options" + fi +} + +_localectl_set-x11-keymap() { + if (( $+commands[pkg-config] )); then + local -a _file _layout _model _variant _options + local _xorg_lst + _xorg_lst=${"$($commands[pkg-config] xkeyboard-config --variable=xkb_base)"} + _file=( ${(ps:\n\!:)"$(<$_xorg_lst/rules/xorg.lst)"} ) + _layout=( ${${${(M)${(f)_file[1]}:# *}# }%% *} ) + _model=( ${${${(M)${(f)_file[2]}:# *}# }%% *} ) + _variant=( ${${${(M)${(f)_file[3]}:# *}# }%% *} ) + _options=( ${${${(M)${(f)_file[4]}:# *}# }%% *} ) + #_layout=( ${(f)"$( echo $_file[1] | awk '/^ / {print $1}' )"} ) + #_model=( ${(f)"$(echo $_file[2] | awk '/^ / {print $1}')"} ) + #_variant=( ${(f)"$(echo $_file[3] | awk '/^ / {print $1}')"} ) + #_options=( ${(f)"$(echo ${_file[4]//:/\\:} | awk '/^ / {print $1}')"} ) + + case $CURRENT in + 2) _describe layouts _layout ;; + 3) _describe models _model;; + 4) _describe variants _variant;; + 5) _describe options _options;; + *) _message "no more options" + esac + fi +} + +_localectl_command() { + local -a _localectl_cmds + _localectl_cmds=( + 'status:Show current locale settings' + 'set-locale:Set system locale' + 'list-locales:Show known locales' + 'set-keymap:Set virtual console keyboard mapping' + 'list-keymaps:Show known virtual console keyboard mappings' + 'set-x11-keymap:Set X11 keyboard mapping' + ) + if (( CURRENT == 1 )); then + _describe -t commands 'localectl command' _localectl_cmds + else + local curcontext="$curcontext" + cmd="${${_localectl_cmds[(r)$words[1]:*]%%:*}}" + if (( $+functions[_localectl_$cmd] )); then + _localectl_$cmd + else + _message "no more options" + fi + fi +} + +_hosts_or_user_at_host() { + _alternative \ + 'users-hosts:: _user_at_host' \ + 'hosts:: _hosts' +} + +_arguments \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + "--no-convert[Don't convert keyboard mappings]" \ + '--no-pager[Do not pipe output into a pager]' \ + '--no-ask-password[Do not prompt for password]' \ + {-H,--host=}'[Operate on remote host]:userathost:_hosts_or_user_at_host' \ + '*::localectl commands:_localectl_command' diff --git a/shell-completion/zsh/_systemd b/shell-completion/zsh/_systemd index 488d460142..70746efeb8 100644 --- a/shell-completion/zsh/_systemd +++ b/shell-completion/zsh/_systemd @@ -1,19 +1,9 @@ -#compdef localectl timedatectl systemd-coredumpctl udevadm systemd-analyze systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-inhibit systemd-machine-id-setup systemd-notify systemd-nspawn systemd-tmpfiles systemd-tty-ask-password-agent machinectl +#compdef timedatectl systemd-coredumpctl udevadm systemd-analyze systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-inhibit systemd-machine-id-setup systemd-notify systemd-nspawn systemd-tmpfiles systemd-tty-ask-password-agent machinectl _ctls() { local curcontext="$curcontext" state lstate line case "$service" in - localectl) - _arguments \ - {-h,--help}'[Show this help]' \ - '--version[Show package version]' \ - "--no-convert[Don't convert keyboard mappings]" \ - '--no-pager[Do not pipe output into a pager]' \ - '--no-ask-password[Do not prompt for password]' \ - {-H,--host=}'[Operate on remote host]:userathost:_hosts_or_user_at_host' \ - '*::localectl commands:_localectl_command' - ;; systemd-coredumpctl) _arguments \ {-o,--output=}'[Write output to FILE]:output file:_files' \ @@ -244,80 +234,6 @@ _outputmodes() { _describe -t output 'output mode' _output_opts || compadd "$@" } -_localectl_set-locale() { - local -a _confs _locales - local expl suf - _locales=( ${(f)"$(_call_program locales "$service" list-locales)"} ) - _confs=( ${${(f)"$(_call_program confs "locale 2>/dev/null")"}%\=*} ) - if [[ -prefix 1 *\= ]]; then - local conf=${PREFIX%%\=*} - compset -P1 '*=' - _wanted locales expl "locales configs" \ - _combination localeconfs confs=$conf locales "$@" - - else - compadd -S '=' $_confs - fi -} - -_localectl_set-keymap() { - local -a _keymaps - _keymaps=( ${(f)"$(_call_program locales "$service" list-keymaps)"} ) - if (( CURRENT <= 3 )); then - _describe keymaps _keymaps - else - _message "no more options" - fi -} - -_localectl_set-x11-keymap() { - if (( $+commands[pkg-config] )); then - local -a _file _layout _model _variant _options - local _xorg_lst - _xorg_lst=${"$($commands[pkg-config] xkeyboard-config --variable=xkb_base)"} - _file=( ${(ps:\n\!:)"$(<$_xorg_lst/rules/xorg.lst)"} ) - _layout=( ${${${(M)${(f)_file[1]}:# *}# }%% *} ) - _model=( ${${${(M)${(f)_file[2]}:# *}# }%% *} ) - _variant=( ${${${(M)${(f)_file[3]}:# *}# }%% *} ) - _options=( ${${${(M)${(f)_file[4]}:# *}# }%% *} ) - #_layout=( ${(f)"$( echo $_file[1] | awk '/^ / {print $1}' )"} ) - #_model=( ${(f)"$(echo $_file[2] | awk '/^ / {print $1}')"} ) - #_variant=( ${(f)"$(echo $_file[3] | awk '/^ / {print $1}')"} ) - #_options=( ${(f)"$(echo ${_file[4]//:/\\:} | awk '/^ / {print $1}')"} ) - - case $CURRENT in - 2) _describe layouts _layout ;; - 3) _describe models _model;; - 4) _describe variants _variant;; - 5) _describe options _options;; - *) _message "no more options" - esac - fi -} - - -_localectl_command() { - local -a _localectl_cmds - _localectl_cmds=( - 'status:Show current locale settings' - 'set-locale:Set system locale' - 'list-locales:Show known locales' - 'set-keymap:Set virtual console keyboard mapping' - 'list-keymaps:Show known virtual console keyboard mappings' - 'set-x11-keymap:Set X11 keyboard mapping' - ) - if (( CURRENT == 1 )); then - _describe -t commands 'localectl command' _localectl_cmds - else - local curcontext="$curcontext" - cmd="${${_localectl_cmds[(r)$words[1]:*]%%:*}}" - if (( $+functions[_localectl_$cmd] )); then - _localectl_$cmd - else - _message "no more options" - fi - fi -} - _timedatectl_set-timezone(){ local -a _timezones _timezones=( ${(f)"$(_call_program timezones "${service}" list-timezones)"} ) -- cgit v1.2.1 From 70e104c4e39d47b3b2a82654bbf1a559b57a9c68 Mon Sep 17 00:00:00 2001 From: William Giokas <1007380@gmail.com> Date: Mon, 29 Jul 2013 14:09:10 -0500 Subject: zsh_completion: Split out zsh _coredumpctl --- Makefile.am | 3 +++ shell-completion/zsh/_systemd | 38 +------------------------------ shell-completion/zsh/_systemd-coredumpctl | 34 +++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 37 deletions(-) create mode 100644 shell-completion/zsh/_systemd-coredumpctl diff --git a/Makefile.am b/Makefile.am index 64d4785db3..cf764cd68e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3104,6 +3104,9 @@ bin_PROGRAMS += \ dist_bashcompletion_DATA += \ shell-completion/bash/systemd-coredumpctl +dist_zshcompletion_DATA += \ + shell-completion/zsh/_systemd-coredumpctl + sysctl_DATA = \ sysctl.d/50-coredump.conf diff --git a/shell-completion/zsh/_systemd b/shell-completion/zsh/_systemd index 70746efeb8..1d0f840e60 100644 --- a/shell-completion/zsh/_systemd +++ b/shell-completion/zsh/_systemd @@ -1,18 +1,9 @@ -#compdef timedatectl systemd-coredumpctl udevadm systemd-analyze systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-inhibit systemd-machine-id-setup systemd-notify systemd-nspawn systemd-tmpfiles systemd-tty-ask-password-agent machinectl +#compdef timedatectl udevadm systemd-analyze systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-inhibit systemd-machine-id-setup systemd-notify systemd-nspawn systemd-tmpfiles systemd-tty-ask-password-agent machinectl _ctls() { local curcontext="$curcontext" state lstate line case "$service" in - systemd-coredumpctl) - _arguments \ - {-o,--output=}'[Write output to FILE]:output file:_files' \ - '--no-pager[Do not pipe output into a pager]' \ - {-h,--help}'[Show this help]' \ - '--version[Show package version]' \ - '*::systemd-coredumpctl commands:_systemd-coredumpctl_command' - - ;; timedatectl) _arguments -s \ {-h,--help}'[Show this help]' \ @@ -288,33 +279,6 @@ _timedatectl_command(){ fi fi } -_systemd-coredumpctl_command(){ - local -a _systemd_coredumpctl_cmds - _systemd_coredumpctl_cmds=( - 'list:List available coredumps' - 'dump:Print coredump to std' - ) - if (( CURRENT == 1 )); then - _describe -t commands 'systemd-coredumpctl command' _systemd_coredumpctl_cmds - else - local curcontext="$curcontext" - local -a _dumps - cmd="${${_systemd_coredumpctl_cmds[(r)$words[1]:*]%%:*}}" - if (( $#cmd )); then - # user can set zstyle ':completion:*:*:systemd-coredumpctl:*' sort no for coredumps to be ordered by date, otherwise they get ordered by pid - _dumps=( "${(foa)$(systemd-coredumpctl list | awk 'BEGIN{OFS=":"} /^\s/ {sub(/[[ \t]+/, ""); print $5,$0}' 2>/dev/null)}" ) - if [[ -n "$_dumps" ]]; then - _describe -t pids 'coredumps' _dumps - else - _message "no coredumps" - fi - else - _message "no more options" - fi - - fi - -} (( $+functions[_machinectl_command] )) || _machinectl_command() { diff --git a/shell-completion/zsh/_systemd-coredumpctl b/shell-completion/zsh/_systemd-coredumpctl new file mode 100644 index 0000000000..f5d12cbcd1 --- /dev/null +++ b/shell-completion/zsh/_systemd-coredumpctl @@ -0,0 +1,34 @@ +#compdef systemd-coredumpctl + +_systemd-coredumpctl_command(){ + local -a _systemd_coredumpctl_cmds + _systemd_coredumpctl_cmds=( + 'list:List available coredumps' + 'dump:Print coredump to std' + ) + if (( CURRENT == 1 )); then + _describe -t commands 'systemd-coredumpctl command' _systemd_coredumpctl_cmds + else + local curcontext="$curcontext" + local -a _dumps + cmd="${${_systemd_coredumpctl_cmds[(r)$words[1]:*]%%:*}}" + if (( $#cmd )); then + # user can set zstyle ':completion:*:*:systemd-coredumpctl:*' sort no for coredumps to be ordered by date, otherwise they get ordered by pid + _dumps=( "${(foa)$(systemd-coredumpctl list | awk 'BEGIN{OFS=":"} /^\s/ {sub(/[[ \t]+/, ""); print $5,$0}' 2>/dev/null)}" ) + if [[ -n "$_dumps" ]]; then + _describe -t pids 'coredumps' _dumps + else + _message "no coredumps" + fi + else + _message "no more options" + fi + fi +} + +_arguments \ + {-o,--output=}'[Write output to FILE]:output file:_files' \ + '--no-pager[Do not pipe output into a pager]' \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + '*::systemd-coredumpctl commands:_systemd-coredumpctl_command' -- cgit v1.2.1 From 20c8382ba7c65be3aa2d141501cc934262f776ba Mon Sep 17 00:00:00 2001 From: William Giokas <1007380@gmail.com> Date: Mon, 29 Jul 2013 14:09:48 -0500 Subject: zsh_completion: Split out zsh _timedatectl --- Makefile.am | 3 ++ shell-completion/zsh/_systemd | 67 +----------------------------------- shell-completion/zsh/_timedatectl | 71 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 66 deletions(-) create mode 100644 shell-completion/zsh/_timedatectl diff --git a/Makefile.am b/Makefile.am index cf764cd68e..cdf5c4660d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3518,6 +3518,9 @@ bin_PROGRAMS += \ dist_bashcompletion_DATA += \ shell-completion/bash/timedatectl + +dist_zshcompletion_DATA += \ + shell-completion/zsh/_timedatectl endif polkitpolicy_in_files += \ diff --git a/shell-completion/zsh/_systemd b/shell-completion/zsh/_systemd index 1d0f840e60..7e23d78326 100644 --- a/shell-completion/zsh/_systemd +++ b/shell-completion/zsh/_systemd @@ -1,19 +1,9 @@ -#compdef timedatectl udevadm systemd-analyze systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-inhibit systemd-machine-id-setup systemd-notify systemd-nspawn systemd-tmpfiles systemd-tty-ask-password-agent machinectl +#compdef udevadm systemd-analyze systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-inhibit systemd-machine-id-setup systemd-notify systemd-nspawn systemd-tmpfiles systemd-tty-ask-password-agent machinectl _ctls() { local curcontext="$curcontext" state lstate line case "$service" in - timedatectl) - _arguments -s \ - {-h,--help}'[Show this help]' \ - '--version[Show package version]' \ - '--adjust-system-clock[Adjust system clock when changing local RTC mode]' \ - '--no-pager[Do not pipe output into a pager]' \ - '--no-ask-password[Do not prompt for password]' \ - {-H,--host=}'[Operate on remote host]:userathost:_hosts_or_user_at_host' \ - '*::timedatectl commands:_timedatectl_command' - ;; udevadm) _arguments \ '--debug[Print debug messages to stderr]' \ @@ -225,61 +215,6 @@ _outputmodes() { _describe -t output 'output mode' _output_opts || compadd "$@" } -_timedatectl_set-timezone(){ - local -a _timezones - _timezones=( ${(f)"$(_call_program timezones "${service}" list-timezones)"} ) - compadd "$_timezones[@]" -} - -_timedatectl_set-time(){ - _message "YYYY-MM-DD HH:MM:SS" -} - -_timedatectl_set-local-rtc(){ - local -a _options - _options=( - '0:Maintain RTC in universal time' - '1:Maintain RTC in local time' - ) - _describe options _options -} - -_timedatectl_set-ntp(){ - local -a _options - _options=( - '0:Disable NTP based network time configuration' - '1:Enable NTP based network time configuration' - ) - _describe options _options -} - -_timedatectl_command(){ - local -a _timedatectl_cmds - _timedatectl_cmds=( - 'status:Show current time settings' - 'set-time:Set system time' - 'set-timezone:Set system timezone' - 'list-timezones:Show known timezones' - 'set-local-rtc:Control whether RTC is in local time' - 'set-ntp:Control whether NTP is enabled' - ) - if (( CURRENT == 1 )); then - _describe -t commands 'timedatectl command' _timedatectl_cmds - else - local curcontext="$curcontext" - cmd="${${_timedatectl_cmds[(r)$words[1]:*]%%:*}}" - if (( $#cmd )); then - if (( $+functions[_timedatectl_$cmd] )); then - _timedatectl_$cmd - else - _message "no more options" - fi - else - _message "unknown timedatectl command: $words[1]" - fi - fi -} - (( $+functions[_machinectl_command] )) || _machinectl_command() { local -a _machinectl_cmds diff --git a/shell-completion/zsh/_timedatectl b/shell-completion/zsh/_timedatectl new file mode 100644 index 0000000000..091b6f10ce --- /dev/null +++ b/shell-completion/zsh/_timedatectl @@ -0,0 +1,71 @@ +#compdef timedatectl + +_timedatectl_set-timezone(){ + local -a _timezones + _timezones=( ${(f)"$(_call_program timezones "${service}" list-timezones)"} ) + compadd "$_timezones[@]" +} + +_timedatectl_set-time(){ + _message "YYYY-MM-DD HH:MM:SS" +} + +_timedatectl_set-local-rtc(){ + local -a _options + _options=( + '0:Maintain RTC in universal time' + '1:Maintain RTC in local time' + ) + _describe options _options +} + +_timedatectl_set-ntp(){ + local -a _options + _options=( + '0:Disable NTP based network time configuration' + '1:Enable NTP based network time configuration' + ) + _describe options _options +} + +_timedatectl_command(){ + local -a _timedatectl_cmds + _timedatectl_cmds=( + 'status:Show current time settings' + 'set-time:Set system time' + 'set-timezone:Set system timezone' + 'list-timezones:Show known timezones' + 'set-local-rtc:Control whether RTC is in local time' + 'set-ntp:Control whether NTP is enabled' + ) + if (( CURRENT == 1 )); then + _describe -t commands 'timedatectl command' _timedatectl_cmds + else + local curcontext="$curcontext" + cmd="${${_timedatectl_cmds[(r)$words[1]:*]%%:*}}" + if (( $#cmd )); then + if (( $+functions[_timedatectl_$cmd] )); then + _timedatectl_$cmd + else + _message "no more options" + fi + else + _message "unknown timedatectl command: $words[1]" + fi + fi +} + +_hosts_or_user_at_host() { + _alternative \ + 'users-hosts:: _user_at_host' \ + 'hosts:: _hosts' +} + +_arguments -s \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + '--adjust-system-clock[Adjust system clock when changing local RTC mode]' \ + '--no-pager[Do not pipe output into a pager]' \ + '--no-ask-password[Do not prompt for password]' \ + {-H,--host=}'[Operate on remote host]:userathost:_hosts_or_user_at_host' \ + '*::timedatectl commands:_timedatectl_command' -- cgit v1.2.1 From a06225fcc168cc3e62edc7efcb42d94cf68f159a Mon Sep 17 00:00:00 2001 From: William Giokas <1007380@gmail.com> Date: Mon, 29 Jul 2013 14:10:39 -0500 Subject: zsh_completion: Split out zsh _udevadm --- Makefile.am | 1 + shell-completion/zsh/_systemd | 142 +----------------------------------------- shell-completion/zsh/_udevadm | 141 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 143 insertions(+), 141 deletions(-) create mode 100644 shell-completion/zsh/_udevadm diff --git a/Makefile.am b/Makefile.am index cdf5c4660d..c96c8b1b73 100644 --- a/Makefile.am +++ b/Makefile.am @@ -346,6 +346,7 @@ dist_bashcompletion_DATA = \ dist_zshcompletion_DATA = \ shell-completion/zsh/_systemctl \ shell-completion/zsh/_journalctl \ + shell-completion/zsh/_udevadm \ shell-completion/zsh/_systemd dist_sysctl_DATA = \ diff --git a/shell-completion/zsh/_systemd b/shell-completion/zsh/_systemd index 7e23d78326..78cb061181 100644 --- a/shell-completion/zsh/_systemd +++ b/shell-completion/zsh/_systemd @@ -1,16 +1,9 @@ -#compdef udevadm systemd-analyze systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-inhibit systemd-machine-id-setup systemd-notify systemd-nspawn systemd-tmpfiles systemd-tty-ask-password-agent machinectl +#compdef systemd-analyze systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-inhibit systemd-machine-id-setup systemd-notify systemd-nspawn systemd-tmpfiles systemd-tty-ask-password-agent machinectl _ctls() { local curcontext="$curcontext" state lstate line case "$service" in - udevadm) - _arguments \ - '--debug[Print debug messages to stderr]' \ - '--version[Print version number]' \ - '--help[Print help text]' \ - '*::udevadm commands:_udevadm_command' - ;; systemd-analyze) _arguments \ {-h,--help}'[Show help text.]' \ @@ -247,139 +240,6 @@ _outputmodes() { fi } -_udevadm_info(){ - _arguments \ - '--query=[Query the database for specified type of device data. It needs the --path or --name to identify the specified device.]:type:(name symlink path property all)' \ - '--path=[The devpath of the device to query.]:sys files:_files -P /sys/ -W /sys' \ - '--name=[The name of the device node or a symlink to query]:device files:_files -P /dev/ -W /dev' \ - '--root[Print absolute paths in name or symlink query.]' \ - '--attribute-walk[Print all sysfs properties of the specified device that can be used in udev rules to match the specified device]' \ - '--export[Print output as key/value pairs.]' \ - '--export-prefix=[Add a prefix to the key name of exported values.]:prefix' \ - '--device-id-of-file=[Print major/minor numbers of the underlying device, where the file lives on.]:files:_udevadm_mounts' \ - '--export-db[Export the content of the udev database.]' \ - '--cleanup-db[Cleanup the udev database.]' -} - -_udevadm_trigger(){ - _arguments \ - '--verbose[Print the list of devices which will be triggered.]' \ - '--dry-run[Do not actually trigger the event.]' \ - '--type=[Trigger a specific type of devices.]:types:(devices subsystems failed)' \ - '--action=[Type of event to be triggered.]:actions:(add change remove)' \ - '--subsystem-match=[Trigger events for devices which belong to a matching subsystem.]' \ - '--subsystem-nomatch=[Do not trigger events for devices which belong to a matching subsystem.]' \ - '--attr-match=attribute=[Trigger events for devices with a matching sysfs attribute.]' \ - '--attr-nomatch=attribute=[Do not trigger events for devices with a matching sysfs attribute.]' \ - '--property-match=[Trigger events for devices with a matching property value.]' \ - '--tag-match=property[Trigger events for devices with a matching tag.]' \ - '--sysname-match=[Trigger events for devices with a matching sys device name.]' \ - '--parent-match=[Trigger events for all children of a given device.]' -} - -_udevadm_settle(){ - _arguments \ - '--timeout=[Maximum number of seconds to wait for the event queue to become empty.]' \ - '--seq-start=[Wait only for events after the given sequence number.]' \ - '--seq-end=[Wait only for events before the given sequence number.]' \ - '--exit-if-exists=[Stop waiting if file exists.]:files:_files' \ - '--quiet[Do not print any output, like the remaining queue entries when reaching the timeout.]' \ - '--help[Print help text.]' -} - -_udevadm_control(){ - _arguments \ - '--exit[Signal and wait for systemd-udevd to exit.]' \ - '--log-priority=[Set the internal log level of systemd-udevd.]:priorities:(err info debug)' \ - '--stop-exec-queue[Signal systemd-udevd to stop executing new events. Incoming events will be queued.]' \ - '--start-exec-queue[Signal systemd-udevd to enable the execution of events.]' \ - '--reload[Signal systemd-udevd to reload the rules files and other databases like the kernel module index.]' \ - '--property=[Set a global property for all events.]' \ - '--children-max=[Set the maximum number of events.]' \ - '--timeout=[The maximum number of seconds to wait for a reply from systemd-udevd.]' \ - '--help[Print help text.]' -} - -_udevadm_monitor(){ - _arguments \ - '--kernel[Print the kernel uevents.]' \ - '--udev[Print the udev event after the rule processing.]' \ - '--property[Also print the properties of the event.]' \ - '--subsystem-match=[Filter events by subsystem/\[devtype\].]' \ - '--tag-match=[Filter events by property.]' \ - '--help[Print help text.]' -} - -_udevadm_test(){ - _arguments \ - '--action=[The action string.]:actions:(add change remove)' \ - '--subsystem=[The subsystem string.]' \ - '--help[Print help text.]' \ - '*::devpath:_files -P /sys/ -W /sys' -} - -_udevadm_test-builtin(){ - if (( CURRENT == 2 )); then - _arguments \ - '--help[Print help text]' \ - '*::builtins:(blkid btrfs hwdb input_id kmod path_id usb_id uaccess)' - elif (( CURRENT == 3 )); then - _arguments \ - '--help[Print help text]' \ - '*::syspath:_files -P /sys -W /sys' - else - _arguments \ - '--help[Print help text]' - fi -} - -_udevadm_mounts(){ - local dev_tmp dpath_tmp mp_tmp mline - - tmp=( "${(@f)$(< /etc/mtab)}" ) - dev_tmp=( "${(@)${(@)tmp%% *}:#none}" ) - mp_tmp=( "${(@)${(@)tmp#* }%% *}" ) - - local MATCH - mp_tmp=("${(@q)mp_tmp//(#m)\\[0-7](#c3)/${(#)$(( 8#${MATCH[2,-1]} ))}}") - dpath_tmp=( "${(@Mq)dev_tmp:#/*}" ) - dev_tmp=( "${(@q)dev_tmp:#/*}" ) - - _alternative \ - 'device-paths: device path:compadd -a dpath_tmp' \ - 'directories:mount point:compadd -a mp_tmp' -} - - -_udevadm_command(){ - local -a _udevadm_cmds - _udevadm_cmds=( - 'info:query sysfs or the udev database' - 'trigger:request events from the kernel' - 'settle:wait for the event queue to finish' - 'control:control the udev daemon' - 'monitor:listen to kernel and udev events' - 'test:test an event run' - 'test-builtin:test a built-in command' - ) - - if ((CURRENT == 1)); then - _describe -t commands 'udevadm commands' _udevadm_cmds - else - local curcontext="$curcontext" - cmd="${${_udevadm_cmds[(r)$words[1]:*]%%:*}}" - if (($#cmd)); then - if (( $+functions[_udevadm_$cmd] )); then - _udevadm_$cmd - else - _message "no options for $cmd" - fi - else - _message "no more options" - fi - fi -} - _ctls "$@" #vim: set ft=zsh sw=4 ts=4 et diff --git a/shell-completion/zsh/_udevadm b/shell-completion/zsh/_udevadm new file mode 100644 index 0000000000..04e9f8dd8e --- /dev/null +++ b/shell-completion/zsh/_udevadm @@ -0,0 +1,141 @@ +#compdef udevadm + +_udevadm_info(){ + _arguments \ + '--query=[Query the database for specified type of device data. It needs the --path or --name to identify the specified device.]:type:(name symlink path property all)' \ + '--path=[The devpath of the device to query.]:sys files:_files -P /sys/ -W /sys' \ + '--name=[The name of the device node or a symlink to query]:device files:_files -P /dev/ -W /dev' \ + '--root[Print absolute paths in name or symlink query.]' \ + '--attribute-walk[Print all sysfs properties of the specified device that can be used in udev rules to match the specified device]' \ + '--export[Print output as key/value pairs.]' \ + '--export-prefix=[Add a prefix to the key name of exported values.]:prefix' \ + '--device-id-of-file=[Print major/minor numbers of the underlying device, where the file lives on.]:files:_udevadm_mounts' \ + '--export-db[Export the content of the udev database.]' \ + '--cleanup-db[Cleanup the udev database.]' +} + +_udevadm_trigger(){ + _arguments \ + '--verbose[Print the list of devices which will be triggered.]' \ + '--dry-run[Do not actually trigger the event.]' \ + '--type=[Trigger a specific type of devices.]:types:(devices subsystems failed)' \ + '--action=[Type of event to be triggered.]:actions:(add change remove)' \ + '--subsystem-match=[Trigger events for devices which belong to a matching subsystem.]' \ + '--subsystem-nomatch=[Do not trigger events for devices which belong to a matching subsystem.]' \ + '--attr-match=attribute=[Trigger events for devices with a matching sysfs attribute.]' \ + '--attr-nomatch=attribute=[Do not trigger events for devices with a matching sysfs attribute.]' \ + '--property-match=[Trigger events for devices with a matching property value.]' \ + '--tag-match=property[Trigger events for devices with a matching tag.]' \ + '--sysname-match=[Trigger events for devices with a matching sys device name.]' \ + '--parent-match=[Trigger events for all children of a given device.]' +} + +_udevadm_settle(){ + _arguments \ + '--timeout=[Maximum number of seconds to wait for the event queue to become empty.]' \ + '--seq-start=[Wait only for events after the given sequence number.]' \ + '--seq-end=[Wait only for events before the given sequence number.]' \ + '--exit-if-exists=[Stop waiting if file exists.]:files:_files' \ + '--quiet[Do not print any output, like the remaining queue entries when reaching the timeout.]' \ + '--help[Print help text.]' +} + +_udevadm_control(){ + _arguments \ + '--exit[Signal and wait for systemd-udevd to exit.]' \ + '--log-priority=[Set the internal log level of systemd-udevd.]:priorities:(err info debug)' \ + '--stop-exec-queue[Signal systemd-udevd to stop executing new events. Incoming events will be queued.]' \ + '--start-exec-queue[Signal systemd-udevd to enable the execution of events.]' \ + '--reload[Signal systemd-udevd to reload the rules files and other databases like the kernel module index.]' \ + '--property=[Set a global property for all events.]' \ + '--children-max=[Set the maximum number of events.]' \ + '--timeout=[The maximum number of seconds to wait for a reply from systemd-udevd.]' \ + '--help[Print help text.]' +} + +_udevadm_monitor(){ + _arguments \ + '--kernel[Print the kernel uevents.]' \ + '--udev[Print the udev event after the rule processing.]' \ + '--property[Also print the properties of the event.]' \ + '--subsystem-match=[Filter events by subsystem/\[devtype\].]' \ + '--tag-match=[Filter events by property.]' \ + '--help[Print help text.]' +} + +_udevadm_test(){ + _arguments \ + '--action=[The action string.]:actions:(add change remove)' \ + '--subsystem=[The subsystem string.]' \ + '--help[Print help text.]' \ + '*::devpath:_files -P /sys/ -W /sys' +} + +_udevadm_test-builtin(){ + if (( CURRENT == 2 )); then + _arguments \ + '--help[Print help text]' \ + '*::builtins:(blkid btrfs hwdb input_id kmod path_id usb_id uaccess)' + elif (( CURRENT == 3 )); then + _arguments \ + '--help[Print help text]' \ + '*::syspath:_files -P /sys -W /sys' + else + _arguments \ + '--help[Print help text]' + fi +} + +_udevadm_mounts(){ + local dev_tmp dpath_tmp mp_tmp mline + + tmp=( "${(@f)$(< /etc/mtab)}" ) + dev_tmp=( "${(@)${(@)tmp%% *}:#none}" ) + mp_tmp=( "${(@)${(@)tmp#* }%% *}" ) + + local MATCH + mp_tmp=("${(@q)mp_tmp//(#m)\\[0-7](#c3)/${(#)$(( 8#${MATCH[2,-1]} ))}}") + dpath_tmp=( "${(@Mq)dev_tmp:#/*}" ) + dev_tmp=( "${(@q)dev_tmp:#/*}" ) + + _alternative \ + 'device-paths: device path:compadd -a dpath_tmp' \ + 'directories:mount point:compadd -a mp_tmp' +} + + +_udevadm_command(){ + local -a _udevadm_cmds + _udevadm_cmds=( + 'info:query sysfs or the udev database' + 'trigger:request events from the kernel' + 'settle:wait for the event queue to finish' + 'control:control the udev daemon' + 'monitor:listen to kernel and udev events' + 'test:test an event run' + 'test-builtin:test a built-in command' + ) + + if ((CURRENT == 1)); then + _describe -t commands 'udevadm commands' _udevadm_cmds + else + local curcontext="$curcontext" + cmd="${${_udevadm_cmds[(r)$words[1]:*]%%:*}}" + if (($#cmd)); then + if (( $+functions[_udevadm_$cmd] )); then + _udevadm_$cmd + else + _message "no options for $cmd" + fi + else + _message "no more options" + fi + fi +} + + +_arguments \ + '--debug[Print debug messages to stderr]' \ + '--version[Print version number]' \ + '--help[Print help text]' \ + '*::udevadm commands:_udevadm_command' -- cgit v1.2.1 From 30fd4d1eb13a200ebcc852d3ce28f3cb30197957 Mon Sep 17 00:00:00 2001 From: William Giokas <1007380@gmail.com> Date: Wed, 31 Jul 2013 17:11:17 -0500 Subject: zsh_completion: Split out zsh _systemd-nspawn Also fix the random lack of completion --- Makefile.am | 1 + shell-completion/zsh/_systemd | 26 +------------------------- shell-completion/zsh/_systemd-nspawn | 24 ++++++++++++++++++++++++ 3 files changed, 26 insertions(+), 25 deletions(-) create mode 100644 shell-completion/zsh/_systemd-nspawn diff --git a/Makefile.am b/Makefile.am index c96c8b1b73..24e4fa4bd3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -347,6 +347,7 @@ dist_zshcompletion_DATA = \ shell-completion/zsh/_systemctl \ shell-completion/zsh/_journalctl \ shell-completion/zsh/_udevadm \ + shell-completion/zsh/_systemd-nspawn \ shell-completion/zsh/_systemd dist_sysctl_DATA = \ diff --git a/shell-completion/zsh/_systemd b/shell-completion/zsh/_systemd index 78cb061181..bacf1795b9 100644 --- a/shell-completion/zsh/_systemd +++ b/shell-completion/zsh/_systemd @@ -1,4 +1,4 @@ -#compdef systemd-analyze systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-inhibit systemd-machine-id-setup systemd-notify systemd-nspawn systemd-tmpfiles systemd-tty-ask-password-agent machinectl +#compdef systemd-analyze systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-inhibit systemd-machine-id-setup systemd-notify systemd-tmpfiles systemd-tty-ask-password-agent machinectl _ctls() { @@ -96,20 +96,6 @@ _ctls() '--booted[Returns 0 if the system was booted up with systemd]' \ '--readahead=[Controls disk read-ahead operations]:arguments:(cancel done noreply)' ;; - systemd-nspawn) - _arguments \ - {-h,--help}'[Show this help]' \ - {--directory=,-D}'[Directory to use as file system root for the namespace container. If omitted the current directory will be used.]:directories:_directories' \ - {--boot,-b}'[Automatically search for an init binary and invoke it instead of a shell or a user supplied program.]' \ - {--user=,-u}'[Run the command under specified user, create home directory and cd into it.]' \ - '--uuid=[Set the specified uuid for the container.]' \ - {--controllers=,-C}'[Makes the container appear in other hierarchies than the name=systemd:/ one. Takes a comma-separated list of controllers.]' \ - '--private-network[Turn off networking in the container. This makes all network interfaces unavailable in the container, with the exception of the loopback device.]' \ - '--read-only[Mount the root file system read only for the container.]' \ - '--capability=[List one or more additional capabilities to grant the container.]:capabilities:_systemd-nspawn' \ - "--link-journal=[Control whether the container's journal shall be made visible to the host system.]:options:(no, host, guest, auto)" \ - '-j[Equivalent to --link-journal=guest.]' - ;; systemd-tmpfiles) _arguments \ '--create[Create, set ownership/permissions based on the config files.]' \ @@ -150,16 +136,6 @@ _ctls() esac } -_systemd-nspawn(){ - local -a _caps - _caps=( CAP_CHOWN CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH - CAP_FOWNER CAP_FSETID CAP_IPC_OWNER CAP_KILL CAP_LEASE CAP_LINUX_IMMUTABLE - CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET_RAW CAP_SETGID CAP_SETFCAP CAP_SETPCAP - CAP_SETUID CAP_SYS_ADMIN CAP_SYS_CHROOT CAP_SYS_NICE CAP_SYS_PTRACE CAP_SYS_TTY_CONFIG - CAP_SYS_RESOURCE CAP_SYS_BOOT ) - _values -s , 'capabilities' "$_caps[@]" -} - _systemd_inhibit_command(){ if (( CURRENT == 1 )); then compset -q diff --git a/shell-completion/zsh/_systemd-nspawn b/shell-completion/zsh/_systemd-nspawn new file mode 100644 index 0000000000..a5f345ea2c --- /dev/null +++ b/shell-completion/zsh/_systemd-nspawn @@ -0,0 +1,24 @@ +#compdef systemd-nspawn + +_nspawn-caps(){ + local -a _caps + _caps=( CAP_CHOWN CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH + CAP_FOWNER CAP_FSETID CAP_IPC_OWNER CAP_KILL CAP_LEASE CAP_LINUX_IMMUTABLE + CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET_RAW CAP_SETGID CAP_SETFCAP CAP_SETPCAP + CAP_SETUID CAP_SYS_ADMIN CAP_SYS_CHROOT CAP_SYS_NICE CAP_SYS_PTRACE CAP_SYS_TTY_CONFIG + CAP_SYS_RESOURCE CAP_SYS_BOOT ) + _values -s , 'capabilities' "$_caps[@]" +} + +_arguments \ + {-h,--help}'[Show this help]' \ + {--directory=,-D}'[Directory to use as file system root for the namespace container. If omitted the current directory will be used.]:directories:_directories' \ + {--boot,-b}'[Automatically search for an init binary and invoke it instead of a shell or a user supplied program.]' \ + {--user=,-u}'[Run the command under specified user, create home directory and cd into it.]' \ + '--uuid=[Set the specified uuid for the container.]' \ + {--controllers=,-C}'[Makes the container appear in other hierarchies than the name=systemd:/ one. Takes a comma-separated list of controllers.]' \ + '--private-network[Turn off networking in the container. This makes all network interfaces unavailable in the container, with the exception of the loopback device.]' \ + '--read-only[Mount the root file system read only for the container.]' \ + '--capability=[List one or more additional capabilities to grant the container.]:capabilities:_nspawn-caps' \ + "--link-journal=[Control whether the container's journal shall be made visible to the host system.]:options:(no, host, guest, auto)" \ + '-j[Equivalent to --link-journal=guest.]' -- cgit v1.2.1 From 67e654f83021a1b3ed55f4b75936d03591bf80c1 Mon Sep 17 00:00:00 2001 From: William Giokas <1007380@gmail.com> Date: Mon, 29 Jul 2013 14:12:15 -0500 Subject: zsh_completion: Split out zsh _systemd-inhibit --- Makefile.am | 3 ++- shell-completion/zsh/_systemd | 30 +----------------------------- shell-completion/zsh/_systemd-inhibit | 27 +++++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 30 deletions(-) create mode 100644 shell-completion/zsh/_systemd-inhibit diff --git a/Makefile.am b/Makefile.am index 24e4fa4bd3..a4443fba9a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3730,7 +3730,8 @@ dist_bashcompletion_DATA += \ shell-completion/bash/loginctl dist_zshcompletion_DATA += \ - shell-completion/zsh/_loginctl + shell-completion/zsh/_loginctl \ + shell-completion/zsh/_systemd-inhibit systemd_inhibit_SOURCES = \ src/login/inhibit.c diff --git a/shell-completion/zsh/_systemd b/shell-completion/zsh/_systemd index bacf1795b9..6908725040 100644 --- a/shell-completion/zsh/_systemd +++ b/shell-completion/zsh/_systemd @@ -1,4 +1,4 @@ -#compdef systemd-analyze systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-inhibit systemd-machine-id-setup systemd-notify systemd-tmpfiles systemd-tty-ask-password-agent machinectl +#compdef systemd-analyze systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-machine-id-setup systemd-notify systemd-tmpfiles systemd-tty-ask-password-agent machinectl _ctls() { @@ -70,17 +70,6 @@ _ctls() {-v,--vm}'[Only detect whether we are run in a VM]' \ {-q,--quiet}"[Don't output anything, just set return value]" ;; - systemd-inhibit) - _arguments \ - {-h,--help}'[Show this help]' \ - '--version[Show package version]' \ - '--what=[Operations to inhibit]:options:(shutdown sleep idle handle-power-key handle-suspend-key handle-hibernate-key handle-lid-switch)' \ - '--who=[A descriptive string who is inhibiting]' \ - '--why=[A descriptive string why is being inhibited]' \ - '--mode=[One of block or delay]' \ - '--list[List active inhibitors]' \ - '*:commands:_systemd_inhibit_command' - ;; systemd-machine-id-setup) _arguments \ {-h,--help}'[Show this help]' \ @@ -136,23 +125,6 @@ _ctls() esac } -_systemd_inhibit_command(){ - if (( CURRENT == 1 )); then - compset -q - _normal - else - local n=${words[(b:2:i)[^-]*]} - if (( n <= CURRENT )); then - compset -n $n - _alternative \ - 'files:file:_files' \ - 'commands:command:_normal' && return 0 - fi - _default - fi - -} - _systemd_analyze_command(){ local -a _systemd_analyze_cmds # Descriptions taken from systemd-analyze --help. diff --git a/shell-completion/zsh/_systemd-inhibit b/shell-completion/zsh/_systemd-inhibit new file mode 100644 index 0000000000..7953455d40 --- /dev/null +++ b/shell-completion/zsh/_systemd-inhibit @@ -0,0 +1,27 @@ +#compdef systemd-inhibit + +_systemd_inhibit_command(){ + if (( CURRENT == 1 )); then + compset -q + _normal + else + local n=${words[(b:2:i)[^-]*]} + if (( n <= CURRENT )); then + compset -n $n + _alternative \ + 'files:file:_files' \ + 'commands:command:_normal' && return 0 + fi + _default + fi +} + +_arguments \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + '--what=[Operations to inhibit]:options:(shutdown sleep idle handle-power-key handle-suspend-key handle-hibernate-key handle-lid-switch)' \ + '--who=[A descriptive string who is inhibiting]' \ + '--why=[A descriptive string why is being inhibited]' \ + '--mode=[One of block or delay]' \ + '--list[List active inhibitors]' \ + '*:commands:_systemd_inhibit_command' -- cgit v1.2.1 From 7abfbe7903d8e792850ec39286a3d86e616a6477 Mon Sep 17 00:00:00 2001 From: William Giokas <1007380@gmail.com> Date: Mon, 29 Jul 2013 14:12:55 -0500 Subject: zsh_completion: Split out zsh _systemd-analyze --- Makefile.am | 1 + shell-completion/zsh/_systemd | 28 +--------------------------- shell-completion/zsh/_systemd-analyze | 26 ++++++++++++++++++++++++++ 3 files changed, 28 insertions(+), 27 deletions(-) create mode 100644 shell-completion/zsh/_systemd-analyze diff --git a/Makefile.am b/Makefile.am index a4443fba9a..4ac09cf922 100644 --- a/Makefile.am +++ b/Makefile.am @@ -348,6 +348,7 @@ dist_zshcompletion_DATA = \ shell-completion/zsh/_journalctl \ shell-completion/zsh/_udevadm \ shell-completion/zsh/_systemd-nspawn \ + shell-completion/zsh/_systemd-analyze \ shell-completion/zsh/_systemd dist_sysctl_DATA = \ diff --git a/shell-completion/zsh/_systemd b/shell-completion/zsh/_systemd index 6908725040..d0e1f3d4f9 100644 --- a/shell-completion/zsh/_systemd +++ b/shell-completion/zsh/_systemd @@ -1,17 +1,9 @@ -#compdef systemd-analyze systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-machine-id-setup systemd-notify systemd-tmpfiles systemd-tty-ask-password-agent machinectl +#compdef systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-machine-id-setup systemd-notify systemd-tmpfiles systemd-tty-ask-password-agent machinectl _ctls() { local curcontext="$curcontext" state lstate line case "$service" in - systemd-analyze) - _arguments \ - {-h,--help}'[Show help text.]' \ - '--user[Shows performance data of user sessions instead of the system manager.]' \ - '--order[When generating graph for dot, show only order]' \ - '--require[When generating graph for dot, show only requirement]' \ - '*::systemd-analyze commands:_systemd_analyze_command' - ;; systemd-ask-password) _arguments \ {-h,--help}'[Show this help]' \ @@ -125,24 +117,6 @@ _ctls() esac } -_systemd_analyze_command(){ - local -a _systemd_analyze_cmds - # Descriptions taken from systemd-analyze --help. - _systemd_analyze_cmds=( - 'time:Print time spent in the kernel before reaching userspace' - 'blame:Print list of running units ordered by time to init' - 'critical-chain:Print a tree of the time critical chain of units' - 'plot:Output SVG graphic showing service initialization' - 'dot:Dump dependency graph (in dot(1) format)' - ) - - if (( CURRENT == 1 )); then - _describe "options" _systemd_analyze_cmds - else - _message "no more options" - fi -} - _hosts_or_user_at_host() { _alternative \ diff --git a/shell-completion/zsh/_systemd-analyze b/shell-completion/zsh/_systemd-analyze new file mode 100644 index 0000000000..13e96c0586 --- /dev/null +++ b/shell-completion/zsh/_systemd-analyze @@ -0,0 +1,26 @@ +#compdef systemd-analyze + +_systemd_analyze_command(){ + local -a _systemd_analyze_cmds + # Descriptions taken from systemd-analyze --help. + _systemd_analyze_cmds=( + 'time:Print time spent in the kernel before reaching userspace' + 'blame:Print list of running units ordered by time to init' + 'critical-chain:Print a tree of the time critical chain of units' + 'plot:Output SVG graphic showing service initialization' + 'dot:Dump dependency graph (in dot(1) format)' + ) + + if (( CURRENT == 1 )); then + _describe "options" _systemd_analyze_cmds + else + _message "no more options" + fi +} + +_arguments \ + {-h,--help}'[Show help text.]' \ + '--user[Shows performance data of user sessions instead of the system manager.]' \ + '--order[When generating graph for dot, show only order]' \ + '--require[When generating graph for dot, show only requirement]' \ + '*::systemd-analyze commands:_systemd_analyze_command' -- cgit v1.2.1 From 439b7ce868810427712ca146b94b7fb004abfbb4 Mon Sep 17 00:00:00 2001 From: William Giokas <1007380@gmail.com> Date: Mon, 29 Jul 2013 14:13:29 -0500 Subject: zsh_completion: Split out zsh _machinectl --- Makefile.am | 3 +++ shell-completion/zsh/_machinectl | 47 ++++++++++++++++++++++++++++++++++++++ shell-completion/zsh/_systemd | 49 +--------------------------------------- 3 files changed, 51 insertions(+), 48 deletions(-) create mode 100644 shell-completion/zsh/_machinectl diff --git a/Makefile.am b/Makefile.am index 4ac09cf922..3713d0dd60 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3632,6 +3632,9 @@ dist_dbussystemservice_DATA += \ dist_dbuspolicy_DATA += \ src/machine/org.freedesktop.machine1.conf +dist_zshcompletion_DATA += \ + shell-completion/zsh/_machinectl + SYSTEM_UNIT_ALIASES += \ systemd-machined.service dbus-org.freedesktop.machine1.service diff --git a/shell-completion/zsh/_machinectl b/shell-completion/zsh/_machinectl new file mode 100644 index 0000000000..89196a568f --- /dev/null +++ b/shell-completion/zsh/_machinectl @@ -0,0 +1,47 @@ +#compdef machinectl + +(( $+functions[_machinectl_command] )) || _machinectl_command() +{ + local -a _machinectl_cmds + _machinectl_cmds=( + "list:List currently running VMs/containers" + "status:Show VM/container status" + "show:Show properties of one or more VMs/containers" + "terminate:Terminate one or more VMs/containers" + "kill:Send signal to process or a VM/container" + ) + if (( CURRENT == 1 )); then + _describe -t commands 'machinectl command' _machinectl_cmds || compadd "$@" + else + local curcontext="$curcontext" + cmd="${${_machinectl_cmds[(r)$words[1]:*]%%:*}}" + if (( $#cmd )); then + case $cmd in + list) msg="no options" ;; + *) + _machines=( "${(foa)$(machinectl list | awk '{print $1}')}" ) + if [[ -n "$_machines" ]]; then + _describe 'machines' _machines + else + _message 'no machines' + fi + esac + else + _message "no more options" + fi + fi +} + +_arguments \ + {-h,--help}'[Prints a short help text and exits.]' \ + '--version[Prints a short version string and exits.]' \ + {-p,--property=}'[Limit output to specified property.]:property:(Name Id Timestamp TimestampMonotonic Service Scope Leader Class State RootDirectory)' \ + {-a,--all}'[Show all proerties]' \ + (-l,--full)'[Do not ellipsize cgroup members]' \ + '--no-pager[Do not pipe output into a pager]' \ + '--no-ask-password[Do not ask for system passwords]' \ + '--kill-who=[Who to send signal to]:killwho:(leader all)' \ + {-s,--signal=}'[Which signal to send]:signal:_signals' \ + {-H,--host=}'[Show information for remote host]:userathost:_hosts_or_user_at_host' \ + {-P,--privileged}'[Acquire privileges before execution]' \ + '*::machinectl command:_machinectl_command' diff --git a/shell-completion/zsh/_systemd b/shell-completion/zsh/_systemd index d0e1f3d4f9..8eced095dc 100644 --- a/shell-completion/zsh/_systemd +++ b/shell-completion/zsh/_systemd @@ -1,4 +1,4 @@ -#compdef systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-machine-id-setup systemd-notify systemd-tmpfiles systemd-tty-ask-password-agent machinectl +#compdef systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-machine-id-setup systemd-notify systemd-tmpfiles systemd-tty-ask-password-agent _ctls() { @@ -98,21 +98,6 @@ _ctls() '--plymouth[Ask question with plymouth(8).]' \ '--console[Ask question on /dev/console.]' ;; - machinectl) - _arguments \ - {-h,--help}'[Prints a short help text and exits.]' \ - '--version[Prints a short version string and exits.]' \ - {-p,--property=}'[Limit output to specified property.]:property:(Name Id Timestamp TimestampMonotonic Service Scope Leader Class State RootDirectory)' \ - {-a,--all}'[Show all proerties]' \ - (-l,--full)'[Do not ellipsize cgroup members]' \ - '--no-pager[Do not pipe output into a pager]' \ - '--no-ask-password[Do not ask for system passwords]' \ - '--kill-who=[Who to send signal to]:killwho:(leader all)' \ - {-s,--signal=}'[Which signal to send]:signal:_signals' \ - {-H,--host=}'[Show information for remote host]:userathost:_hosts_or_user_at_host' \ - {-P,--privileged}'[Acquire privileges before execution]' \ - '*::machinectl command:_machinectl_command' - ;; *) _message 'eh?' ;; esac } @@ -130,38 +115,6 @@ _outputmodes() { _describe -t output 'output mode' _output_opts || compadd "$@" } -(( $+functions[_machinectl_command] )) || _machinectl_command() -{ - local -a _machinectl_cmds - _machinectl_cmds=( - "list:List currently running VMs/containers" - "status:Show VM/container status" - "show:Show properties of one or more VMs/containers" - "terminate:Terminate one or more VMs/containers" - "kill:Send signal to process or a VM/container" - ) - if (( CURRENT == 1 )); then - _describe -t commands 'machinectl command' _machinectl_cmds || compadd "$@" - else - local curcontext="$curcontext" - cmd="${${_machinectl_cmds[(r)$words[1]:*]%%:*}}" - if (( $#cmd )); then - case $cmd in - list) msg="no options" ;; - *) - _machines=( "${(foa)$(machinectl list | awk '{print $1}')}" ) - if [[ -n "$_machines" ]]; then - _describe 'machines' _machines - else - _message 'no machines' - fi - esac - else - _message "no more options" - fi - fi -} - _ctls "$@" #vim: set ft=zsh sw=4 ts=4 et -- cgit v1.2.1 From c51fa9dd4e3dc5d8b1c38a43ef01e6ac19b99085 Mon Sep 17 00:00:00 2001 From: William Giokas <1007380@gmail.com> Date: Mon, 29 Jul 2013 14:13:57 -0500 Subject: zsh_completion: Remove unused functions --- shell-completion/zsh/_systemd | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/shell-completion/zsh/_systemd b/shell-completion/zsh/_systemd index 8eced095dc..1addfa5878 100644 --- a/shell-completion/zsh/_systemd +++ b/shell-completion/zsh/_systemd @@ -102,19 +102,6 @@ _ctls() esac } -_hosts_or_user_at_host() -{ - _alternative \ - 'users-hosts:: _user_at_host' \ - 'hosts:: _hosts' -} - -_outputmodes() { - local -a _output_opts - _output_opts=(short short-monotonic verbose export json json-pretty json-see cat) - _describe -t output 'output mode' _output_opts || compadd "$@" -} - _ctls "$@" #vim: set ft=zsh sw=4 ts=4 et -- cgit v1.2.1 From 4a8fa990693edc47ac2192bf088a6e22e2390b41 Mon Sep 17 00:00:00 2001 From: William Giokas <1007380@gmail.com> Date: Mon, 29 Jul 2013 14:37:35 -0500 Subject: zsh_completion: Fix journalctl's --boot Actually displays a list of boot ID's and offsets to the user --- shell-completion/zsh/_journalctl | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/shell-completion/zsh/_journalctl b/shell-completion/zsh/_journalctl index 440e35d05b..4409fd7d68 100644 --- a/shell-completion/zsh/_journalctl +++ b/shell-completion/zsh/_journalctl @@ -39,6 +39,15 @@ _journal_fields() { _describe 'possible values' _fields } +_journal_boots() { + local -a _bootid _previousboots + _bootid=( ${(fao)"$(_call_program bootid "$service -F _BOOT_ID")"} ) + _previousboots=( -{1..${#_bootid}} ) + _alternative : \ + "offsets:boot offsets:(${_previousboots[1,-2]})" \ + "bootid:boot ids:(${_bootid[@]})" +} + _arguments -s \ {-h,--help}'[Show this help]' \ '--version[Show package version]' \ @@ -54,7 +63,7 @@ _arguments -s \ {-x,--catalog}'[Show explanatory texts with each log line]' \ {-q,--quiet}"[Don't show privilege warning]" \ {-m,--merge}'[Show entries from all available journals]' \ - {-b,--boot}'[Show entries from the specified boot only]' \ + {-b,--boot=}'[Show data only from the specified boot or offset]:boot id or offset:_journal_boots' \ {-k,--dmesg}'[Show only kernel messages, Implies -b]' \ {-u,--unit=}'[Show data only from the specified unit]:units:_journal_fields _SYSTEMD_UNIT' \ '--user-unit[Show data only from the specified user session unit]:units:_journal_fields _SYSTEMD_USER_UNIT' \ -- cgit v1.2.1 From 1272ff850ac65557f3cc06e00d5ddbd2588ff8b0 Mon Sep 17 00:00:00 2001 From: William Giokas <1007380@gmail.com> Date: Tue, 30 Jul 2013 19:05:31 -0500 Subject: zsh_completion: Split out zsh _systemd-tmpfiles You can choose to have systemd-tmpfiles at configuration time, so only install the completion for this if configured to do so. --- Makefile.am | 3 +++ shell-completion/zsh/_systemd | 12 +----------- shell-completion/zsh/_systemd-tmpfiles | 10 ++++++++++ 3 files changed, 14 insertions(+), 11 deletions(-) create mode 100644 shell-completion/zsh/_systemd-tmpfiles diff --git a/Makefile.am b/Makefile.am index 3713d0dd60..e35eaeb73d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1565,6 +1565,9 @@ SYSINIT_TARGET_WANTS += \ systemd-tmpfiles-setup-dev.service \ systemd-tmpfiles-setup.service +dist_zshcompletion_DATA += \ + shell-completion/zsh/_systemd-tmpfiles + TIMERS_TARGET_WANTS += \ systemd-tmpfiles-clean.timer diff --git a/shell-completion/zsh/_systemd b/shell-completion/zsh/_systemd index 1addfa5878..7aab52d5b6 100644 --- a/shell-completion/zsh/_systemd +++ b/shell-completion/zsh/_systemd @@ -1,4 +1,4 @@ -#compdef systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-machine-id-setup systemd-notify systemd-tmpfiles systemd-tty-ask-password-agent +#compdef systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-machine-id-setup systemd-notify systemd-tty-ask-password-agent _ctls() { @@ -77,16 +77,6 @@ _ctls() '--booted[Returns 0 if the system was booted up with systemd]' \ '--readahead=[Controls disk read-ahead operations]:arguments:(cancel done noreply)' ;; - systemd-tmpfiles) - _arguments \ - '--create[Create, set ownership/permissions based on the config files.]' \ - '--clean[Clean up all files and directories with an age parameter configured.]' \ - '--remove[All files and directories marked with r, R in the configuration files are removed.]' \ - '--prefix=[Only apply rules that apply to paths with the specified prefix.]' \ - '--exclude-prefix=[Ignore rules that apply to paths with the specified prefix.]' \ - '--help[Prints a short help text and exits.]' \ - '*::files:_files' - ;; systemd-tty-ask-password-agent) _arguments \ {-h,--help}'[Prints a short help text and exits.]' \ diff --git a/shell-completion/zsh/_systemd-tmpfiles b/shell-completion/zsh/_systemd-tmpfiles new file mode 100644 index 0000000000..4913dedd2c --- /dev/null +++ b/shell-completion/zsh/_systemd-tmpfiles @@ -0,0 +1,10 @@ +#compdef systemd-tmpfiles + +_arguments \ + '--create[Create, set ownership/permissions based on the config files.]' \ + '--clean[Clean up all files and directories with an age parameter configured.]' \ + '--remove[All files and directories marked with r, R in the configuration files are removed.]' \ + '--prefix=[Only apply rules that apply to paths with the specified prefix.]' \ + '--exclude-prefix=[Ignore rules that apply to paths with the specified prefix.]' \ + '--help[Prints a short help text and exits.]' \ + '*::files:_files' -- cgit v1.2.1 From 4af6e458e5a683b89032d560eb353c2272d3d564 Mon Sep 17 00:00:00 2001 From: William Giokas <1007380@gmail.com> Date: Thu, 1 Aug 2013 21:35:16 -0500 Subject: zsh_completion: Speed up noncached perf of _journalctl Splitting things unnecessarily at newlines causes tab completion to take an extremely long time. Also add a note saying that caching is not good for journalctl's completion. --- shell-completion/zsh/_journalctl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shell-completion/zsh/_journalctl b/shell-completion/zsh/_journalctl index 4409fd7d68..61983d5b6d 100644 --- a/shell-completion/zsh/_journalctl +++ b/shell-completion/zsh/_journalctl @@ -24,7 +24,8 @@ _list_fields() { _journal_none() { local -a _commands _files - _commands=( ${(f)"$(_call_program commands "$service" -F _EXE 2>/dev/null)"} ) + # Setting use-cache will slow this down considerably + _commands=( ${"$(_call_program commands "$service" -F _EXE 2>/dev/null)"} ) _alternative : \ 'files:/dev files:_files -W /dev -P /dev/' \ "commands:commands:($_commands[@])" \ -- cgit v1.2.1 From 6c17bf04b901a7ea8b4ec28fa635312fc2cd868a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 2 Aug 2013 07:58:26 -0400 Subject: coredumpctl: add more debug output It can be quite useful when somebody confuses _PID with COREDUMP_PID :). --- Makefile.am | 4 +++- src/journal/coredumpctl.c | 9 ++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index e35eaeb73d..a4b4cb46a0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3102,7 +3102,9 @@ systemd_coredumpctl_SOURCES = \ systemd_coredumpctl_LDADD = \ libsystemd-shared.la \ - libsystemd-journal.la + libsystemd-journal.la \ + libsystemd-journal-internal.la \ + libsystemd-id128-internal.la bin_PROGRAMS += \ systemd-coredumpctl diff --git a/src/journal/coredumpctl.c b/src/journal/coredumpctl.c index e1bd8621e3..75c96cc081 100644 --- a/src/journal/coredumpctl.c +++ b/src/journal/coredumpctl.c @@ -342,7 +342,7 @@ static int dump_list(sd_journal *j) { assert(j); /* The coredumps are likely to compressed, and for just - * listing them we don#t need to decompress them, so let's + * listing them we don't need to decompress them, so let's * pick a fairly low data threshold here */ sd_journal_set_data_threshold(j, 4096); @@ -557,6 +557,13 @@ int main(int argc, char *argv[]) { } } + if (_unlikely_(log_get_max_level() >= LOG_PRI(LOG_DEBUG))) { + _cleanup_free_ char *filter; + + filter = journal_make_match_string(j); + log_debug("Journal filter: %s", filter); + } + switch(arg_action) { case ACTION_LIST: -- cgit v1.2.1 From a217fdc98eab936502003c970e93f24d5f00a034 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 2 Aug 2013 07:58:56 -0400 Subject: zsh_completion: add "gdb" verb to coredumpctl --- shell-completion/zsh/_systemd-coredumpctl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/shell-completion/zsh/_systemd-coredumpctl b/shell-completion/zsh/_systemd-coredumpctl index f5d12cbcd1..1c67500d96 100644 --- a/shell-completion/zsh/_systemd-coredumpctl +++ b/shell-completion/zsh/_systemd-coredumpctl @@ -4,7 +4,8 @@ _systemd-coredumpctl_command(){ local -a _systemd_coredumpctl_cmds _systemd_coredumpctl_cmds=( 'list:List available coredumps' - 'dump:Print coredump to std' + 'dump:Print coredump to stdout' + 'gdb:Start gdb on a coredump' ) if (( CURRENT == 1 )); then _describe -t commands 'systemd-coredumpctl command' _systemd_coredumpctl_cmds @@ -28,6 +29,7 @@ _systemd-coredumpctl_command(){ _arguments \ {-o,--output=}'[Write output to FILE]:output file:_files' \ + {-F,--field=}'[Show field in list output]:field' \ '--no-pager[Do not pipe output into a pager]' \ {-h,--help}'[Show this help]' \ '--version[Show package version]' \ -- cgit v1.2.1 From 3b6c7e78cf38c1cad8fbb44d21e40ebf69c7cc77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 2 Aug 2013 11:01:10 -0400 Subject: tests: add a program for repetitive opening and closing of the journal Basically wraps an example provided by George McCollister. Should help with leaks in the future. --- Makefile.am | 9 ++++++ src/journal/test-journal-init.c | 60 +++++++++++++++++++++++++++++++++++++++ src/journal/test-journal-stream.c | 2 +- 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 src/journal/test-journal-init.c diff --git a/Makefile.am b/Makefile.am index a4b4cb46a0..8e64aaa6ed 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2793,6 +2793,14 @@ test_journal_stream_LDADD = \ libsystemd-journal-internal.la \ libsystemd-id128-internal.la +test_journal_init_SOURCES = \ + src/journal/test-journal-init.c + +test_journal_init_LDADD = \ + libsystemd-shared.la \ + libsystemd-daemon-internal.la \ + libsystemd-journal.la + test_journal_verify_SOURCES = \ src/journal/test-journal-verify.c @@ -2983,6 +2991,7 @@ tests += \ test-journal-syslog \ test-journal-match \ test-journal-stream \ + test-journal-init \ test-journal-verify \ test-journal-interleaving \ test-mmap-cache \ diff --git a/src/journal/test-journal-init.c b/src/journal/test-journal-init.c new file mode 100644 index 0000000000..58f260d6c2 --- /dev/null +++ b/src/journal/test-journal-init.c @@ -0,0 +1,60 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Zbigniew Jędrzejewski-Szmek + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include + +#include "log.h" +#include "util.h" + +int main(int argc, char *argv[]) { + sd_journal *j; + int r, i, I = 100; + char t[] = "/tmp/journal-stream-XXXXXX"; + + log_set_max_level(LOG_DEBUG); + + if (argc >= 2) + safe_atoi(argv[1], &I); + log_info("Running %d loops", I); + + assert_se(mkdtemp(t)); + + for (i = 0; i < I; i++) { + r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY); + assert_se(r == 0); + + sd_journal_close(j); + + r = sd_journal_open_directory(&j, t, 0); + assert_se(r == 0); + + sd_journal_close(j); + + j = NULL; + r = sd_journal_open_directory(&j, t, SD_JOURNAL_LOCAL_ONLY); + assert_se(r == -EINVAL); + assert_se(j == NULL); + } + + assert_se(rm_rf_dangerous(t, false, true, false) >= 0); + + return 0; +} diff --git a/src/journal/test-journal-stream.c b/src/journal/test-journal-stream.c index 4aba7febc7..6b32b252e8 100644 --- a/src/journal/test-journal-stream.c +++ b/src/journal/test-journal-stream.c @@ -75,7 +75,7 @@ int main(int argc, char *argv[]) { JournalFile *one, *two, *three; char t[] = "/tmp/journal-stream-XXXXXX"; unsigned i; - _cleanup_journal_close_ sd_journal*j = NULL; + _cleanup_journal_close_ sd_journal *j = NULL; char *z; const void *data; size_t l; -- cgit v1.2.1 From 8e6d9397b550f5617fc9231e3a275348cda23c89 Mon Sep 17 00:00:00 2001 From: George McCollister Date: Thu, 1 Aug 2013 12:40:01 -0500 Subject: journal: fix hashmap leak in mmap-cache hashmap_free() wasn't being called on m->contexts and m->fds resulting in a leak. To reproduce do: while(1) { sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY); sd_journal_close(j); } Memory usage will increase until OOM. --- src/journal/mmap-cache.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/journal/mmap-cache.c b/src/journal/mmap-cache.c index 767f555526..03b57beb04 100644 --- a/src/journal/mmap-cache.c +++ b/src/journal/mmap-cache.c @@ -307,9 +307,13 @@ static void mmap_cache_free(MMapCache *m) { while ((c = hashmap_first(m->contexts))) context_free(c); + hashmap_free(m->contexts); + while ((f = hashmap_first(m->fds))) fd_free(f); + hashmap_free(m->fds); + while (m->unused) window_free(m->unused); -- cgit v1.2.1 From d267e69da42f51ed0b34b59c0e3bc988127b95a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 1 Aug 2013 22:58:03 -0400 Subject: pkg-config: export systemd{system,user}generatordir and catalogdir We export the location of a bunch of directories this way, so it makes sense to add those three. Especially catalogdir is something that we want people to add things to. Note on the naming: the first two are tied closely to systemd itself, so I prefixed them with "systemd". The third one is rather more generic, so no prefix. https://bugs.freedesktop.org/show_bug.cgi?id=67635 --- Makefile.am | 4 +++- src/core/systemd.pc.in | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 8e64aaa6ed..1d7abfd61f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -82,9 +82,9 @@ userunitdir=$(prefix)/lib/systemd/user userpresetdir=$(prefix)/lib/systemd/user-preset tmpfilesdir=$(prefix)/lib/tmpfiles.d sysctldir=$(prefix)/lib/sysctl.d -usergeneratordir=$(prefix)/lib/systemd/user-generators pkgincludedir=$(includedir)/systemd systemgeneratordir=$(rootlibexecdir)/system-generators +usergeneratordir=$(prefix)/lib/systemd/user-generators systemshutdowndir=$(rootlibexecdir)/system-shutdown systemsleepdir=$(rootlibexecdir)/system-sleep systemunitdir=$(rootprefix)/lib/systemd/system @@ -4106,6 +4106,8 @@ substitutions = \ '|catalogdir=$(catalogdir)|' \ '|tmpfilesdir=$(tmpfilesdir)|' \ '|sysctldir=$(sysctldir)|' \ + '|systemgeneratordir=$(systemgeneratordir)|' \ + '|usergeneratordir=$(usergeneratordir)|' \ '|PACKAGE_VERSION=$(PACKAGE_VERSION)|' \ '|PACKAGE_NAME=$(PACKAGE_NAME)|' \ '|PACKAGE_URL=$(PACKAGE_URL)|' \ diff --git a/src/core/systemd.pc.in b/src/core/systemd.pc.in index 2f49d5df52..de0f6494e9 100644 --- a/src/core/systemd.pc.in +++ b/src/core/systemd.pc.in @@ -16,6 +16,9 @@ systemdsystemconfdir=@pkgsysconfdir@/system systemduserconfdir=@pkgsysconfdir@/user systemdsystemunitpath=${systemdsystemconfdir}:/etc/systemd/system:/run/systemd/system:/usr/local/lib/systemd/system:${systemdsystemunitdir}:/usr/lib/systemd/system:/lib/systemd/system systemduserunitpath=${systemduserconfdir}:/etc/systemd/user:/run/systemd/user:/usr/local/lib/systemd/user:/usr/local/share/systemd/user:${systemduserunitdir}:/usr/lib/systemd/user:/usr/share/systemd/user +systemdsystemgeneratordir=@systemgeneratordir@ +systemdusergeneratordir=@usergeneratordir@ +catalogdir=@catalogdir@ Name: systemd Description: systemd System and Service Manager -- cgit v1.2.1 From 7eb942c4086c563ca08f1b94c974d896eedb2e64 Mon Sep 17 00:00:00 2001 From: Daniel Wallace Date: Fri, 2 Aug 2013 21:38:14 -0500 Subject: zsh completion: add _kernel-install --- Makefile.am | 1 + shell-completion/zsh/_kernel-install | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 shell-completion/zsh/_kernel-install diff --git a/Makefile.am b/Makefile.am index 1d7abfd61f..b9c283503c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -347,6 +347,7 @@ dist_zshcompletion_DATA = \ shell-completion/zsh/_systemctl \ shell-completion/zsh/_journalctl \ shell-completion/zsh/_udevadm \ + shell-completion/zsh/_kernel-install \ shell-completion/zsh/_systemd-nspawn \ shell-completion/zsh/_systemd-analyze \ shell-completion/zsh/_systemd diff --git a/shell-completion/zsh/_kernel-install b/shell-completion/zsh/_kernel-install new file mode 100644 index 0000000000..065518834c --- /dev/null +++ b/shell-completion/zsh/_kernel-install @@ -0,0 +1,26 @@ +#compdef kernel-install + +_images(){ + if [[ "$words[2]" == "remove" ]]; then + _message 'No more options' + else + _path_files -W /boot/ -P /boot/ -g "vmlinuz-*" + fi +} + +_kernels(){ + read _MACHINE_ID < /etc/machine-id + _kernel=( /lib/modules/[0-9]* ) + if [[ "$cmd" == "remove" && -n "$_MACHINE_ID" ]]; then + _kernel=( /lib/modules/[0-9]* "/boot/$_MACHINE_ID"/[0-9]* ) + fi + _kernel=( ${_kernel##*/} ) + _describe "installed kernels" _kernel +} + +_arguments \ + '1::add or remove:(add remove)' \ + '2::kernel versions:_kernels' \ + '3::kernel images:_images' + +#vim: set ft=zsh sw=4 ts=4 et -- cgit v1.2.1 From 692ec7c998d5f889376686e4d83b696f1712e13e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 3 Aug 2013 10:18:21 -0400 Subject: build-sys: link with librt if linking with libsd-daemon-int In fba1ea0 'build: do not link everything with -lrt (and therefore -pthread)' librt was removed from the list of libraries. But libsd-daemon-internal also uses symbols from librt and librt must thus be added everywhere where libsd-daemon-interal is used, or otherwise linking might fail: /usr/bin/ld: ./.libs/libudev-core.a(sd-daemon.o): undefined reference to symbol 'mq_getattr@@GLIBC_2.3.4' /usr/bin/ld: note: 'mq_getattr@@GLIBC_2.3.4' is defined in DSO /lib64/librt.so.1 so try adding it to the linker command line --- Makefile.am | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/Makefile.am b/Makefile.am index b9c283503c..b8b8d06629 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2090,6 +2090,7 @@ libudev_la_LIBADD = \ libsystemd-shared.la \ libsystemd-label.la \ libsystemd-daemon-internal.la \ + $(RT_LIBS) \ libsystemd-id128-internal.la pkgconfiglib_DATA += \ @@ -2261,6 +2262,7 @@ libudev_core_la_LIBADD = \ libudev-private.la \ libsystemd-label.la \ libsystemd-daemon-internal.la \ + $(RT_LIBS) \ libsystemd-shared.la \ $(BLKID_LIBS) \ $(KMOD_LIBS) @@ -2647,7 +2649,8 @@ libsystemd_id128_la_LDFLAGS = \ libsystemd_id128_la_LIBADD = \ libsystemd-shared.la \ libsystemd-label.la \ - libsystemd-daemon-internal.la + libsystemd-daemon-internal.la \ + $(RT_LIBS) libsystemd_id128_internal_la_SOURCES = \ $(libsystemd_id128_la_SOURCES) @@ -2800,6 +2803,7 @@ test_journal_init_SOURCES = \ test_journal_init_LDADD = \ libsystemd-shared.la \ libsystemd-daemon-internal.la \ + $(RT_LIBS) \ libsystemd-journal.la test_journal_verify_SOURCES = \ @@ -2866,6 +2870,7 @@ libsystemd_journal_la_LIBADD = \ libsystemd-shared.la \ libsystemd-label.la \ libsystemd-daemon-internal.la \ + $(RT_LIBS) \ libsystemd-id128-internal.la libsystemd_journal_internal_la_SOURCES = \ @@ -3815,7 +3820,8 @@ libsystemd_login_la_LDFLAGS = \ libsystemd_login_la_LIBADD = \ libsystemd-shared.la \ - libsystemd-daemon-internal.la + libsystemd-daemon-internal.la \ + $(RT_LIBS) libsystemd_login_internal_la_SOURCES = \ $(libsystemd_login_la_SOURCES) @@ -3843,6 +3849,7 @@ pam_systemd_la_LIBADD = \ libsystemd-dbus.la \ libsystemd-shared.la \ libsystemd-daemon-internal.la \ + $(RT_LIBS) \ $(PAM_LIBS) pamlib_LTLIBRARIES = \ @@ -4027,7 +4034,8 @@ _reader_la_LIBADD = \ libsystemd-journal.la \ libsystemd-id128.la \ libsystemd-shared.la \ - libsystemd-daemon-internal.la + libsystemd-daemon-internal.la \ + $(RT_LIBS) login_la_SOURCES = \ src/python-systemd/login.c \ @@ -4050,7 +4058,8 @@ login_la_LIBADD = \ libsystemd-journal.la \ libsystemd-login.la \ libsystemd-shared.la \ - libsystemd-daemon-internal.la + libsystemd-daemon-internal.la \ + $(RT_LIBS) dist_pkgpyexec_PYTHON = \ src/python-systemd/journal.py \ -- cgit v1.2.1 From 92d700dea651e2a09ee75c7713b8387f11435cec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 4 Aug 2013 08:07:55 -0400 Subject: gitignore: add test-journal-init --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 694fc3d8f2..285f4062a2 100644 --- a/.gitignore +++ b/.gitignore @@ -115,6 +115,7 @@ /test-journal-match /test-journal-send /test-journal-stream +/test-journal-init /test-journal-syslog /test-journal-verify /test-libudev -- cgit v1.2.1 From 0b5a519c89b5fb48ec7a3cfbd9c02283ae0f23ac Mon Sep 17 00:00:00 2001 From: Daniel Schaal Date: Fri, 2 Aug 2013 07:59:02 +0200 Subject: systemd-delta: Only print colors when on a tty This make systemd-delta follow the behaviour of systemctl and journalctl. https://bugs.freedesktop.org/show_bug.cgi?id=67656 [zj: unify color query methods between those three programs.] --- src/delta/delta.c | 15 +++++--- src/journal/journalctl.c | 5 ++- src/shared/util.h | 16 +++++++++ src/systemctl/systemctl.c | 88 +++++++++++++++++------------------------------ 4 files changed, 60 insertions(+), 64 deletions(-) diff --git a/src/delta/delta.c b/src/delta/delta.c index 49c2fc323a..b3272d916e 100644 --- a/src/delta/delta.c +++ b/src/delta/delta.c @@ -66,7 +66,8 @@ static int notify_override_masked(const char *top, const char *bottom) { if (!(arg_flags & SHOW_MASKED)) return 0; - printf(ANSI_HIGHLIGHT_RED_ON "[MASKED]" ANSI_HIGHLIGHT_OFF " %s → %s\n", top, bottom); + printf("%s%s%s %s → %s\n", + ansi_highlight_red(), "[MASKED]", ansi_highlight_off(), top, bottom); return 1; } @@ -74,7 +75,8 @@ static int notify_override_equivalent(const char *top, const char *bottom) { if (!(arg_flags & SHOW_EQUIVALENT)) return 0; - printf(ANSI_HIGHLIGHT_GREEN_ON "[EQUIVALENT]" ANSI_HIGHLIGHT_OFF " %s → %s\n", top, bottom); + printf("%s%s%s %s → %s\n", + ansi_highlight_green(), "[EQUIVALENT]", ansi_highlight(), top, bottom); return 1; } @@ -82,7 +84,8 @@ static int notify_override_redirected(const char *top, const char *bottom) { if (!(arg_flags & SHOW_REDIRECTED)) return 0; - printf(ANSI_HIGHLIGHT_ON "[REDIRECTED]" ANSI_HIGHLIGHT_OFF " %s → %s\n", top, bottom); + printf("%s%s%s %s → %s\n", + ansi_highlight(), "[REDIRECTED]", ansi_highlight_off(), top, bottom); return 1; } @@ -90,7 +93,8 @@ static int notify_override_overridden(const char *top, const char *bottom) { if (!(arg_flags & SHOW_OVERRIDDEN)) return 0; - printf(ANSI_HIGHLIGHT_ON "[OVERRIDDEN]" ANSI_HIGHLIGHT_OFF " %s → %s\n", top, bottom); + printf("%s%s%s %s → %s\n", + ansi_highlight(), "[OVERRIDDEN]", ansi_highlight_off(), top, bottom); return 1; } @@ -98,7 +102,8 @@ static int notify_override_extended(const char *top, const char *bottom) { if (!(arg_flags & SHOW_EXTENDED)) return 0; - printf(ANSI_HIGHLIGHT_ON "[EXTENDED]" ANSI_HIGHLIGHT_OFF " %s → %s\n", top, bottom); + printf("%s%s%s %s → %s\n", + ansi_highlight(), "[EXTENDED]", ansi_highlight_off(), top, bottom); return 1; } diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index dde2ed7e37..feea6bf19e 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -1605,14 +1605,13 @@ int main(int argc, char *argv[]) { if (!arg_merge) { sd_id128_t boot_id; - const char *color_on = on_tty() ? ANSI_HIGHLIGHT_ON : "", - *color_off = on_tty() ? ANSI_HIGHLIGHT_OFF : ""; r = sd_journal_get_monotonic_usec(j, NULL, &boot_id); if (r >= 0) { if (previous_boot_id_valid && !sd_id128_equal(boot_id, previous_boot_id)) - printf("%s-- Reboot --%s\n", color_on, color_off); + printf("%s-- Reboot --%s\n", + ansi_highlight(), ansi_highlight_off()); previous_boot_id = boot_id; previous_boot_id_valid = true; diff --git a/src/shared/util.h b/src/shared/util.h index ac999c624c..3be692ec33 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -374,6 +374,22 @@ void columns_lines_cache_reset(int _unused_ signum); bool on_tty(void); +static inline const char *ansi_highlight(void) { + return on_tty() ? ANSI_HIGHLIGHT_ON : ""; +} + +static inline const char *ansi_highlight_red(void) { + return on_tty() ? ANSI_HIGHLIGHT_RED_ON : ""; +} + +static inline const char *ansi_highlight_green(void) { + return on_tty() ? ANSI_HIGHLIGHT_GREEN_ON : ""; +} + +static inline const char *ansi_highlight_off(void) { + return on_tty() ? ANSI_HIGHLIGHT_OFF : ""; +} + int running_in_chroot(void); char *ellipsize(const char *s, size_t length, unsigned percent); diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 5a4d80c4d6..8ec1824f3b 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -175,30 +175,6 @@ static void polkit_agent_open_if_enabled(void) { } #endif -static const char *ansi_highlight(bool b) { - - if (!on_tty()) - return ""; - - return b ? ANSI_HIGHLIGHT_ON : ANSI_HIGHLIGHT_OFF; -} - -static const char *ansi_highlight_red(bool b) { - - if (!on_tty()) - return ""; - - return b ? ANSI_HIGHLIGHT_RED_ON : ANSI_HIGHLIGHT_OFF; -} - -static const char *ansi_highlight_green(bool b) { - - if (!on_tty()) - return ""; - - return b ? ANSI_HIGHLIGHT_GREEN_ON : ANSI_HIGHLIGHT_OFF; -} - static int translate_bus_error_to_exit_status(int r, const DBusError *error) { assert(error); @@ -381,14 +357,14 @@ static void output_units_list(const struct unit_info *unit_infos, unsigned c) { if (streq(u->load_state, "error") || streq(u->load_state, "not-found")) { - on_loaded = on = ansi_highlight_red(true); - off_loaded = off = ansi_highlight_red(false); + on_loaded = on = ansi_highlight_red(); + off_loaded = off = ansi_highlight_off(); } else on_loaded = off_loaded = ""; if (streq(u->active_state, "failed")) { - on_active = on = ansi_highlight_red(true); - off_active = off = ansi_highlight_red(false); + on_active = on = ansi_highlight_red(); + off_active = off = ansi_highlight_off(); } else on_active = off_active = ""; @@ -416,11 +392,11 @@ static void output_units_list(const struct unit_info *unit_infos, unsigned c) { if (job_count) printf("JOB = Pending job for the unit.\n"); puts(""); - on = ansi_highlight(true); - off = ansi_highlight(false); + on = ansi_highlight(); + off = ansi_highlight_off(); } else { - on = ansi_highlight_red(true); - off = ansi_highlight_red(false); + on = ansi_highlight_red(); + off = ansi_highlight_off(); } if (arg_all) @@ -683,13 +659,13 @@ static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) { printf("\n"); } - on = ansi_highlight(true); - off = ansi_highlight(false); + on = ansi_highlight(); + off = ansi_highlight_off(); if (!arg_no_legend) printf("\n"); } else { - on = ansi_highlight_red(true); - off = ansi_highlight_red(false); + on = ansi_highlight_red(); + off = ansi_highlight_off(); } if (!arg_no_legend) { @@ -838,11 +814,11 @@ static void output_unit_file_list(const UnitFileList *units, unsigned c) { u->state == UNIT_FILE_MASKED_RUNTIME || u->state == UNIT_FILE_DISABLED || u->state == UNIT_FILE_INVALID) { - on = ansi_highlight_red(true); - off = ansi_highlight_red(false); + on = ansi_highlight_red(); + off = ansi_highlight_off(); } else if (u->state == UNIT_FILE_ENABLED) { - on = ansi_highlight_green(true); - off = ansi_highlight_green(false); + on = ansi_highlight_green(); + off = ansi_highlight_off(); } else on = off = ""; @@ -1250,8 +1226,8 @@ static void list_jobs_print(struct job_info* jobs, size_t n) { assert(n == 0 || jobs); if (n == 0) { - on = ansi_highlight_green(true); - off = ansi_highlight_green(false); + on = ansi_highlight_green(); + off = ansi_highlight_off(); printf("%sNo jobs running.%s\n", on, off); return; @@ -1287,8 +1263,8 @@ static void list_jobs_print(struct job_info* jobs, size_t n) { _cleanup_free_ char *e = NULL; if (streq(j->state, "running")) { - on = ansi_highlight(true); - off = ansi_highlight(false); + on = ansi_highlight(); + off = ansi_highlight_off(); } else on = off = ""; @@ -1301,8 +1277,8 @@ static void list_jobs_print(struct job_info* jobs, size_t n) { } } - on = ansi_highlight(true); - off = ansi_highlight(false); + on = ansi_highlight(); + off = ansi_highlight_off(); if (on_tty()) printf("\n%s%zu jobs listed%s.\n", on, n, off); @@ -2558,8 +2534,8 @@ static void print_status_info(UnitStatusInfo *i) { printf(" Follow: unit currently follows state of %s\n", i->following); if (streq_ptr(i->load_state, "error")) { - on = ansi_highlight_red(true); - off = ansi_highlight_red(false); + on = ansi_highlight_red(); + off = ansi_highlight_off(); } else on = off = ""; @@ -2609,11 +2585,11 @@ static void print_status_info(UnitStatusInfo *i) { ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state; if (streq_ptr(i->active_state, "failed")) { - on = ansi_highlight_red(true); - off = ansi_highlight_red(false); + on = ansi_highlight_red(); + off = ansi_highlight_off(); } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) { - on = ansi_highlight_green(true); - off = ansi_highlight_green(false); + on = ansi_highlight_green(); + off = ansi_highlight_off(); } else on = off = ""; @@ -2688,8 +2664,8 @@ static void print_status_info(UnitStatusInfo *i) { good = is_clean_exit_lsb(p->code, p->status, NULL); if (!good) { - on = ansi_highlight_red(true); - off = ansi_highlight_red(false); + on = ansi_highlight_red(); + off = ansi_highlight_off(); } else on = off = ""; @@ -2808,8 +2784,8 @@ static void print_status_info(UnitStatusInfo *i) { if (i->need_daemon_reload) printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n", - ansi_highlight_red(true), - ansi_highlight_red(false), + ansi_highlight_red(), + ansi_highlight_off(), arg_scope == UNIT_FILE_SYSTEM ? "" : "--user "); } -- cgit v1.2.1 From d6ee7fa24f5437b7bb2e12f94e0cb828ed25943a Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Mon, 5 Aug 2013 01:13:28 +0200 Subject: man: wording and grammar updates This includes regularly-submitted corrections to comma setting and orthographical mishaps that appeared in man/ in recent commits. --- man/journald.conf.xml | 2 +- man/systemd-run.xml | 6 +++--- man/systemd.kill.xml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/man/journald.conf.xml b/man/journald.conf.xml index 9219b3daaf..7aa2e78ed3 100644 --- a/man/journald.conf.xml +++ b/man/journald.conf.xml @@ -355,7 +355,7 @@ syncing is unconditionally done immediately after a log message of priority CRIT, ALERT or EMERG has been - logged, this setting hence applies + logged. This setting hence applies only to messages of the levels ERR, WARNING, NOTICE, INFO, DEBUG. The default timeout is 5 minutes. diff --git a/man/systemd-run.xml b/man/systemd-run.xml index e1e885178d..6b0189c25d 100644 --- a/man/systemd-run.xml +++ b/man/systemd-run.xml @@ -151,7 +151,7 @@ along with systemd; If not, see . - After the service's process terminated keep + After the service's process has terminated, keep the service around until it is explicitly stopped. This is useful to collect runtime information about the service after it finished running. Also see @@ -164,10 +164,10 @@ along with systemd; If not, see . - When terminating the scope unit send a SIGHUP + When terminating the scope unit, send a SIGHUP immediately after SIGTERM. This is useful to indicate to shells and shell-like processes that the connection has been - sewered. Also see SendSIGHUP= in + severed. Also see SendSIGHUP= in systemd.kill5. diff --git a/man/systemd.kill.xml b/man/systemd.kill.xml index 517a891777..ab3d28f23a 100644 --- a/man/systemd.kill.xml +++ b/man/systemd.kill.xml @@ -123,8 +123,8 @@ SIGHUP (if enabled with SendSIGHUP=). If - then after a delay (configured via the - TimeoutStopSec= option) + then, after a delay (configured via the + TimeoutStopSec= option), processes still remain, the termination request is repeated with the SIGKILL -- cgit v1.2.1 From 9cfda9644094e8d0fdd9f8b74ade9868514a6a70 Mon Sep 17 00:00:00 2001 From: Michael Scherer Date: Sun, 4 Aug 2013 22:36:42 +0200 Subject: man: fix typo in documentation of systemd-machined --- man/systemd-machined.service.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/systemd-machined.service.xml b/man/systemd-machined.service.xml index abe221a178..352b4a025f 100644 --- a/man/systemd-machined.service.xml +++ b/man/systemd-machined.service.xml @@ -45,7 +45,7 @@ systemd-machined.service systemd-machined - Virtual machine and container registartion manager + Virtual machine and container registration manager -- cgit v1.2.1 From 04fefcddb8e71e87abeb0faff0f547eb8ae88a64 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Thu, 1 Aug 2013 12:14:02 +0200 Subject: journal: handle multiline syslog messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the journal can handle multiple lines just well natively, and rsyslog can be configured to handle them as well, there is no need to truncate messages from syslog() after the first newline. Reproducer: 1. Add following four lines to /etc/rsyslog.conf ---------- $EscapeControlCharactersOnReceive off $ActionFileDefaultTemplate RSYSLOG_SysklogdFileFormat $SpaceLFOnReceive on $DropTrailingLFOnReception off ---------- 3. Restart rsyslog # service rsyslog restart 4. Compile and run the following program ---------- #include #include int main() { syslog(LOG_INFO, "aaa%caaa", '\n'); return 0; } ---------- Actual results: Below message appears in /var/log/messages. ----------    Sep 7 19:19:39 localhost test2: aaa ---------- Expected results: Below message, which worked prior to systemd-journald appears in /var/log/messages. ----------    Sep 7 19:19:39 localhost test2: aaa aaa https://bugzilla.redhat.com/show_bug.cgi?id=855313 --- src/journal/journald-server.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 821935c390..f417059ec5 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -1240,12 +1240,7 @@ int process_event(Server *s, struct epoll_event *ev) { char *e; if (n > 0 && n_fds == 0) { - e = memchr(s->buffer, '\n', n); - if (e) - *e = 0; - else - s->buffer[n] = 0; - + s->buffer[n] = 0; server_process_syslog_message(s, strstrip(s->buffer), ucred, tv, label, label_len); } else if (n_fds > 0) log_warning("Got file descriptors via syslog socket. Ignoring."); -- cgit v1.2.1 From cff452c7e974db5053cdbd0d7bbbab2e3b4c91b9 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 6 Aug 2013 15:03:53 +0200 Subject: TODO: add weird instance unit enable behavior --- TODO | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/TODO b/TODO index 99122b5715..8896747073 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,9 @@ Bugfixes: +* enabling an instance unit creates pointless link, and + the unit will be started with getty@getty.service: + $ systemctl enable getty@.service + ln -s '/usr/lib/systemd/system/getty@.service' '/etc/systemd/system/getty.target.wants/getty@.service' + * check systemd-tmpfiles for selinux context hookup for mknod(), symlink() and similar * swap units that are activated by one name but shown in the kernel under another are semi-broken -- cgit v1.2.1 From 608c3dc5693177d9c297753a63349135a8edd76f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 6 Aug 2013 21:02:35 -0400 Subject: journald: remove unused variable --- src/journal/journald-server.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index f417059ec5..14afcfb794 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -1237,8 +1237,6 @@ int process_event(Server *s, struct epoll_event *ev) { } if (ev->data.fd == s->syslog_fd) { - char *e; - if (n > 0 && n_fds == 0) { s->buffer[n] = 0; server_process_syslog_message(s, strstrip(s->buffer), ucred, tv, label, label_len); -- cgit v1.2.1 From ebec5783c4ff847d09816860261bbea34287ddf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 6 Aug 2013 21:30:34 -0400 Subject: systemd: fix segv in snapshot creation https://bugs.freedesktop.org/show_bug.cgi?id=67848 --- src/core/snapshot.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/snapshot.c b/src/core/snapshot.c index 1423854098..d11239dff3 100644 --- a/src/core/snapshot.c +++ b/src/core/snapshot.c @@ -221,8 +221,10 @@ int snapshot_create(Manager *m, const char *name, bool cleanup, DBusError *e, Sn if (asprintf(&n, "snapshot-%u.snapshot", ++ m->n_snapshots) < 0) return -ENOMEM; - if (!manager_get_unit(m, n)) + if (!manager_get_unit(m, n)) { + name = n; break; + } free(n); n = NULL; -- cgit v1.2.1 From 4a792f4676e5f8fa86aff8aac09c4b6391dee313 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Mon, 5 Aug 2013 19:54:00 -0600 Subject: keymap: add HP EliteBook 2570p's wlan switch to hwdb https://bugs.freedesktop.org/show_bug.cgi?id=66178 --- hwdb/60-keyboard.hwdb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index 0ee65d792a..46da5749ec 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -392,6 +392,10 @@ keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP G60 Notebook PC:pvr* KEYBOARD_KEY_d8=!f23 # touchpad off KEYBOARD_KEY_d9=!f22 # touchpad on +# 2570p +keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*2570p*:pvr* + KEYBOARD_KEY_f8=wlan # Wireless HW switch button + # TX2 keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[tT][xX]2*:pvr* KEYBOARD_KEY_c2=media -- cgit v1.2.1 From 0787758d26337ec897d9553fe962678fbf0a0962 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 4 Aug 2013 22:46:38 -0400 Subject: hwdb: add GIGABYTE U2442 mute key to the force-release list https://bugs.freedesktop.org/show_bug.cgi?id=67651 --- hwdb/60-keyboard.hwdb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index 46da5749ec..c58b72cc16 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -319,6 +319,13 @@ keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*ESPRIMO Mobile V6*:pvr* KEYBOARD_KEY_ce=brightnessup KEYBOARD_KEY_ef=brightnessdown +########################################################### +# GIGABYTE +########################################################### + +keyboard:dmi:bvn*:bvr*:bd*:svnGIGABYTE:pnU2442:* + KEYBOARD_KEY_a0=! # mute + ########################################################### # Genius ########################################################### -- cgit v1.2.1 From 0238cf7cda0720c21d9b40d7256988aba29fc565 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 7 Aug 2013 13:10:01 +0200 Subject: udev: hwdb - try reading modalias for usb before falling back to the composed one --- src/udev/udev-builtin-hwdb.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/udev/udev-builtin-hwdb.c b/src/udev/udev-builtin-hwdb.c index f1c0ca9cb1..d6aa96bb3d 100644 --- a/src/udev/udev-builtin-hwdb.c +++ b/src/udev/udev-builtin-hwdb.c @@ -102,13 +102,12 @@ static int udev_builtin_hwdb_search(struct udev_device *dev, struct udev_device if (subsystem && !streq(dsubsys, subsystem)) continue; + modalias = udev_device_get_property_value(d, "MODALIAS"); + /* the usb_device does not have a modalias, compose one */ - if (streq(dsubsys, "usb")) + if (!modalias && streq(dsubsys, "usb")) modalias = modalias_usb(d, s, sizeof(s)); - if (!modalias) - modalias = udev_device_get_property_value(d, "MODALIAS"); - if (!modalias) continue; -- cgit v1.2.1 From 1fab57c209035f7e66198343074e9cee06718bda Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 7 Aug 2013 16:46:53 +0200 Subject: TODO: add hwdb timestamp check --- TODO | 3 +++ 1 file changed, 3 insertions(+) diff --git a/TODO b/TODO index 8896747073..ead699cd16 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,7 @@ Bugfixes: +* the running hwdb seems not to pick up updated database files without + an explicit: udevadm control --reload + * enabling an instance unit creates pointless link, and the unit will be started with getty@getty.service: $ systemctl enable getty@.service -- cgit v1.2.1 From f058ccf2cdc20ff9ad986e84727d2cf43c51a0ef Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 7 Aug 2013 16:49:18 +0200 Subject: hwdb: update --- hwdb/20-OUI.hwdb | 344 +++++++++++++++++++++++++++++++++++++++++- hwdb/20-pci-vendor-model.hwdb | 114 ++++++++++---- 2 files changed, 427 insertions(+), 31 deletions(-) diff --git a/hwdb/20-OUI.hwdb b/hwdb/20-OUI.hwdb index 5ebd6413b9..baf1df17ac 100644 --- a/hwdb/20-OUI.hwdb +++ b/hwdb/20-OUI.hwdb @@ -4070,7 +4070,7 @@ OUI:0050C2556* ID_OUI_FROM_DATABASE=Freiburger BlickZentrum OUI:0050C2557* - ID_OUI_FROM_DATABASE=TOYO RADIO SYSTEMS CO., LTD. + ID_OUI_FROM_DATABASE=Netcomsec OUI:0050C2558* ID_OUI_FROM_DATABASE=Bedo Elektronik GmbH @@ -13141,6 +13141,69 @@ OUI:40D85513C* OUI:40D85513D* ID_OUI_FROM_DATABASE=Perm Scientific-Industrial Instrument Making Company JSC +OUI:40D85513E* + ID_OUI_FROM_DATABASE=hanatech + +OUI:40D85513F* + ID_OUI_FROM_DATABASE=Zhejiang Wellsun Electric Meter Co.,Ltd + +OUI:40D855140* + ID_OUI_FROM_DATABASE=InnoTrans Communications, Inc + +OUI:40D855141* + ID_OUI_FROM_DATABASE=Key Systems, Inc. + +OUI:40D855142* + ID_OUI_FROM_DATABASE=Tetracore, Inc. + +OUI:40D855143* + ID_OUI_FROM_DATABASE=Tokyo Drawing Ltd. + +OUI:40D855144* + ID_OUI_FROM_DATABASE=Venco + +OUI:40D855145* + ID_OUI_FROM_DATABASE=Weber Marking Systems GmbH + +OUI:40D855146* + ID_OUI_FROM_DATABASE=Pleiger Elektronik GmbH and Co. KG + +OUI:40D855147* + ID_OUI_FROM_DATABASE=Aplex Technology Inc. + +OUI:40D855148* + ID_OUI_FROM_DATABASE=SEIKO TIME SYSTEMS INC. + +OUI:40D855149* + ID_OUI_FROM_DATABASE=Engage Technologies + +OUI:40D85514A* + ID_OUI_FROM_DATABASE=GENERAL DYNAMICS C4 SYSTEMS + +OUI:40D85514C* + ID_OUI_FROM_DATABASE=PLT + +OUI:40D85514D* + ID_OUI_FROM_DATABASE=SOMFY SAS + +OUI:40D85514E* + ID_OUI_FROM_DATABASE=Marposs S.p.A + +OUI:40D85514F* + ID_OUI_FROM_DATABASE=TDS Software Solutions Pty Ltd + +OUI:40D855150* + ID_OUI_FROM_DATABASE=SHIKINO HIGH-TECH + +OUI:40D855151* + ID_OUI_FROM_DATABASE=Progress Rail Services, Inspection and Information Systems + +OUI:40D855152* + ID_OUI_FROM_DATABASE=Home Automation Europe + +OUI:40D855153* + ID_OUI_FROM_DATABASE=BlinkPipe Ltd + OUI:000000* ID_OUI_FROM_DATABASE=XEROX CORPORATION @@ -26020,6 +26083,9 @@ OUI:0010EE* OUI:0010EF* ID_OUI_FROM_DATABASE=DBTEL INCORPORATED +OUI:0010F0* + ID_OUI_FROM_DATABASE=RITTAL-WERK RUDOLF LOH GmbH & Co. + OUI:0010F1* ID_OUI_FROM_DATABASE=I-O CORPORATION @@ -48487,6 +48553,9 @@ OUI:00A1DE* OUI:00A2DA* ID_OUI_FROM_DATABASE=INAT GmbH +OUI:00A2FF* + ID_OUI_FROM_DATABASE=abatec group AG + OUI:00AA00* ID_OUI_FROM_DATABASE=INTEL CORPORATION @@ -51046,6 +51115,9 @@ OUI:00E0FF* OUI:00E175* ID_OUI_FROM_DATABASE=AK-Systems Ltd +OUI:00E3B2* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:00E666* ID_OUI_FROM_DATABASE=ARIMA Communications Corp. @@ -51773,7 +51845,7 @@ OUI:080080* ID_OUI_FROM_DATABASE=AES DATA INC. OUI:080081* - ID_OUI_FROM_DATABASE=,ASTECH INC. + ID_OUI_FROM_DATABASE=ASTECH INC. OUI:080082* ID_OUI_FROM_DATABASE=VERITAS SOFTWARE @@ -52120,6 +52192,9 @@ OUI:0C2AE7* OUI:0C2D89* ID_OUI_FROM_DATABASE=QiiQ Communications Inc. +OUI:0C3021* + ID_OUI_FROM_DATABASE=Apple, Inc + OUI:0C37DC* ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd @@ -52132,9 +52207,15 @@ OUI:0C3C65* OUI:0C469D* ID_OUI_FROM_DATABASE=MS Sedco +OUI:0C473D* + ID_OUI_FROM_DATABASE=Hitron Technologies. Inc + OUI:0C4C39* ID_OUI_FROM_DATABASE=Mitrastar Technology +OUI:0C4DE9* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:0C51F7* ID_OUI_FROM_DATABASE=CHAUVIN ARNOUX @@ -52243,6 +52324,9 @@ OUI:0CA402* OUI:0CA42A* ID_OUI_FROM_DATABASE=OB Telecom Electronic Technology Co., Ltd +OUI:0CA694* + ID_OUI_FROM_DATABASE=Sunitec Enterprise Co.,Ltd + OUI:0CAF5A* ID_OUI_FROM_DATABASE=GENUS POWER INFRASTRUCTURES LIMITED @@ -52522,6 +52606,9 @@ OUI:1078D2* OUI:107A86* ID_OUI_FROM_DATABASE=U&U ENGINEERING INC. +OUI:107BEF* + ID_OUI_FROM_DATABASE=ZyXEL Communications Corp + OUI:1083D2* ID_OUI_FROM_DATABASE=Microseven Systems, LLC @@ -52708,6 +52795,9 @@ OUI:1441E2* OUI:144319* ID_OUI_FROM_DATABASE=Creative&Link Technology Limited +OUI:1446E4* + ID_OUI_FROM_DATABASE=AVISTEL + OUI:144978* ID_OUI_FROM_DATABASE=Digital Control Incorporated @@ -52726,6 +52816,9 @@ OUI:145A05* OUI:145BD1* ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. +OUI:146080* + ID_OUI_FROM_DATABASE=zte corporation + OUI:146308* ID_OUI_FROM_DATABASE=JABIL CIRCUIT (SHANGHAI) LTD. @@ -52780,6 +52873,9 @@ OUI:14A9E3* OUI:14ABF0* ID_OUI_FROM_DATABASE=ARRIS Group, Inc. +OUI:14B126* + ID_OUI_FROM_DATABASE=Industrial Software Co + OUI:14B1C8* ID_OUI_FROM_DATABASE=InfiniWing, Inc. @@ -52933,6 +53029,9 @@ OUI:183F47* OUI:18422F* ID_OUI_FROM_DATABASE=Alcatel Lucent +OUI:184462* + ID_OUI_FROM_DATABASE=Riava Networks, Inc. + OUI:184617* ID_OUI_FROM_DATABASE=Samsung Electronics @@ -53392,6 +53491,9 @@ OUI:2013E0* OUI:2016D8* ID_OUI_FROM_DATABASE=Liteon Technology Corporation +OUI:20180E* + ID_OUI_FROM_DATABASE=Shenzhen Sunchip Technology Co., Ltd + OUI:201A06* ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD. @@ -53836,6 +53938,9 @@ OUI:28061E* OUI:28068D* ID_OUI_FROM_DATABASE=ITL, LLC +OUI:280B5C* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:280CB8* ID_OUI_FROM_DATABASE=Mikrosay Yazilim ve Elektronik A.S. @@ -53896,6 +54001,9 @@ OUI:28401A* OUI:284121* ID_OUI_FROM_DATABASE=OptiSense Network, LLC +OUI:2847AA* + ID_OUI_FROM_DATABASE=Nokia Corporation + OUI:284846* ID_OUI_FROM_DATABASE=GridCentric Inc. @@ -53962,6 +54070,9 @@ OUI:2893FE* OUI:28940F* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. +OUI:2894AF* + ID_OUI_FROM_DATABASE=Samhwa Telecom + OUI:28987B* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd @@ -54208,6 +54319,9 @@ OUI:2C69BA* OUI:2C6BF5* ID_OUI_FROM_DATABASE=Juniper networks +OUI:2C7155* + ID_OUI_FROM_DATABASE=HiveMotion + OUI:2C72C3* ID_OUI_FROM_DATABASE=Soundmatters @@ -54346,6 +54460,9 @@ OUI:300B9C* OUI:300ED5* ID_OUI_FROM_DATABASE=Hon Hai Precision Ind.Co.Ltd +OUI:3010E4* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:30142D* ID_OUI_FROM_DATABASE=Piciorgros GmbH @@ -54364,6 +54481,9 @@ OUI:3017C8* OUI:3018CF* ID_OUI_FROM_DATABASE=DEOS control systems GmbH +OUI:301966* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:301A28* ID_OUI_FROM_DATABASE=Mako Networks Ltd @@ -54520,6 +54640,9 @@ OUI:30D357* OUI:30D46A* ID_OUI_FROM_DATABASE=Autosales Incorporated +OUI:30D6C9* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:30DE86* ID_OUI_FROM_DATABASE=Cedac Software S.r.l. @@ -54595,6 +54718,9 @@ OUI:344B3D* OUI:344B50* ID_OUI_FROM_DATABASE=ZTE Corporation +OUI:344F3F* + ID_OUI_FROM_DATABASE=IO-Power Technology Co., Ltd. + OUI:344F69* ID_OUI_FROM_DATABASE=EKINOPS SAS @@ -54604,6 +54730,9 @@ OUI:3451C9* OUI:345B11* ID_OUI_FROM_DATABASE=EVI HEAT AB +OUI:345C40* + ID_OUI_FROM_DATABASE=Cargt Holdings LLC + OUI:346178* ID_OUI_FROM_DATABASE=The Boeing Company @@ -54646,6 +54775,9 @@ OUI:348446* OUI:34862A* ID_OUI_FROM_DATABASE=Heinz Lackmann GmbH & Co KG +OUI:34885D* + ID_OUI_FROM_DATABASE=Logitech Far East + OUI:3495DB* ID_OUI_FROM_DATABASE=Logitec Corporation @@ -54769,6 +54901,9 @@ OUI:34D2C4* OUI:34D7B4* ID_OUI_FROM_DATABASE=Tributary Systems, Inc. +OUI:34DBFD* + ID_OUI_FROM_DATABASE=Cisco + OUI:34DF2A* ID_OUI_FROM_DATABASE=Fujikon Industrial Co.,Limited @@ -55402,6 +55537,9 @@ OUI:40704A* OUI:407074* ID_OUI_FROM_DATABASE=Life Technology (China) Co., Ltd +OUI:407A80* + ID_OUI_FROM_DATABASE=Nokia Corporation + OUI:407B1B* ID_OUI_FROM_DATABASE=Mettle Networks Inc. @@ -56056,6 +56194,9 @@ OUI:4C55CC* OUI:4C5DCD* ID_OUI_FROM_DATABASE=Oy Finnish Electric Vehicle Technologies Ltd +OUI:4C5E0C* + ID_OUI_FROM_DATABASE=Routerboard.com + OUI:4C5FD2* ID_OUI_FROM_DATABASE=Alcatel-Lucent @@ -56377,6 +56518,9 @@ OUI:50B888* OUI:50B8A2* ID_OUI_FROM_DATABASE=ImTech Technologies LLC, +OUI:50C271* + ID_OUI_FROM_DATABASE=SECURETECH INC + OUI:50C58D* ID_OUI_FROM_DATABASE=Juniper Networks @@ -56611,6 +56755,9 @@ OUI:54E63F* OUI:54E6FC* ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD. +OUI:54EAA8* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:54F5B6* ID_OUI_FROM_DATABASE=ORIENTAL PACIFIC INTERNATIONAL LIMITED @@ -56791,6 +56938,9 @@ OUI:58B035* OUI:58B0D4* ID_OUI_FROM_DATABASE=ZuniData Systems Inc. +OUI:58B961* + ID_OUI_FROM_DATABASE=SOLEM Electronique + OUI:58B9E1* ID_OUI_FROM_DATABASE=Crystalfontz America, Inc. @@ -56800,6 +56950,9 @@ OUI:58BC27* OUI:58BDA3* ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. +OUI:58BDF9* + ID_OUI_FROM_DATABASE=Sigrand + OUI:58BFEA* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. @@ -57049,6 +57202,9 @@ OUI:5CD41B* OUI:5CD4AB* ID_OUI_FROM_DATABASE=Zektor +OUI:5CD61F* + ID_OUI_FROM_DATABASE=Qardio, Inc + OUI:5CD998* ID_OUI_FROM_DATABASE=D-Link Corporation @@ -57193,6 +57349,9 @@ OUI:60601F* OUI:6063FD* ID_OUI_FROM_DATABASE=Transcend Communication Beijing Co.,Ltd. +OUI:6064A1* + ID_OUI_FROM_DATABASE=RADiflow Ltd. + OUI:606720* ID_OUI_FROM_DATABASE=Intel Corporate @@ -57284,7 +57443,7 @@ OUI:60BD91* ID_OUI_FROM_DATABASE=Move Innovation OUI:60C397* - ID_OUI_FROM_DATABASE=2 Wire Inc + ID_OUI_FROM_DATABASE=2Wire Inc OUI:60C547* ID_OUI_FROM_DATABASE=Apple, Inc. @@ -57433,6 +57592,9 @@ OUI:64317E* OUI:643409* ID_OUI_FROM_DATABASE=BITwave Pte Ltd +OUI:644214* + ID_OUI_FROM_DATABASE=Swisscom Energy Solutions AG + OUI:644346* ID_OUI_FROM_DATABASE=GuangDong Quick Network Computer CO.,LTD @@ -57709,6 +57871,9 @@ OUI:681605* OUI:681729* ID_OUI_FROM_DATABASE=Intel Corporate +OUI:68193F* + ID_OUI_FROM_DATABASE=Digital Airways + OUI:681AB2* ID_OUI_FROM_DATABASE=zte corporation @@ -57727,6 +57892,9 @@ OUI:681FD8* OUI:68234B* ID_OUI_FROM_DATABASE=Nihon Dengyo Kousaku +OUI:682DDC* + ID_OUI_FROM_DATABASE=Wuhan Changjiang Electro-Communication Equipment CO.,LTD + OUI:683B1E* ID_OUI_FROM_DATABASE=Countwise LTD @@ -58030,6 +58198,9 @@ OUI:6C81FE* OUI:6C8336* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +OUI:6C8366* + ID_OUI_FROM_DATABASE=Nanjing SAC Power Grid Automation Co., Ltd. + OUI:6C8686* ID_OUI_FROM_DATABASE=Technonia @@ -58267,6 +58438,9 @@ OUI:705681* OUI:705812* ID_OUI_FROM_DATABASE=Panasonic AVC Networks Company +OUI:705957* + ID_OUI_FROM_DATABASE=Medallion Instrumentation Systems + OUI:705AB6* ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD. @@ -58276,6 +58450,9 @@ OUI:705CAD* OUI:705EAA* ID_OUI_FROM_DATABASE=Action Target, Inc. +OUI:706173* + ID_OUI_FROM_DATABASE=Calantec GmbH + OUI:706417* ID_OUI_FROM_DATABASE=ORBIS TECNOLOGIA ELECTRICA S.A. @@ -58447,6 +58624,9 @@ OUI:70F927* OUI:740ABC* ID_OUI_FROM_DATABASE=JSJS Designs (Europe) Limited +OUI:740EDB* + ID_OUI_FROM_DATABASE=Optowiz Co., Ltd + OUI:741489* ID_OUI_FROM_DATABASE=SRT Wireless @@ -58468,6 +58648,9 @@ OUI:7427EA* OUI:742B0F* ID_OUI_FROM_DATABASE=Infinidat Ltd. +OUI:742B62* + ID_OUI_FROM_DATABASE=Fujitsu Limited + OUI:742D0A* ID_OUI_FROM_DATABASE=Norfolk Elektronik AG @@ -58585,6 +58768,9 @@ OUI:749DDC* OUI:74A4A7* ID_OUI_FROM_DATABASE=QRS Music Technologies, Inc. +OUI:74A4B5* + ID_OUI_FROM_DATABASE=Powerleader Science and Technology Co. Ltd. + OUI:74A722* ID_OUI_FROM_DATABASE=LG Electronics @@ -58624,6 +58810,9 @@ OUI:74D02B* OUI:74D0DC* ID_OUI_FROM_DATABASE=ERICSSON AB +OUI:74D435* + ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD. + OUI:74D675* ID_OUI_FROM_DATABASE=WYMA Tecnologia @@ -58765,6 +58954,9 @@ OUI:7846C4* OUI:78471D* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +OUI:78491D* + ID_OUI_FROM_DATABASE=The Will-Burt Company + OUI:784B08* ID_OUI_FROM_DATABASE=f.robotics acquisitions ltd @@ -59080,6 +59272,9 @@ OUI:7C3E9D* OUI:7C438F* ID_OUI_FROM_DATABASE=E-Band Communications Corp. +OUI:7C49B9* + ID_OUI_FROM_DATABASE=Plexus Manufacturing Sdn Bhd + OUI:7C4A82* ID_OUI_FROM_DATABASE=Portsmith LLC @@ -59191,12 +59386,18 @@ OUI:7CB232* OUI:7CB542* ID_OUI_FROM_DATABASE=ACES Technology +OUI:7CB733* + ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP + OUI:7CB77B* ID_OUI_FROM_DATABASE=Paradigm Electronics Inc OUI:7CBB6F* ID_OUI_FROM_DATABASE=Cosco Electronics Co., Ltd. +OUI:7CBD06* + ID_OUI_FROM_DATABASE=AE REFUsol + OUI:7CBFB1* ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. @@ -59398,6 +59599,9 @@ OUI:80711F* OUI:807693* ID_OUI_FROM_DATABASE=Newag SA +OUI:8079AE* + ID_OUI_FROM_DATABASE=ShanDong Tecsunrise Co.,Ltd + OUI:807A7F* ID_OUI_FROM_DATABASE=ABB Genway Xiamen Electrical Equipment CO., LTD @@ -59455,6 +59659,9 @@ OUI:80A1D7* OUI:80AAA4* ID_OUI_FROM_DATABASE=USAG +OUI:80B219* + ID_OUI_FROM_DATABASE=ELEKTRON TECHNOLOGY UK LIMITED + OUI:80B289* ID_OUI_FROM_DATABASE=Forworld Electronics Ltd. @@ -59560,6 +59767,9 @@ OUI:84253F* OUI:8425DB* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +OUI:84262B* + ID_OUI_FROM_DATABASE=Alcatel-Lucent + OUI:8427CE* ID_OUI_FROM_DATABASE=Corporation of the Presiding Bishop of The Church of Jesus Christ of Latter-day Saints @@ -59830,6 +60040,12 @@ OUI:885395* OUI:8853D4* ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd +OUI:88576D* + ID_OUI_FROM_DATABASE=XTA Electronics Ltd + +OUI:885A92* + ID_OUI_FROM_DATABASE=Cisco + OUI:885C4F* ID_OUI_FROM_DATABASE=Alcatel Lucent @@ -60160,6 +60376,9 @@ OUI:8CC7D0* OUI:8CC8CD* ID_OUI_FROM_DATABASE=Samsung Electronics Co., LTD +OUI:8CCDA2* + ID_OUI_FROM_DATABASE=ACTP, Inc. + OUI:8CCDE8* ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. @@ -60250,6 +60469,9 @@ OUI:901D27* OUI:901EDD* ID_OUI_FROM_DATABASE=GREAT COMPUTER CORPORATION +OUI:902083* + ID_OUI_FROM_DATABASE=General Engine Management Systems Ltd. + OUI:902155* ID_OUI_FROM_DATABASE=HTC Corporation @@ -60328,6 +60550,9 @@ OUI:905F8D* OUI:90610C* ID_OUI_FROM_DATABASE=Fida International (S) Pte Ltd +OUI:906717* + ID_OUI_FROM_DATABASE=Alphion India Private Limited + OUI:9067B5* ID_OUI_FROM_DATABASE=Alcatel-Lucent @@ -60346,6 +60571,9 @@ OUI:907025* OUI:907240* ID_OUI_FROM_DATABASE=Apple +OUI:907990* + ID_OUI_FROM_DATABASE=Benchmark Electronics Romania SRL + OUI:907A0A* ID_OUI_FROM_DATABASE=Gebr. Bode GmbH & Co KG @@ -60367,6 +60595,9 @@ OUI:90840D* OUI:9088A2* ID_OUI_FROM_DATABASE=IONICS TECHNOLOGY ME LTDA +OUI:908C44* + ID_OUI_FROM_DATABASE=H.K ZONGMU TECHNOLOGY CO., LTD. + OUI:908D1D* ID_OUI_FROM_DATABASE=GH Technologies @@ -60385,9 +60616,15 @@ OUI:9092B4* OUI:9094E4* ID_OUI_FROM_DATABASE=D-Link International +OUI:909916* + ID_OUI_FROM_DATABASE=ELVEES NeoTek OJSC + OUI:909DE0* ID_OUI_FROM_DATABASE=Newland Design + Assoc. Inc. +OUI:909F43* + ID_OUI_FROM_DATABASE=Accutron Instruments Inc. + OUI:90A2DA* ID_OUI_FROM_DATABASE=GHEO SA @@ -60499,6 +60736,9 @@ OUI:940BD5* OUI:940C6D* ID_OUI_FROM_DATABASE=TP-LINK Technologies Co.,Ltd. +OUI:94103E* + ID_OUI_FROM_DATABASE=Belkin International Inc. + OUI:9411DA* ID_OUI_FROM_DATABASE=ITF Fröschl GmbH @@ -60634,6 +60874,9 @@ OUI:94B8C5* OUI:94BA31* ID_OUI_FROM_DATABASE=Visiontec da Amazônia Ltda. +OUI:94BA56* + ID_OUI_FROM_DATABASE=Shenzhen Coship Electronics Co., Ltd. + OUI:94BF1E* ID_OUI_FROM_DATABASE=eflow Inc. / Smart Device Planning and Development Division @@ -60835,6 +61078,9 @@ OUI:986022* OUI:9866EA* ID_OUI_FROM_DATABASE=Industrial Control Communications, Inc. +OUI:986CF5* + ID_OUI_FROM_DATABASE=zte corporation + OUI:986DC8* ID_OUI_FROM_DATABASE=TOSHIBA MITSUBISHI-ELECTRIC INDUSTRIAL SYSTEMS CORPORATION @@ -61003,6 +61249,9 @@ OUI:9C3AAF* OUI:9C417C* ID_OUI_FROM_DATABASE=Hame Technology Co., Limited +OUI:9C443D* + ID_OUI_FROM_DATABASE=CHENGDU XUGUANG TECHNOLOGY CO, LTD + OUI:9C4563* ID_OUI_FROM_DATABASE=DIMEP Sistemas @@ -61132,12 +61381,18 @@ OUI:9CB008* OUI:9CB206* ID_OUI_FROM_DATABASE=PROCENTEC +OUI:9CB654* + ID_OUI_FROM_DATABASE=Hewlett Packard + OUI:9CB70D* ID_OUI_FROM_DATABASE=Liteon Technology Corporation OUI:9CB793* ID_OUI_FROM_DATABASE=Creatcomm Technology Inc. +OUI:9CBB98* + ID_OUI_FROM_DATABASE=Shen Zhen RND Electronic Co.,LTD + OUI:9CC077* ID_OUI_FROM_DATABASE=PrintCounts, LLC @@ -61189,6 +61444,9 @@ OUI:9CF61A* OUI:9CF67D* ID_OUI_FROM_DATABASE=Ricardo Prague, s.r.o. +OUI:9CF8DB* + ID_OUI_FROM_DATABASE=shenzhen eyunmei technology co,.ltd + OUI:9CF938* ID_OUI_FROM_DATABASE=AREVA NP GmbH @@ -61219,8 +61477,11 @@ OUI:A01290* OUI:A0133B* ID_OUI_FROM_DATABASE=Copyright © HiTi Digital, Inc. +OUI:A0143D* + ID_OUI_FROM_DATABASE=PARROT SA + OUI:A0165C* - ID_OUI_FROM_DATABASE=TangoTec Ltd. + ID_OUI_FROM_DATABASE=Triteka LTD OUI:A01859* ID_OUI_FROM_DATABASE=Shenzhen Yidashi Electronics Co Ltd @@ -61618,6 +61879,9 @@ OUI:A49B13* OUI:A49EDB* ID_OUI_FROM_DATABASE=AutoCrib, Inc. +OUI:A49F89* + ID_OUI_FROM_DATABASE=Shanghai Rui Rui Communication Technology Co.Ltd. + OUI:A4A24A* ID_OUI_FROM_DATABASE=Cisco SPVTG @@ -61846,6 +62110,9 @@ OUI:A87B39* OUI:A87E33* ID_OUI_FROM_DATABASE=Nokia Danmark A/S +OUI:A886DD* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:A88792* ID_OUI_FROM_DATABASE=Broadband Antenna Tracking Systems @@ -62050,6 +62317,9 @@ OUI:AC4E91* OUI:AC4FFC* ID_OUI_FROM_DATABASE=SVS-VISTEK GmbH +OUI:AC5036* + ID_OUI_FROM_DATABASE=Pi-Coral Inc + OUI:AC5135* ID_OUI_FROM_DATABASE=MPI TECH @@ -62578,12 +62848,18 @@ OUI:B46238* OUI:B46293* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +OUI:B462AD* + ID_OUI_FROM_DATABASE=raytest GmbH + OUI:B467E9* ID_OUI_FROM_DATABASE=Qingdao GoerTek Technology Co., Ltd. OUI:B4749F* ID_OUI_FROM_DATABASE=askey computer corp +OUI:B4750E* + ID_OUI_FROM_DATABASE=Belkin International Inc. + OUI:B47F5E* ID_OUI_FROM_DATABASE=Foresight Manufacture (S) Pte Ltd @@ -63085,6 +63361,9 @@ OUI:BC3BAF* OUI:BC3E13* ID_OUI_FROM_DATABASE=Accordance Systems Inc. +OUI:BC4100* + ID_OUI_FROM_DATABASE=Codaco Electronic s.r.o. + OUI:BC4377* ID_OUI_FROM_DATABASE=Hang Zhou Huite Technology Co.,ltd. @@ -63280,6 +63559,9 @@ OUI:C01E9B* OUI:C02506* ID_OUI_FROM_DATABASE=AVM GmbH +OUI:C0255C* + ID_OUI_FROM_DATABASE=Cisco + OUI:C027B9* ID_OUI_FROM_DATABASE=Beijing National Railway Research & Design Institute of Signal & Communication Co., Ltd. @@ -63298,6 +63580,9 @@ OUI:C02C7A* OUI:C034B4* ID_OUI_FROM_DATABASE=Gigastone Corporation +OUI:C03580* + ID_OUI_FROM_DATABASE=A&R TECH + OUI:C035BD* ID_OUI_FROM_DATABASE=Velocytech Aps @@ -63532,6 +63817,9 @@ OUI:C4242E* OUI:C42628* ID_OUI_FROM_DATABASE=Airo Wireless +OUI:C42795* + ID_OUI_FROM_DATABASE=Technicolor USA Inc. + OUI:C42C03* ID_OUI_FROM_DATABASE=Apple, Inc. @@ -63694,6 +63982,9 @@ OUI:C4CD45* OUI:C4D489* ID_OUI_FROM_DATABASE=JiangSu Joyque Information Industry Co.,Ltd +OUI:C4D655* + ID_OUI_FROM_DATABASE=Tercel technology co.,ltd + OUI:C4D987* ID_OUI_FROM_DATABASE=Intel Corporate @@ -64027,6 +64318,9 @@ OUI:CC04B4* OUI:CC051B* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +OUI:CC07AB* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:CC08E0* ID_OUI_FROM_DATABASE=Apple, Inc. @@ -64144,6 +64438,9 @@ OUI:CC6DA0* OUI:CC6DEF* ID_OUI_FROM_DATABASE=TJK Tietolaite Oy +OUI:CC720F* + ID_OUI_FROM_DATABASE=Viscount Systems Inc. + OUI:CC7669* ID_OUI_FROM_DATABASE=SEETECH @@ -64405,6 +64702,9 @@ OUI:D07E28* OUI:D08999* ID_OUI_FROM_DATABASE=APCON, Inc. +OUI:D08A55* + ID_OUI_FROM_DATABASE=Skullcandy + OUI:D08B7E* ID_OUI_FROM_DATABASE=Passif Semiconductor @@ -64912,6 +65212,9 @@ OUI:D8490B* OUI:D84B2A* ID_OUI_FROM_DATABASE=Cognitas Technologies, Inc. +OUI:D850E6* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + OUI:D8543A* ID_OUI_FROM_DATABASE=Texas Instruments @@ -64969,6 +65272,9 @@ OUI:D8952F* OUI:D89685* ID_OUI_FROM_DATABASE=GoPro +OUI:D89695* + ID_OUI_FROM_DATABASE=Apple, Inc + OUI:D8973B* ID_OUI_FROM_DATABASE=Emerson Network Power Embedded Power @@ -65164,6 +65470,9 @@ OUI:DC3C84* OUI:DC3E51* ID_OUI_FROM_DATABASE=Solberg & Andersen AS +OUI:DC3EF8* + ID_OUI_FROM_DATABASE=Nokia Corporation + OUI:DC4517* ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. @@ -65875,6 +66184,9 @@ OUI:E8481F* OUI:E84E06* ID_OUI_FROM_DATABASE=EDUP INTERNATIONAL (HK) CO., LTD +OUI:E84E84* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:E84ECE* ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. @@ -65902,6 +66214,9 @@ OUI:E85BF0* OUI:E85E53* ID_OUI_FROM_DATABASE=Infratec Datentechnik GmbH +OUI:E8611F* + ID_OUI_FROM_DATABASE=Dawning Information Industry Co.,Ltd + OUI:E86CDA* ID_OUI_FROM_DATABASE=Supercomputers and Neurocomputers Research Center @@ -66052,6 +66367,9 @@ OUI:E8E875* OUI:E8EADA* ID_OUI_FROM_DATABASE=Denkovi Assembly Electroncs LTD +OUI:E8EDF3* + ID_OUI_FROM_DATABASE=Cisco + OUI:E8F1B0* ID_OUI_FROM_DATABASE=SAGEMCOM SAS @@ -66658,6 +66976,9 @@ OUI:F4600D* OUI:F46349* ID_OUI_FROM_DATABASE=Diffon Corporation +OUI:F46ABC* + ID_OUI_FROM_DATABASE=Adonit Corp. Ltd. + OUI:F46D04* ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. @@ -66859,6 +67180,9 @@ OUI:F83553* OUI:F835DD* ID_OUI_FROM_DATABASE=Gemtek Technology Co., Ltd. +OUI:F83D4E* + ID_OUI_FROM_DATABASE=Softlink Automation System Co., Ltd + OUI:F83DFF* ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd @@ -67030,6 +67354,9 @@ OUI:F8DB4C* OUI:F8DB7F* ID_OUI_FROM_DATABASE=HTC Corporation +OUI:F8DB88* + ID_OUI_FROM_DATABASE=Dell Inc PCBA Test + OUI:F8DC7A* ID_OUI_FROM_DATABASE=Variscite LTD @@ -67111,6 +67438,9 @@ OUI:FC1186* OUI:FC1794* ID_OUI_FROM_DATABASE=InterCreative Co., Ltd +OUI:FC1BFF* + ID_OUI_FROM_DATABASE=V-ZUG AG + OUI:FC1D59* ID_OUI_FROM_DATABASE=I Smart Cities HK Ltd @@ -67243,6 +67573,9 @@ OUI:FCAD0F* OUI:FCAF6A* ID_OUI_FROM_DATABASE=Conemtech AB +OUI:FCB0C4* + ID_OUI_FROM_DATABASE=Shanghai DareGlobal Technologies Co., Ltd + OUI:FCC23D* ID_OUI_FROM_DATABASE=Atmel Corporation @@ -67267,6 +67600,9 @@ OUI:FCD4F6* OUI:FCD6BD* ID_OUI_FROM_DATABASE=Robert Bosch GmbH +OUI:FCD817* + ID_OUI_FROM_DATABASE=Beijing Hesun Technologies Co.Ltd. + OUI:FCDB96* ID_OUI_FROM_DATABASE=ENERVALLEY CO., LTD diff --git a/hwdb/20-pci-vendor-model.hwdb b/hwdb/20-pci-vendor-model.hwdb index 2436a29e9a..c9830f5bbd 100644 --- a/hwdb/20-pci-vendor-model.hwdb +++ b/hwdb/20-pci-vendor-model.hwdb @@ -1986,7 +1986,7 @@ pci:v00001002d00004370sv00001462sd00000131* ID_MODEL_FROM_DATABASE=MS-1013 Notebook pci:v00001002d00004371* - ID_MODEL_FROM_DATABASE=IXP SB400 PCI-PCI Bridge + ID_MODEL_FROM_DATABASE=IXP SB4x0 PCI-PCI Bridge pci:v00001002d00004371sv0000103Csd0000308B* ID_MODEL_FROM_DATABASE=MX6125 @@ -1995,7 +1995,7 @@ pci:v00001002d00004371sv00001462sd00007217* ID_MODEL_FROM_DATABASE=Aspire L250 pci:v00001002d00004372* - ID_MODEL_FROM_DATABASE=IXP SB400 SMBus Controller + ID_MODEL_FROM_DATABASE=IXP SB4x0 SMBus Controller pci:v00001002d00004372sv00001025sd00000080* ID_MODEL_FROM_DATABASE=Aspire 5024WLMMi @@ -2013,7 +2013,7 @@ pci:v00001002d00004372sv00001462sd00007217* ID_MODEL_FROM_DATABASE=Aspire L250 pci:v00001002d00004373* - ID_MODEL_FROM_DATABASE=IXP SB400 USB2 Host Controller + ID_MODEL_FROM_DATABASE=IXP SB4x0 USB2 Host Controller pci:v00001002d00004373sv00001025sd00000080* ID_MODEL_FROM_DATABASE=Aspire 5024WLMMi @@ -2028,7 +2028,7 @@ pci:v00001002d00004373sv00001462sd00007217* ID_MODEL_FROM_DATABASE=Aspire L250 pci:v00001002d00004374* - ID_MODEL_FROM_DATABASE=IXP SB400 USB Host Controller + ID_MODEL_FROM_DATABASE=IXP SB4x0 USB Host Controller pci:v00001002d00004374sv0000103Csd00002A20* ID_MODEL_FROM_DATABASE=Pavilion t3030.de Desktop PC @@ -2040,7 +2040,7 @@ pci:v00001002d00004374sv00001462sd00007217* ID_MODEL_FROM_DATABASE=Aspire L250 pci:v00001002d00004375* - ID_MODEL_FROM_DATABASE=IXP SB400 USB Host Controller + ID_MODEL_FROM_DATABASE=IXP SB4x0 USB Host Controller pci:v00001002d00004375sv00001025sd00000080* ID_MODEL_FROM_DATABASE=Aspire 5024WLMMi @@ -2055,7 +2055,7 @@ pci:v00001002d00004375sv00001462sd00007217* ID_MODEL_FROM_DATABASE=Aspire L250 pci:v00001002d00004376* - ID_MODEL_FROM_DATABASE=IXP SB400 IDE Controller + ID_MODEL_FROM_DATABASE=IXP SB4x0 IDE Controller pci:v00001002d00004376sv00001025sd00000080* ID_MODEL_FROM_DATABASE=Aspire 5024WLMMi @@ -2073,7 +2073,7 @@ pci:v00001002d00004376sv00001462sd00007217* ID_MODEL_FROM_DATABASE=Aspire L250 pci:v00001002d00004377* - ID_MODEL_FROM_DATABASE=IXP SB400 PCI-ISA Bridge + ID_MODEL_FROM_DATABASE=IXP SB4x0 PCI-ISA Bridge pci:v00001002d00004377sv00001025sd00000080* ID_MODEL_FROM_DATABASE=Aspire 5024WLMi @@ -2100,7 +2100,7 @@ pci:v00001002d00004378sv00001462sd00000131* ID_MODEL_FROM_DATABASE=MS-1013 Notebook pci:v00001002d00004379* - ID_MODEL_FROM_DATABASE=IXP SB400 Serial ATA Controller + ID_MODEL_FROM_DATABASE=IXP SB4x0 Serial ATA Controller pci:v00001002d00004379sv00001462sd00007141* ID_MODEL_FROM_DATABASE=Aspire L250 @@ -2154,7 +2154,7 @@ pci:v00001002d00004380sv000017F2sd00005999* ID_MODEL_FROM_DATABASE=KI690-AM2 Motherboard pci:v00001002d00004381* - ID_MODEL_FROM_DATABASE=SB400 SATA Controller (RAID 5 mode) + ID_MODEL_FROM_DATABASE=SB600 SATA Controller (RAID 5 mode) pci:v00001002d00004382* ID_MODEL_FROM_DATABASE=SB600 AC97 Audio @@ -3927,25 +3927,25 @@ pci:v00001002d00005A31* ID_MODEL_FROM_DATABASE=RC410 Host Bridge pci:v00001002d00005A33* - ID_MODEL_FROM_DATABASE=Radeon Xpress 200 Host Bridge + ID_MODEL_FROM_DATABASE=RS400 Host Bridge pci:v00001002d00005A34* - ID_MODEL_FROM_DATABASE=RS480 PCI-X Root Port + ID_MODEL_FROM_DATABASE=RS4xx PCI Express Port [ext gfx] pci:v00001002d00005A36* - ID_MODEL_FROM_DATABASE=RS480 PCI Bridge + ID_MODEL_FROM_DATABASE=RC4xx/RS4xx PCI Express Port 1 pci:v00001002d00005A37* - ID_MODEL_FROM_DATABASE=RS480 PCI Bridge + ID_MODEL_FROM_DATABASE=RC4xx/RS4xx PCI Express Port 2 pci:v00001002d00005A38* - ID_MODEL_FROM_DATABASE=RS480 PCI Bridge + ID_MODEL_FROM_DATABASE=RC4xx/RS4xx PCI Express Port 3 pci:v00001002d00005A39* - ID_MODEL_FROM_DATABASE=RS480 PCI Bridge + ID_MODEL_FROM_DATABASE=RC4xx/RS4xx PCI Express Port 4 pci:v00001002d00005A3F* - ID_MODEL_FROM_DATABASE=RS480 PCI Bridge + ID_MODEL_FROM_DATABASE=RC4xx/RS4xx PCI Bridge [int gfx] pci:v00001002d00005A3Fsv00001462sd00007217* ID_MODEL_FROM_DATABASE=Aspire L250 @@ -19299,7 +19299,7 @@ pci:v000010B9d00001689* ID_MODEL_FROM_DATABASE=M1689 K8 Northbridge [Super K8 Single Chip] pci:v000010B9d00001695* - ID_MODEL_FROM_DATABASE=M1695 K8 Northbridge [PCI Express and HyperTransport] + ID_MODEL_FROM_DATABASE=M1695 Host Bridge pci:v000010B9d00001697* ID_MODEL_FROM_DATABASE=M1697 HTT Host Bridge @@ -25328,6 +25328,9 @@ pci:v000010DEd00000FC6* pci:v000010DEd00000FC6sv00001043sd00008428* ID_MODEL_FROM_DATABASE=GTX650-DC-1GD5 +pci:v000010DEd00000FCD* + ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 755M] + pci:v000010DEd00000FD1* ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 650M] @@ -25398,7 +25401,7 @@ pci:v000010DEd00000FE6* ID_MODEL_FROM_DATABASE=GK107 [NVS K1 USM] pci:v000010DEd00000FE7* - ID_MODEL_FROM_DATABASE=GRID K1 vGPU + ID_MODEL_FROM_DATABASE=GK107GL [GRID K1] pci:v000010DEd00000FE7sv000010DEsd0000101E* ID_MODEL_FROM_DATABASE=GRID K100 @@ -25421,6 +25424,9 @@ pci:v000010DEd00000FF7* pci:v000010DEd00000FF7sv000010DEsd00001037* ID_MODEL_FROM_DATABASE=GRID K140Q +pci:v000010DEd00000FF8* + ID_MODEL_FROM_DATABASE=GK107GLM [Quadro K500M] + pci:v000010DEd00000FF9* ID_MODEL_FROM_DATABASE=GK107GL [Quadro K2000D] @@ -25859,6 +25865,9 @@ pci:v000010DEd00001140sv00001043sd0000220A* pci:v000010DEd00001140sv00001043sd0000221A* ID_MODEL_FROM_DATABASE=GeForce GT 720M +pci:v000010DEd00001140sv00001043sd00008595* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + pci:v000010DEd00001140sv00001179sd0000FA01* ID_MODEL_FROM_DATABASE=GeForce 710M @@ -25931,6 +25940,9 @@ pci:v000010DEd00001140sv00001179sd0000FA88* pci:v000010DEd00001140sv00001179sd0000FA89* ID_MODEL_FROM_DATABASE=GeForce 710M +pci:v000010DEd00001140sv0000144Dsd0000B092* + ID_MODEL_FROM_DATABASE=GeForce GT 620M + pci:v000010DEd00001140sv0000144Dsd0000C0D5* ID_MODEL_FROM_DATABASE=GeForce GT 630M @@ -25961,6 +25973,12 @@ pci:v000010DEd00001140sv00001462sd000010B8* pci:v000010DEd00001140sv00001462sd000010E9* ID_MODEL_FROM_DATABASE=GeForce GT 720M +pci:v000010DEd00001140sv00001462sd0000AA33* + ID_MODEL_FROM_DATABASE=GeForce 720M + +pci:v000010DEd00001140sv00001462sd0000AAA2* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + pci:v000010DEd00001140sv0000152Dsd00000926* ID_MODEL_FROM_DATABASE=GeForce 620M @@ -26094,7 +26112,7 @@ pci:v000010DEd0000118C* ID_MODEL_FROM_DATABASE=GK104 [NVS K2 USM] pci:v000010DEd0000118D* - ID_MODEL_FROM_DATABASE=GRID K2 vGPU + ID_MODEL_FROM_DATABASE=GK104GL [GRID K2] pci:v000010DEd0000118Dsv000010DEsd0000101D* ID_MODEL_FROM_DATABASE=GRID K200 @@ -26138,6 +26156,9 @@ pci:v000010DEd000011B0sv000010DEsd0000101B* pci:v000010DEd000011B1* ID_MODEL_FROM_DATABASE=GK104GL [Tesla K2 USM] +pci:v000010DEd000011B7* + ID_MODEL_FROM_DATABASE=GK104GLM [Quadro K4100M] + pci:v000010DEd000011BA* ID_MODEL_FROM_DATABASE=GK104GL [Quadro K5000] @@ -26207,6 +26228,9 @@ pci:v000010DEd000011E3* pci:v000010DEd000011FA* ID_MODEL_FROM_DATABASE=GK106GL [Quadro K4000] +pci:v000010DEd000011FC* + ID_MODEL_FROM_DATABASE=GK106GLM [Quadro K2100M] + pci:v000010DEd00001200* ID_MODEL_FROM_DATABASE=GF114 [GeForce GTX 560 Ti] @@ -26330,9 +26354,15 @@ pci:v000010DEd00001293* pci:v000010DEd00001294* ID_MODEL_FROM_DATABASE=GK208M [GeForce GT 740M] +pci:v000010DEd00001295* + ID_MODEL_FROM_DATABASE=GK208M [GeForce 710M] + pci:v000010DEd000012A0* ID_MODEL_FROM_DATABASE=GK208 +pci:v000010DEd000012BA* + ID_MODEL_FROM_DATABASE=GK208GLM [Quadro K510M] + pci:v000010DF* ID_VENDOR_FROM_DATABASE=Emulex Corporation @@ -26799,7 +26829,7 @@ pci:v000010ECd00008129sv000010ECsd00008129* ID_MODEL_FROM_DATABASE=RT8129 Fast Ethernet Adapter pci:v000010ECd00008129sv000011ECsd00008129* - ID_MODEL_FROM_DATABASE=RT8129 Fast Ethernet Adapter + ID_MODEL_FROM_DATABASE=RTL8111/8168 PCIe Gigabit Ethernet (misconfigured) pci:v000010ECd00008136* ID_MODEL_FROM_DATABASE=RTL8101E/RTL8102E PCI Express Fast Ethernet controller @@ -46364,6 +46394,15 @@ pci:v00001619d00004620* pci:v00001619d00004640* ID_MODEL_FROM_DATABASE=FarSync T4Ue PCI Express (4-port X.21/V.35/V.24) +pci:v00001619d00005621* + ID_MODEL_FROM_DATABASE=FarSync T2Ee PCI Express (2 port X.21/V.35/V.24) + +pci:v00001619d00005641* + ID_MODEL_FROM_DATABASE=FarSync T4Ee PCI Express (4 port X.21/V.35/V.24) + +pci:v00001619d00006620* + ID_MODEL_FROM_DATABASE=FarSync T2U-PMC PCI Express (2 port X.21/V.35/V.24) + pci:v0000161F* ID_VENDOR_FROM_DATABASE=Rioworks @@ -46463,6 +46502,9 @@ pci:v00001657d00000022sv00001657sd00000023* pci:v00001657d00000022sv00001657sd00000024* ID_MODEL_FROM_DATABASE=16Gbps FC HBA +pci:v00001657d00000023* + ID_MODEL_FROM_DATABASE=1869 16Gbps FC HBA + pci:v00001657d00000646* ID_MODEL_FROM_DATABASE=400 4Gbps PCIe FC HBA @@ -52559,6 +52601,18 @@ pci:v00006666d00004000* pci:v00006688* ID_VENDOR_FROM_DATABASE=Zycoo Co., Ltd +pci:v00006688d00001200* + ID_MODEL_FROM_DATABASE=CooVOX TDM Analog Module + +pci:v00006688d00001400* + ID_MODEL_FROM_DATABASE=CooVOX TDM GSM Module + +pci:v00006688d00001600* + ID_MODEL_FROM_DATABASE=CooVOX TDM E1/T1 Module + +pci:v00006688d00001800* + ID_MODEL_FROM_DATABASE=CooVOX TDM BRI Module + pci:v00006900* ID_VENDOR_FROM_DATABASE=Red Hat, Inc. @@ -56792,6 +56846,15 @@ pci:v00008086d00001557* pci:v00008086d00001557sv00008086sd00000001* ID_MODEL_FROM_DATABASE=Ethernet OCP Server Adapter X520-1 +pci:v00008086d00001558* + ID_MODEL_FROM_DATABASE=Ethernet Converged Network Adapter X520-Q1 + +pci:v00008086d00001558sv00008086sd0000011A* + ID_MODEL_FROM_DATABASE=Ethernet Converged Network Adapter X520-Q1 + +pci:v00008086d00001558sv00008086sd0000011B* + ID_MODEL_FROM_DATABASE=Ethernet Converged Network Adapter X520-Q1 + pci:v00008086d00001559* ID_MODEL_FROM_DATABASE=Ethernet Connection I218-V @@ -56811,7 +56874,7 @@ pci:v00008086d0000155Dsv00008086sd00000001* ID_MODEL_FROM_DATABASE=Ethernet Server Bypass Adapter X520-SR2 pci:v00008086d00001560* - ID_MODEL_FROM_DATABASE=Ethernet Controller X540-AT1 + ID_MODEL_FROM_DATABASE=Ethernet Controller X540 pci:v00008086d0000157B* ID_MODEL_FROM_DATABASE=I210 Gigabit Network Connection @@ -57942,22 +58005,19 @@ pci:v00008086d00001F3F* ID_MODEL_FROM_DATABASE=Avoton RAID SATA3 Controller pci:v00008086d00001F40* - ID_MODEL_FROM_DATABASE=Avoton GbE x4 1000base-KX + ID_MODEL_FROM_DATABASE=Ethernet Connection I354 1.0 GbE Backplane pci:v00008086d00001F41* - ID_MODEL_FROM_DATABASE=Avoton GbE x4 SGMII + ID_MODEL_FROM_DATABASE=Ethernet Connection I354 pci:v00008086d00001F42* ID_MODEL_FROM_DATABASE=Avoton GbE -pci:v00008086d00001F43* - ID_MODEL_FROM_DATABASE=Avoton GbE EEPROM-less - pci:v00008086d00001F44* ID_MODEL_FROM_DATABASE=Avoton GbE Virtual Function pci:v00008086d00001F45* - ID_MODEL_FROM_DATABASE=Avoton GbE 2500base-KX + ID_MODEL_FROM_DATABASE=Ethernet Connection I354 2.5 GbE Backplane pci:v00008086d00002250* ID_MODEL_FROM_DATABASE=Xeon Phi coprocessor 5100 series -- cgit v1.2.1 From 68eda4bd168306f51c90e5d22824c494d709289e Mon Sep 17 00:00:00 2001 From: Ronny Chevalier Date: Thu, 25 Jul 2013 17:36:01 +0200 Subject: dbus: use _cleanup_free_ instead of freeing ourself --- src/core/dbus-execute.c | 3 +-- src/core/dbus-job.c | 11 ++--------- src/core/dbus-manager.c | 14 +++----------- src/core/unit.c | 36 ++++++++++++++---------------------- 4 files changed, 20 insertions(+), 44 deletions(-) diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index 73590c82be..2402e8c34d 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -77,12 +77,11 @@ static int bus_execute_append_oom_score_adjust(DBusMessageIter *i, const char *p if (c->oom_score_adjust_set) n = c->oom_score_adjust; else { - char *t; + _cleanup_free_ char *t = NULL; n = 0; if (read_one_line_file("/proc/self/oom_score_adj", &t) >= 0) { safe_atoi(t, &n); - free(t); } } diff --git a/src/core/dbus-job.c b/src/core/dbus-job.c index a85d3185c2..4ab88d06c3 100644 --- a/src/core/dbus-job.c +++ b/src/core/dbus-job.c @@ -60,7 +60,7 @@ static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_job_append_type, job_type, JobType); static int bus_job_append_unit(DBusMessageIter *i, const char *property, void *data) { Job *j = data; DBusMessageIter sub; - char *p; + _cleanup_free_ char *p = NULL; assert(i); assert(property); @@ -75,12 +75,9 @@ static int bus_job_append_unit(DBusMessageIter *i, const char *property, void *d if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &j->unit->id) || !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &p)) { - free(p); return -ENOMEM; } - free(p); - if (!dbus_message_iter_close_container(i, &sub)) return -ENOMEM; @@ -136,7 +133,7 @@ static DBusHandlerResult bus_job_message_handler(DBusConnection *connection, DBu /* Be nice to gdbus and return introspection data for our mid-level paths */ if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect")) { - char *introspection = NULL; + _cleanup_free_ char *introspection = NULL; FILE *f; Iterator i; size_t size; @@ -169,7 +166,6 @@ static DBusHandlerResult bus_job_message_handler(DBusConnection *connection, DBu if (ferror(f)) { fclose(f); - free(introspection); goto oom; } @@ -179,12 +175,9 @@ static DBusHandlerResult bus_job_message_handler(DBusConnection *connection, DBu goto oom; if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection, DBUS_TYPE_INVALID)) { - free(introspection); goto oom; } - free(introspection); - if (!bus_maybe_send_reply(connection, message, reply)) goto oom; diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index e1a169ca21..75e2e45b66 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -413,7 +413,7 @@ static int bus_manager_set_log_target(DBusMessageIter *i, const char *property, } static int bus_manager_append_log_level(DBusMessageIter *i, const char *property, void *data) { - char *t; + _cleanup_free_ char *t = NULL; int r; assert(i); @@ -426,7 +426,6 @@ static int bus_manager_append_log_level(DBusMessageIter *i, const char *property if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t)) r = -ENOMEM; - free(t); return r; } @@ -1191,7 +1190,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, goto oom; } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect")) { - char *introspection = NULL; + _cleanup_free_ char *introspection = NULL; FILE *f; Iterator i; Unit *u; @@ -1217,7 +1216,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, fputs(INTROSPECTION_BEGIN, f); HASHMAP_FOREACH_KEY(u, k, m->units, i) { - char *p; + _cleanup_free_ char *p = NULL; if (k != u->id) continue; @@ -1225,12 +1224,10 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, p = bus_path_escape(k); if (!p) { fclose(f); - free(introspection); goto oom; } fprintf(f, "", p); - free(p); } HASHMAP_FOREACH(j, m->jobs, i) @@ -1240,7 +1237,6 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, if (ferror(f)) { fclose(f); - free(introspection); goto oom; } @@ -1250,12 +1246,8 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, goto oom; if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection, DBUS_TYPE_INVALID)) { - free(introspection); goto oom; } - - free(introspection); - } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Reload")) { SELINUX_ACCESS_CHECK(connection, message, "reload"); diff --git a/src/core/unit.c b/src/core/unit.c index b56be83a31..27119b0cd7 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -189,7 +189,8 @@ fail: } int unit_choose_id(Unit *u, const char *name) { - char *s, *t = NULL, *i; + char *s, *i; + _cleanup_free_ char *t = NULL; int r; assert(u); @@ -208,7 +209,6 @@ int unit_choose_id(Unit *u, const char *name) { /* Selects one of the names of this unit as the id */ s = set_get(u->names, (char*) name); - free(t); if (!s) return -ENOENT; @@ -598,7 +598,7 @@ int unit_merge(Unit *u, Unit *other) { int unit_merge_by_name(Unit *u, const char *name) { Unit *other; int r; - char *s = NULL; + _cleanup_free_ char *s = NULL; assert(u); assert(name); @@ -619,7 +619,6 @@ int unit_merge_by_name(Unit *u, const char *name) { else r = unit_merge(u, other); - free(s); return r; } @@ -677,7 +676,7 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { char *t, **j; UnitDependency d; Iterator i; - char *p2; + _cleanup_free_ char *p2 = NULL; const char *prefix2; char timestamp1[FORMAT_TIMESTAMP_MAX], @@ -811,7 +810,6 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { if (u->nop_job) job_dump(u->nop_job, f, prefix2); - free(p2); } /* Common implementation for multiple backends */ @@ -1914,7 +1912,7 @@ int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, con int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) { Unit *other; int r; - char *s; + _cleanup_free_ char *s = NULL; assert(u); assert(name || path); @@ -1923,19 +1921,17 @@ int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency return -ENOMEM; if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0) - goto finish; + return r; r = unit_add_two_dependencies(u, d, e, other, add_reference); -finish: - free(s); return r; } int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) { Unit *other; int r; - char *s; + _cleanup_free_ char *s = NULL; assert(u); assert(name || path); @@ -1944,19 +1940,17 @@ int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *n return -ENOMEM; if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0) - goto finish; + return r; r = unit_add_dependency(other, d, u, add_reference); -finish: - free(s); return r; } int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) { Unit *other; int r; - char *s; + _cleanup_free_ char *s = NULL; assert(u); assert(name || path); @@ -1965,13 +1959,11 @@ int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDep return -ENOMEM; if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0) - goto finish; + return r; if ((r = unit_add_two_dependencies(other, d, e, u, add_reference)) < 0) - goto finish; + return r; -finish: - free(s); return r; } @@ -2036,7 +2028,7 @@ int unit_add_default_slice(Unit *u) { if (u->instance) { _cleanup_free_ char *prefix = NULL, *escaped = NULL; - ; + /* Implicitly place all instantiated units in their * own per-template slice */ @@ -2349,7 +2341,7 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) { int unit_add_node_link(Unit *u, const char *what, bool wants) { Unit *device; - char *e; + _cleanup_free_ char *e = NULL; int r; assert(u); @@ -2367,7 +2359,7 @@ int unit_add_node_link(Unit *u, const char *what, bool wants) { return -ENOMEM; r = manager_load_unit(u->manager, e, NULL, NULL, &device); - free(e); + if (r < 0) return r; -- cgit v1.2.1 From 689a97f52383110bf0da049e8f6294993f4020dd Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Thu, 8 Aug 2013 21:44:02 +0200 Subject: udevd: respect the log-level set in /etc/udev/udev.conf A regression introduced when we moved to systemd's logging is that the only way to adjust the log-level of the udev daemon is via the env var, kernel commandline or the commandline. This reintroduces support for specifying this in the configuration file. --- src/udev/udevd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/udev/udevd.c b/src/udev/udevd.c index 45ec3d681f..7c6c5d6a87 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -923,7 +923,10 @@ int main(int argc, char *argv[]) log_set_target(LOG_TARGET_AUTO); log_parse_environment(); log_open(); + udev_set_log_fn(udev, udev_main_log); + log_set_max_level(udev_get_log_priority(udev)); + log_debug("version %s\n", VERSION); label_init("/dev"); -- cgit v1.2.1 From 21d1a6786326ad8996b6207eb20be01b056f1450 Mon Sep 17 00:00:00 2001 From: WANG Chao Date: Thu, 8 Aug 2013 15:18:11 +0800 Subject: fstab-generator: respect noauto/nofail when adding sysroot mount Currently we don't respect noauto/nofail root mount options (from rootflags kernel cmdline). We should map these two flags to the corresponding boolean variable noauto and nofail when calling add_mount(). --- src/fstab-generator/fstab-generator.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index c17299f267..87b17cd365 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -492,6 +492,7 @@ static int parse_new_root_from_proc_cmdline(void) { char *w, *state; int r; size_t l; + bool noauto, nofail; r = read_one_line_file("/proc/cmdline", &line); if (r < 0) { @@ -547,6 +548,9 @@ static int parse_new_root_from_proc_cmdline(void) { } } + noauto = !!strstr(opts, "noauto"); + nofail = !!strstr(opts, "nofail"); + if (!what) { log_debug("Could not find a root= entry on the kernel commandline."); return 0; @@ -558,7 +562,7 @@ static int parse_new_root_from_proc_cmdline(void) { } log_debug("Found entry what=%s where=/sysroot type=%s", what, type); - r = add_mount(what, "/sysroot", type, opts, 0, false, false, false, + r = add_mount(what, "/sysroot", type, opts, 0, noauto, nofail, false, false, NULL, NULL, NULL, SPECIAL_INITRD_ROOT_FS_TARGET, "/proc/cmdline"); return (r < 0) ? r : 0; -- cgit v1.2.1 From 41efeaec037678ac790e2a02df9020f83cc3a359 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 9 Aug 2013 16:40:57 +0200 Subject: service: always unwatch PIDs before forgetting old ones --- src/core/service.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/core/service.c b/src/core/service.c index b98f11aed8..df49ce1853 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -191,6 +191,8 @@ static int service_set_main_pid(Service *s, pid_t pid) { if (pid == getpid()) return -EINVAL; + service_unwatch_main_pid(s); + s->main_pid = pid; s->main_pid_known = true; @@ -2158,10 +2160,8 @@ static void service_enter_start(Service *s) { assert(s->exec_command[SERVICE_EXEC_START]); assert(!s->exec_command[SERVICE_EXEC_START]->command_next || s->type == SERVICE_ONESHOT); - if (s->type == SERVICE_FORKING) - service_unwatch_control_pid(s); - else - service_unwatch_main_pid(s); + service_unwatch_control_pid(s); + service_unwatch_main_pid(s); /* We want to ensure that nobody leaks processes from * START_PRE here, so let's go on a killing spree, People @@ -3751,6 +3751,7 @@ static void service_reset_failed(Unit *u) { static int service_kill(Unit *u, KillWho who, int signo, DBusError *error) { Service *s = SERVICE(u); + return unit_kill_common(u, who, signo, s->main_pid, s->control_pid, error); } -- cgit v1.2.1 From b0693d30863a36da63d2a2732aa298fff6d34d0d Mon Sep 17 00:00:00 2001 From: Maciej Wereski Date: Fri, 9 Aug 2013 12:54:10 +0200 Subject: service: prohibit Restart= set when Type=oneshot --- TODO | 2 -- src/core/service.c | 6 ++++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index ead699cd16..60622f7c72 100644 --- a/TODO +++ b/TODO @@ -88,8 +88,6 @@ Features: full, make sure to write how many messages are lost as first thing to syslog when it works again. -* prohibit Restart= set with Type=oneshot - * man: the documentation of Restart= currently is very misleading and suggests the tools from ExecStartPre= might get restarted. * load .d/*.conf dropins for device units diff --git a/src/core/service.c b/src/core/service.c index df49ce1853..4070fd741b 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -1113,6 +1113,12 @@ static int service_verify(Service *s) { return -EINVAL; } + if (s->type == SERVICE_ONESHOT && s->restart != SERVICE_RESTART_NO) { + log_error_unit(UNIT(s)->id, + "%s has Restart setting other than no, which isn't allowed for Type=oneshot services. Refusing.", UNIT(s)->id); + return -EINVAL; + } + if (s->type == SERVICE_DBUS && !s->bus_name) { log_error_unit(UNIT(s)->id, "%s is of type D-Bus but no D-Bus service name has been specified. Refusing.", UNIT(s)->id); -- cgit v1.2.1 From ef53700c20b0fc51dbdedfb4a611fe6ca8411df9 Mon Sep 17 00:00:00 2001 From: WANG Chao Date: Fri, 9 Aug 2013 17:01:50 +0800 Subject: fstab-generator: read rd.fstab=on/off switch correctly --- src/fstab-generator/fstab-generator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index 87b17cd365..5a2074ec7f 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -600,9 +600,9 @@ static int parse_proc_cmdline(void) { } else if (startswith(word, "rd.fstab=")) { if (in_initrd()) { - r = parse_boolean(word + 6); + r = parse_boolean(word + 9); if (r < 0) - log_warning("Failed to parse fstab switch %s. Ignoring.", word + 6); + log_warning("Failed to parse fstab switch %s. Ignoring.", word + 9); else arg_enabled = r; } -- cgit v1.2.1 From 94bbc9915a4272a20feda86c5f97b8a587482aa1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 7 Aug 2013 12:36:59 +0200 Subject: update TODO --- TODO | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index 60622f7c72..438b644035 100644 --- a/TODO +++ b/TODO @@ -31,7 +31,7 @@ Fedora 20: CGroup Rework Completion: -* introduce "mainpid" for scopes +* introduce "mainpid" for scopes (or maybe not?) * implement system-wide DefaultCPUAccounting=1 switch (and similar for blockio, memory?) @@ -39,8 +39,6 @@ CGroup Rework Completion: * handle jointly mounted controllers correctly -* logind: implement session kill exceptions - * make BlockIODeviceWeight=, BlockIODeviceBandwidth= runtime settable * introduce high-level settings for RT budget, swappiness @@ -49,6 +47,12 @@ CGroup Rework Completion: Features: +* unlink PID files of units after exit + +* tiny tool that saves/restores backlight + +* systemctl status output should should include list of triggering units and their status + * for transient units, instead of writing out drop-ins for all properties consider serializing them in the normal serialization stream * logind: when logging out, remove user-owned sysv and posix IPC objects -- cgit v1.2.1 From 19c98efe17155734698c12482cd40834a89f0e48 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 8 Aug 2013 21:10:52 +0200 Subject: hwdb: map logitech R400 presenter keys from powerpoint hotkeys to sensible KEY_ definitions --- hwdb/60-keyboard.hwdb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index c58b72cc16..0c6f293a81 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -642,6 +642,12 @@ keyboard:usb:v046DpC52[9B]* KEYBOARD_KEY_0c022d=zoomin KEYBOARD_KEY_0c022e=zoomout +# Logitech Presenter R400 +keyboard:usb:v046DpC52Dd*dc*dsc*dp*ic*isc*ip*in00* + KEYBOARD_KEY_070029=presentation + KEYBOARD_KEY_07003e=presentation + KEYBOARD_KEY_070037=displaytoggle + ########################################################### # Maxdata ########################################################### -- cgit v1.2.1 From f535088ef72a92533f2c4270d06289c89737fa2a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 8 Aug 2013 21:12:03 +0200 Subject: systemctl: add missing newline to --help output --- src/systemctl/systemctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 8ec1824f3b..3dd74c2694 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -4650,7 +4650,7 @@ static int systemctl_help(void) { " link [PATH...] Link one or more units files into\n" " the search path\n" " get-default Get the name of the default target\n" - " set-default NAME Set the default target\n" + " set-default NAME Set the default target\n\n" "Job Commands:\n" " list-jobs List jobs\n" " cancel [JOB...] Cancel all, one, or more jobs\n\n" -- cgit v1.2.1 From 94e0bd7db1d7ca8ab7f738cdab1d014241f5b225 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 3 Aug 2013 19:38:13 -0400 Subject: systemctl: show hint about --full when lines don't fit --- src/journal/journal-gatewayd.c | 2 +- src/journal/journalctl.c | 3 +- src/shared/logs-show.c | 37 ++++++++++------ src/shared/logs-show.h | 6 ++- src/systemctl/systemctl.c | 97 +++++++++++++++++++++++++----------------- 5 files changed, 89 insertions(+), 56 deletions(-) diff --git a/src/journal/journal-gatewayd.c b/src/journal/journal-gatewayd.c index 10224a1ac1..06a236df6b 100644 --- a/src/journal/journal-gatewayd.c +++ b/src/journal/journal-gatewayd.c @@ -248,7 +248,7 @@ static ssize_t request_reader_entries( } } - r = output_journal(m->tmp, m->journal, m->mode, 0, OUTPUT_FULL_WIDTH); + r = output_journal(m->tmp, m->journal, m->mode, 0, OUTPUT_FULL_WIDTH, NULL); if (r < 0) { log_error("Failed to serialize item: %s", strerror(-r)); return MHD_CONTENT_READER_END_WITH_ERROR; diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index feea6bf19e..5cf9390249 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -1305,6 +1305,7 @@ int main(int argc, char *argv[]) { sd_id128_t previous_boot_id; bool previous_boot_id_valid = false, first_line = true; int n_shown = 0; + bool ellipsized = false; setlocale(LC_ALL, ""); log_parse_environment(); @@ -1624,7 +1625,7 @@ int main(int argc, char *argv[]) { on_tty() * OUTPUT_COLOR | arg_catalog * OUTPUT_CATALOG; - r = output_journal(stdout, j, arg_output, 0, flags); + r = output_journal(stdout, j, arg_output, 0, flags, &ellipsized); need_seek = true; if (r == -EADDRNOTAVAIL) break; diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index bd7363aa82..51cd7d51c5 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -101,10 +101,11 @@ static bool shall_print(const char *p, size_t l, OutputFlags flags) { return true; } -static void print_multiline(FILE *f, unsigned prefix, unsigned n_columns, OutputMode flags, int priority, const char* message, size_t message_len) { +static bool print_multiline(FILE *f, unsigned prefix, unsigned n_columns, OutputMode flags, int priority, const char* message, size_t message_len) { const char *color_on = "", *color_off = ""; const char *pos, *end; bool continuation = false; + bool ellipsized = false; if (flags & OUTPUT_COLOR) { if (priority <= LOG_ERR) { @@ -130,17 +131,22 @@ static void print_multiline(FILE *f, unsigned prefix, unsigned n_columns, Output else if (prefix < n_columns && n_columns - prefix >= 3) { _cleanup_free_ char *e; + ellipsized = true; e = ellipsize_mem(pos, len, n_columns - prefix, 90); if (!e) fprintf(f, "%s%.*s%s\n", color_on, len, pos, color_off); else fprintf(f, "%s%s%s\n", color_on, e, color_off); - } else + } else { + ellipsized = true; fputs("...\n", f); + } continuation = true; } + + return ellipsized; } static int output_short( @@ -157,6 +163,7 @@ static int output_short( _cleanup_free_ char *hostname = NULL, *identifier = NULL, *comm = NULL, *pid = NULL, *fake_pid = NULL, *message = NULL, *realtime = NULL, *monotonic = NULL, *priority = NULL; size_t hostname_len = 0, identifier_len = 0, comm_len = 0, pid_len = 0, fake_pid_len = 0, message_len = 0, realtime_len = 0, monotonic_len = 0, priority_len = 0; int p = LOG_INFO; + bool ellipsized = false; assert(f); assert(j); @@ -314,13 +321,14 @@ static int output_short( fprintf(f, ": [%s blob data]\n", format_bytes(bytes, sizeof(bytes), message_len)); } else { fputs(": ", f); - print_multiline(f, n + 2, n_columns, flags, p, message, message_len); + ellipsized |= + print_multiline(f, n + 2, n_columns, flags, p, message, message_len); } if (flags & OUTPUT_CATALOG) print_catalog(f, j); - return 0; + return ellipsized; } static int output_verbose( @@ -817,7 +825,8 @@ int output_journal( sd_journal *j, OutputMode mode, unsigned n_columns, - OutputFlags flags) { + OutputFlags flags, + bool *ellipsized) { int ret; assert(mode >= 0); @@ -828,6 +837,10 @@ int output_journal( ret = output_funcs[mode](f, j, mode, n_columns, flags); fflush(stdout); + + if (ellipsized && ret > 0) + *ellipsized = true; + return ret; } @@ -837,7 +850,8 @@ static int show_journal(FILE *f, unsigned n_columns, usec_t not_before, unsigned how_many, - OutputFlags flags) { + OutputFlags flags, + bool *ellipsized) { int r; unsigned line = 0; @@ -888,7 +902,7 @@ static int show_journal(FILE *f, line ++; - r = output_journal(f, j, mode, n_columns, flags); + r = output_journal(f, j, mode, n_columns, flags, ellipsized); if (r < 0) goto finish; } @@ -1037,7 +1051,8 @@ int show_journal_by_unit( unsigned how_many, uid_t uid, OutputFlags flags, - bool system) { + bool system, + bool *ellipsized) { _cleanup_journal_close_ sd_journal*j = NULL; int r; @@ -1072,11 +1087,7 @@ int show_journal_by_unit( log_debug("Journal filter: %s", filter); } - r = show_journal(f, j, mode, n_columns, not_before, how_many, flags); - if (r < 0) - return r; - - return 0; + return show_journal(f, j, mode, n_columns, not_before, how_many, flags, ellipsized); } static const char *const output_mode_table[_OUTPUT_MODE_MAX] = { diff --git a/src/shared/logs-show.h b/src/shared/logs-show.h index c9a9ad3e91..11b3b59b7b 100644 --- a/src/shared/logs-show.h +++ b/src/shared/logs-show.h @@ -35,7 +35,8 @@ int output_journal( sd_journal *j, OutputMode mode, unsigned n_columns, - OutputFlags flags); + OutputFlags flags, + bool *ellipsized); int add_match_this_boot(sd_journal *j); @@ -57,7 +58,8 @@ int show_journal_by_unit( unsigned how_many, uid_t uid, OutputFlags flags, - bool system); + bool system, + bool *ellipsized); void json_escape( FILE *f, diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 3dd74c2694..a635891bc0 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -2503,7 +2503,8 @@ typedef struct UnitStatusInfo { LIST_HEAD(ExecStatusInfo, exec); } UnitStatusInfo; -static void print_status_info(UnitStatusInfo *i) { +static void print_status_info(UnitStatusInfo *i, + bool *ellipsized) { ExecStatusInfo *p; const char *on, *off, *ss; usec_t timestamp; @@ -2779,7 +2780,8 @@ static void print_status_info(UnitStatusInfo *i) { arg_lines, getuid(), flags, - arg_scope == UNIT_FILE_SYSTEM); + arg_scope == UNIT_FILE_SYSTEM, + ellipsized); } if (i->need_daemon_reload) @@ -3345,7 +3347,12 @@ static int print_property(const char *name, DBusMessageIter *iter) { return 0; } -static int show_one(const char *verb, DBusConnection *bus, const char *path, bool show_properties, bool *new_line) { +static int show_one(const char *verb, + DBusConnection *bus, + const char *path, + bool show_properties, + bool *new_line, + bool *ellipsized) { _cleanup_free_ DBusMessage *reply = NULL; const char *interface = ""; int r; @@ -3415,7 +3422,7 @@ static int show_one(const char *verb, DBusConnection *bus, const char *path, boo if (streq(verb, "help")) show_unit_help(&info); else - print_status_info(&info); + print_status_info(&info, ellipsized); } strv_free(info.documentation); @@ -3446,7 +3453,11 @@ static int show_one(const char *verb, DBusConnection *bus, const char *path, boo return r; } -static int show_one_by_pid(const char *verb, DBusConnection *bus, uint32_t pid, bool *new_line) { +static int show_one_by_pid(const char *verb, + DBusConnection *bus, + uint32_t pid, + bool *new_line, + bool *ellipsized) { _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; const char *path = NULL; _cleanup_dbus_error_free_ DBusError error; @@ -3474,11 +3485,15 @@ static int show_one_by_pid(const char *verb, DBusConnection *bus, uint32_t pid, return -EIO; } - r = show_one(verb, bus, path, false, new_line); + r = show_one(verb, bus, path, false, new_line, ellipsized); return r; } -static int show_all(const char* verb, DBusConnection *bus, bool show_properties, bool *new_line) { +static int show_all(const char* verb, + DBusConnection *bus, + bool show_properties, + bool *new_line, + bool *ellipsized) { _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; _cleanup_free_ struct unit_info *unit_infos = NULL; unsigned c = 0; @@ -3503,7 +3518,7 @@ static int show_all(const char* verb, DBusConnection *bus, bool show_properties, printf("%s -> '%s'\n", u->id, p); - r = show_one(verb, bus, p, show_properties, new_line); + r = show_one(verb, bus, p, show_properties, new_line, ellipsized); if (r != 0) return r; } @@ -3515,6 +3530,7 @@ static int show(DBusConnection *bus, char **args) { int r, ret = 0; bool show_properties, show_status, new_line = false; char **name; + bool ellipsized = false; assert(bus); assert(args); @@ -3528,48 +3544,51 @@ static int show(DBusConnection *bus, char **args) { /* If no argument is specified inspect the manager itself */ if (show_properties && strv_length(args) <= 1) - return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line); + return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized); if (show_status && strv_length(args) <= 1) - return show_all(args[0], bus, false, &new_line); - - STRV_FOREACH(name, args+1) { - uint32_t id; + ret = show_all(args[0], bus, false, &new_line, &ellipsized); + else + STRV_FOREACH(name, args+1) { + uint32_t id; - if (safe_atou32(*name, &id) < 0) { - _cleanup_free_ char *p = NULL, *n = NULL; - /* Interpret as unit name */ + if (safe_atou32(*name, &id) < 0) { + _cleanup_free_ char *p = NULL, *n = NULL; + /* Interpret as unit name */ - n = unit_name_mangle(*name); - if (!n) - return log_oom(); + n = unit_name_mangle(*name); + if (!n) + return log_oom(); - p = unit_dbus_path_from_name(n); - if (!p) - return log_oom(); + p = unit_dbus_path_from_name(n); + if (!p) + return log_oom(); - r = show_one(args[0], bus, p, show_properties, &new_line); - if (r != 0) - ret = r; + r = show_one(args[0], bus, p, show_properties, &new_line, &ellipsized); + if (r != 0) + ret = r; - } else if (show_properties) { - _cleanup_free_ char *p = NULL; + } else if (show_properties) { + _cleanup_free_ char *p = NULL; - /* Interpret as job id */ - if (asprintf(&p, "/org/freedesktop/systemd1/job/%u", id) < 0) - return log_oom(); + /* Interpret as job id */ + if (asprintf(&p, "/org/freedesktop/systemd1/job/%u", id) < 0) + return log_oom(); - r = show_one(args[0], bus, p, show_properties, &new_line); - if (r != 0) - ret = r; + r = show_one(args[0], bus, p, show_properties, &new_line, &ellipsized); + if (r != 0) + ret = r; - } else { - /* Interpret as PID */ - r = show_one_by_pid(args[0], bus, id, &new_line); - if (r != 0) - ret = r; + } else { + /* Interpret as PID */ + r = show_one_by_pid(args[0], bus, id, &new_line, &ellipsized); + if (r != 0) + ret = r; + } } - } + + if (ellipsized && !arg_quiet) + printf("Hint: Some lines were ellipsized, use -l to show in full.\n"); return ret; } -- cgit v1.2.1 From b4b02cbeec04b51697bce1f4e439b9b7afae5393 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 8 Aug 2013 08:32:43 -0400 Subject: logs-show: fix indentation for 2nd and later lines, show lines in full Now --full will show long fields in full, like it already did with --all. --- src/shared/logs-show.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index 51cd7d51c5..2270c3b030 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -135,9 +135,13 @@ static bool print_multiline(FILE *f, unsigned prefix, unsigned n_columns, Output e = ellipsize_mem(pos, len, n_columns - prefix, 90); if (!e) - fprintf(f, "%s%.*s%s\n", color_on, len, pos, color_off); + fprintf(f, "%*s%s%.*s%s\n", + continuation * prefix, "", + color_on, len, pos, color_off); else - fprintf(f, "%s%s%s\n", color_on, e, color_off); + fprintf(f, "%*s%s%s%s\n", + continuation * prefix, "", + color_on, e, color_off); } else { ellipsized = true; fputs("...\n", f); @@ -168,7 +172,7 @@ static int output_short( assert(f); assert(j); - sd_journal_set_data_threshold(j, flags & OUTPUT_SHOW_ALL ? 0 : PRINT_THRESHOLD); + sd_journal_set_data_threshold(j, flags & (OUTPUT_SHOW_ALL|OUTPUT_FULL_WIDTH) ? 0 : PRINT_THRESHOLD); JOURNAL_FOREACH_DATA_RETVAL(j, data, length, r) { -- cgit v1.2.1 From a6f0104a16350a4c2660837da6e0e5c2e50e2389 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 11 Aug 2013 10:56:09 -0400 Subject: logs-show: limit to 3 lines and use dots if not showing full message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So far, we would show up to 128 bytes from a message, simply cutting of the rest. With multiline messages, it is quite common for a message to be longer than that, and this model doesn't really work anymore. A new limit is added: up to 3 lines will be shown, unless --full is used (c.f. first line below). The limit for bytes is extended to 300 bytes. An ellipsis will always be used, if some form of truncation occurs. If the tail of the message is cut off, either because of length or line limit, dots will be shown at the end of the last line. If this last line is short, the dots will be simply appended. If the last line is too long for that, it will be ellipsized with dots at the very end. Note that the limits are in bytes, not characters, and we suck at outputting unicode strings (c.f. last three lines below). Aug 11 10:46:21 fedora python[67]: test message line line... Aug 11 10:50:47 fedora python[76]: test message word word word word word word word word word word word wor... Aug 11 10:55:11 fedora python[83]: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx... Aug 11 11:03:21 fedora python[90]: ąąąąąąąąąąąąąąąąąąąąąąąąąąąąąą... Aug 11 11:03:53 fedora python[97]: aąąąąąąąąąąąąąąąąąąąąąąąąąąąąąą... Aug 11 11:25:45 fedora python[121]: aąąąąąąąąąąąąąąąąąąąąąąąąąąąąąąąąąą�... --- TODO | 4 +++ src/shared/logs-show.c | 77 ++++++++++++++++++++++++++++++++++++-------------- src/shared/util.c | 2 +- 3 files changed, 61 insertions(+), 22 deletions(-) diff --git a/TODO b/TODO index 438b644035..d72a65dcf6 100644 --- a/TODO +++ b/TODO @@ -19,6 +19,10 @@ Bugfixes: * properly handle .mount unit state tracking when two mount points are stacked one on top of another on the exact same mount point. +* ellipsize_mem must take into account multi-byte unicode characters, and + - make the resulting line the requested number of *characters*, not *bytes*, + - avoid truncuating multi-byte sequences in the middle. + Fedora 20: * external: ps should gain colums for slice and machine diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index 2270c3b030..af738a313e 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -32,7 +32,11 @@ #include "hashmap.h" #include "journal-internal.h" -#define PRINT_THRESHOLD 128 +/* up to three lines (each up to 100 characters), + or 300 characters, whichever is less */ +#define PRINT_LINE_THRESHOLD 3 +#define PRINT_CHAR_THRESHOLD 300 + #define JSON_THRESHOLD 4096 static int print_catalog(FILE *f, sd_journal *j) { @@ -92,7 +96,7 @@ static bool shall_print(const char *p, size_t l, OutputFlags flags) { if (flags & OUTPUT_SHOW_ALL) return true; - if (l >= PRINT_THRESHOLD) + if (l >= PRINT_CHAR_THRESHOLD) return false; if (!utf8_is_printable(p, l)) @@ -104,8 +108,8 @@ static bool shall_print(const char *p, size_t l, OutputFlags flags) { static bool print_multiline(FILE *f, unsigned prefix, unsigned n_columns, OutputMode flags, int priority, const char* message, size_t message_len) { const char *color_on = "", *color_off = ""; const char *pos, *end; - bool continuation = false; bool ellipsized = false; + int line = 0; if (flags & OUTPUT_COLOR) { if (priority <= LOG_ERR) { @@ -117,37 +121,61 @@ static bool print_multiline(FILE *f, unsigned prefix, unsigned n_columns, Output } } - for (pos = message; pos < message + message_len; pos = end + 1) { + for (pos = message; + pos < message + message_len; + pos = end + 1, line++) { + bool continuation = line > 0; + bool tail_line; int len; for (end = pos; end < message + message_len && *end != '\n'; end++) ; len = end - pos; assert(len >= 0); - if (flags & (OUTPUT_FULL_WIDTH | OUTPUT_SHOW_ALL) || prefix + len + 1 < n_columns) + /* We need to figure out when we are showing the last line, and + * will skip subsequent lines. In that case, we will put the dots + * at the end of the line, instead of putting dots in the middle + * or not at all. + */ + tail_line = + line + 1 == PRINT_LINE_THRESHOLD || + end + 1 >= message + message_len; + + if (flags & (OUTPUT_FULL_WIDTH | OUTPUT_SHOW_ALL) || + (prefix + len + 1 < n_columns && !tail_line)) { fprintf(f, "%*s%s%.*s%s\n", continuation * prefix, "", color_on, len, pos, color_off); - else if (prefix < n_columns && n_columns - prefix >= 3) { - _cleanup_free_ char *e; + continue; + } - ellipsized = true; - e = ellipsize_mem(pos, len, n_columns - prefix, 90); + /* Beyond this point, ellipsization will happen. */ + ellipsized = true; - if (!e) - fprintf(f, "%*s%s%.*s%s\n", + if (prefix < n_columns && n_columns - prefix >= 3) { + if (n_columns - prefix > (unsigned) len + 3) + fprintf(f, "%*s%s%.*s...%s\n", continuation * prefix, "", color_on, len, pos, color_off); - else - fprintf(f, "%*s%s%s%s\n", - continuation * prefix, "", - color_on, e, color_off); - } else { - ellipsized = true; + else { + _cleanup_free_ char *e; + + e = ellipsize_mem(pos, len, n_columns - prefix, + tail_line ? 100 : 90); + if (!e) + fprintf(f, "%*s%s%.*s%s\n", + continuation * prefix, "", + color_on, len, pos, color_off); + else + fprintf(f, "%*s%s%s%s\n", + continuation * prefix, "", + color_on, e, color_off); + } + } else fputs("...\n", f); - } - continuation = true; + if (tail_line) + break; } return ellipsized; @@ -172,7 +200,13 @@ static int output_short( assert(f); assert(j); - sd_journal_set_data_threshold(j, flags & (OUTPUT_SHOW_ALL|OUTPUT_FULL_WIDTH) ? 0 : PRINT_THRESHOLD); + /* Set the threshold to one bigger than the actual print + * treshold, so that if the line is actually longer than what + * we're willing to print, ellipsization will occur. This way + * we won't output a misleading line without any indication of + * truncation. + */ + sd_journal_set_data_threshold(j, flags & (OUTPUT_SHOW_ALL|OUTPUT_FULL_WIDTH) ? 0 : PRINT_CHAR_THRESHOLD + 1); JOURNAL_FOREACH_DATA_RETVAL(j, data, length, r) { @@ -389,7 +423,8 @@ static int output_verbose( } if (flags & OUTPUT_SHOW_ALL || - (((length < PRINT_THRESHOLD) || flags & OUTPUT_FULL_WIDTH) && utf8_is_printable(data, length))) { + (((length < PRINT_CHAR_THRESHOLD) || flags & OUTPUT_FULL_WIDTH) + && utf8_is_printable(data, length))) { fprintf(f, " %s%.*s=", on, fieldlen, (const char*)data); print_multiline(f, 4 + fieldlen + 1, 0, OUTPUT_FULL_WIDTH, 0, c + 1, length - fieldlen - 1); fputs(off, f); diff --git a/src/shared/util.c b/src/shared/util.c index c8ed53c8b6..f23dd92a6b 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -3332,7 +3332,7 @@ char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigne r = new0(char, new_length+1); if (!r) - return r; + return NULL; x = (new_length * percent) / 100; -- cgit v1.2.1 From 631c922c68ec1fc5c34077c1d95b76eff38e1608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 12 Aug 2013 12:01:55 -0400 Subject: shell-completion: tell bash about --state --- shell-completion/bash/systemctl | 7 ++++++- shell-completion/zsh/_systemctl | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/shell-completion/bash/systemctl b/shell-completion/bash/systemctl index 517b49a6af..5346eef65b 100644 --- a/shell-completion/bash/systemctl +++ b/shell-completion/bash/systemctl @@ -74,7 +74,7 @@ _systemctl () { [STANDALONE]='--all -a --reverse --after --before --defaults --fail --ignore-dependencies --failed --force -f --full -l --global --help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall --quiet -q --privileged -P --system --user --version --runtime' - [ARG]='--host -H --kill-mode --kill-who --property -p --signal -s --type -t --root' + [ARG]='--host -H --kill-mode --kill-who --property -p --signal -s --type -t --state --root' ) if __contains_word "--user" ${COMP_WORDS[*]}; then @@ -91,6 +91,11 @@ _systemctl () { --type|-t) comps='automount device mount path service snapshot socket swap target timer' ;; + --state) + comps='loaded not-found stub + active inactive + dead elapsed exited listening mounted plugged running waiting' + ;; --kill-who) comps='all control main' ;; diff --git a/shell-completion/zsh/_systemctl b/shell-completion/zsh/_systemctl index 70d6f3394a..f78dc19b7e 100644 --- a/shell-completion/zsh/_systemctl +++ b/shell-completion/zsh/_systemctl @@ -304,7 +304,7 @@ _arguments -s \ {-h,--help}'[Show help]' \ '--version[Show package version]' \ {-t,--type=}'[List only units of a particular type]:unit type:(automount device mount path service snapshot socket swap target timer)' \ - '--state=[Display units in the specifyied state]:unit state:(loaded failed active inactive not-found listening running waiting plugged mounted exited dead masked)' \ + '--state=[Display units in the specified state]:unit state:(loaded failed active inactive not-found listening running waiting plugged mounted exited dead masked)' \ \*{-p,--property=}'[Show only properties by specific name]:unit property' \ {-a,--all}'[Show all units/properties, including dead/empty ones]' \ '--reverse[Show reverse dependencies]' \ -- cgit v1.2.1 From 0b41bcec90c3d47bc512bf7ce64c150d29416a31 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 13 Aug 2013 00:00:32 +0200 Subject: TODO: update --- TODO | 3 +++ 1 file changed, 3 insertions(+) diff --git a/TODO b/TODO index d72a65dcf6..b766efe397 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,7 @@ Bugfixes: +* update COPYRIGHT in our README: + http://ftp-master.metadata.debian.org/changelogs//main/s/systemd/systemd_204-2_copyright + * the running hwdb seems not to pick up updated database files without an explicit: udevadm control --reload -- cgit v1.2.1 From bed2e820dba48591853547547a46ba4de04f86ad Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 13 Aug 2013 10:12:35 +0200 Subject: missing: use btrfs.h instead of defining our own btrfs structures --- src/readahead/readahead-collect.c | 1 + src/shared/missing.h | 17 ----------------- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/src/readahead/readahead-collect.c b/src/readahead/readahead-collect.c index ccd8408c1b..658c230d65 100644 --- a/src/readahead/readahead-collect.c +++ b/src/readahead/readahead-collect.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include diff --git a/src/shared/missing.h b/src/shared/missing.h index 534b3ccd4e..6e4b398fcb 100644 --- a/src/shared/missing.h +++ b/src/shared/missing.h @@ -154,23 +154,6 @@ static inline int fanotify_mark(int fanotify_fd, unsigned int flags, uint64_t ma } #endif -#ifndef BTRFS_IOCTL_MAGIC -#define BTRFS_IOCTL_MAGIC 0x94 -#endif - -#ifndef BTRFS_PATH_NAME_MAX -#define BTRFS_PATH_NAME_MAX 4087 -#endif - -struct btrfs_ioctl_vol_args { - int64_t fd; - char name[BTRFS_PATH_NAME_MAX + 1]; -}; - -#ifndef BTRFS_IOC_DEFRAG -#define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, struct btrfs_ioctl_vol_args) -#endif - #ifndef BTRFS_SUPER_MAGIC #define BTRFS_SUPER_MAGIC 0x9123683E #endif -- cgit v1.2.1 From 1a14a53cfded6e78c6e8dfb73fdff0039971d642 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 13 Aug 2013 10:13:45 +0200 Subject: gpt-auto-generator: add basic auto-discovery of GPT partitions This adds a simple generator that is capable of automatically discovering certain GPT partitions by their type UUID and mount/enable them. This currently covers swap partitions and /home partitions, but is expected to grow more features soon. This currently doesn't handle LUKS encrypted /home. This enables all swap partitions of type 0657fd6da4ab43c484e50933c84b4f4f, if found. This mounts the first partition of type 933ac7e12eb44f13b8440e14e2aef915 as /home, if it is found. --- .gitignore | 1 + Makefile.am | 18 + TODO | 2 + src/gpt-auto-generator/gpt-auto-generator.c | 492 ++++++++++++++++++++++++++++ 4 files changed, 513 insertions(+) create mode 100644 src/gpt-auto-generator/gpt-auto-generator.c diff --git a/.gitignore b/.gitignore index 285f4062a2..dc5d735f08 100644 --- a/.gitignore +++ b/.gitignore @@ -46,6 +46,7 @@ /systemd-fstab-generator /systemd-getty-generator /systemd-gnome-ask-password-agent +/systemd-gpt-auto-generator /systemd-hostnamed /systemd-inhibit /systemd-initctl diff --git a/Makefile.am b/Makefile.am index b8b8d06629..c19d596120 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1702,6 +1702,24 @@ bin_PROGRAMS += \ bootctl endif +# ------------------------------------------------------------------------------ +systemgenerator_PROGRAMS += \ + systemd-gpt-auto-generator + +systemd_gpt_auto_generator_SOURCES = \ + src/gpt-auto-generator/gpt-auto-generator.c + +systemd_gpt_auto_generator_LDADD = \ + libsystemd-label.la \ + libsystemd-shared.la \ + libsystemd-id128-internal.la \ + libudev-private.la \ + $(BLKID_LIBS) + +systemd_gpt_auto_generator_CFLAGS = \ + $(AM_CFLAGS) \ + $(BLKID_CFLAGS) + # ------------------------------------------------------------------------------ systemd_rc_local_generator_SOURCES = \ src/rc-local-generator/rc-local-generator.c diff --git a/TODO b/TODO index b766efe397..b845255d03 100644 --- a/TODO +++ b/TODO @@ -54,6 +54,8 @@ CGroup Rework Completion: Features: +* rename F_TYPE_CMP() to F_TYPE_EQUAL() + * unlink PID files of units after exit * tiny tool that saves/restores backlight diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c new file mode 100644 index 0000000000..0c7635bfe4 --- /dev/null +++ b/src/gpt-auto-generator/gpt-auto-generator.c @@ -0,0 +1,492 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include "path-util.h" +#include "util.h" +#include "mkdir.h" +#include "missing.h" +#include "sd-id128.h" +#include "libudev.h" +#include "special.h" +#include "unit-name.h" + +/* TODO: + * + * - Properly handle cryptsetup partitions + * - Define new partition type for encrypted swap + * + */ + +static const char *arg_dest = "/tmp"; + +static int verify_gpt_partition(dev_t dev, sd_id128_t *type, unsigned *nr, char **fstype) { + _cleanup_free_ char *t = NULL; + blkid_probe b = NULL; + const char *v; + int r; + + r = asprintf(&t, "/dev/block/%u:%u", major(dev), minor(dev)); + if (r < 0) + return -ENOMEM; + + errno = 0; + b = blkid_new_probe_from_filename(t); + if (!b) { + if (errno != 0) + return -errno; + + return -ENOMEM; + } + + blkid_probe_enable_superblocks(b, 1); + blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE); + blkid_probe_enable_partitions(b, 1); + blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS); + + errno = 0; + r = blkid_do_safeprobe(b); + if (r == -2) { + r = -ENODEV; + goto finish; + } else if (r == 1) { + r = -ENODEV; + goto finish; + } else if (r != 0) { + r = errno ? -errno : -EIO; + goto finish; + } + + errno = 0; + r = blkid_probe_lookup_value(b, "PART_ENTRY_SCHEME", &v, NULL); + if (r != 0) { + r = errno ? -errno : -EIO; + goto finish; + } + + if (strcmp(v, "gpt") != 0) { + r = 0; + goto finish; + } + + if (type) { + errno = 0; + r = blkid_probe_lookup_value(b, "PART_ENTRY_TYPE", &v, NULL); + if (r != 0) { + r = errno ? -errno : -EIO; + goto finish; + } + + r = sd_id128_from_string(v, type); + if (r < 0) + return r; + } + + if (nr) { + errno = 0; + r = blkid_probe_lookup_value(b, "PART_ENTRY_NUMBER", &v, NULL); + if (r != 0) { + r = errno ? -errno : -EIO; + goto finish; + } + + r = safe_atou(v, nr); + if (r < 0) + return r; + } + + + if (fstype) { + char *fst; + + errno = 0; + r = blkid_probe_lookup_value(b, "TYPE", &v, NULL); + if (r != 0) + *fstype = NULL; + else { + fst = strdup(v); + if (!fst) { + r = -ENOMEM; + goto finish; + } + + *fstype = fst; + } + } + + return 1; + +finish: + if (b) + blkid_free_probe(b); + + return r; +} + +static int add_swap(const char *path, const char *fstype) { + _cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL; + _cleanup_fclose_ FILE *f = NULL; + + log_debug("Adding swap: %s %s", path, fstype); + + name = unit_name_from_path(path, ".swap"); + if (!name) + return log_oom(); + + unit = strjoin(arg_dest, "/", name, NULL); + if (!unit) + return log_oom(); + + f = fopen(unit, "wxe"); + if (!f) { + log_error("Failed to create unit file %s: %m", unit); + return -errno; + } + + fprintf(f, + "# Automatically generated by systemd-gpt-auto-generator\n\n" + "[Unit]\n" + "DefaultDependencies=no\n" + "Conflicts=" SPECIAL_UMOUNT_TARGET "\n" + "Before=" SPECIAL_UMOUNT_TARGET " " SPECIAL_SWAP_TARGET "\n\n" + "[Mount]\n" + "What=%s\n", + path); + + fflush(f); + if (ferror(f)) { + log_error("Failed to write unit file %s: %m", unit); + return -errno; + } + + lnk = strjoin(arg_dest, "/" SPECIAL_SWAP_TARGET ".wants/", name, NULL); + if (!lnk) + return log_oom(); + + mkdir_parents_label(lnk, 0755); + if (symlink(unit, lnk) < 0) { + log_error("Failed to create symlink %s: %m", lnk); + return -errno; + } + + return 0; +} + +static int add_home(const char *path, const char *fstype) { + _cleanup_free_ char *unit = NULL, *lnk = NULL; + _cleanup_fclose_ FILE *f = NULL; + + log_debug("Adding home: %s %s", path, fstype); + + unit = strappend(arg_dest, "/home.mount"); + if (!unit) + return log_oom(); + + f = fopen(unit, "wxe"); + if (!f) { + log_error("Failed to create unit file %s: %m", unit); + return -errno; + } + + fprintf(f, + "# Automatically generated by systemd-gpt-auto-generator\n\n" + "[Unit]\n" + "DefaultDependencies=no\n" + "After=" SPECIAL_LOCAL_FS_PRE_TARGET "\n" + "Conflicts=" SPECIAL_UMOUNT_TARGET "\n" + "Before=" SPECIAL_UMOUNT_TARGET " " SPECIAL_LOCAL_FS_TARGET "\n\n" + "[Mount]\n" + "What=%s\n" + "Where=/home\n" + "Type=%s\n" + "FsckPassNo=2\n", + path, fstype); + + fflush(f); + if (ferror(f)) { + log_error("Failed to write unit file %s: %m", unit); + return -errno; + } + + lnk = strjoin(arg_dest, "/" SPECIAL_LOCAL_FS_TARGET ".requires/home.mount", NULL); + if (!lnk) + return log_oom(); + + + mkdir_parents_label(lnk, 0755); + if (symlink(unit, lnk) < 0) { + log_error("Failed to create symlink %s: %m", lnk); + return -errno; + } + + return 0; +} + +static int enumerate_partitions(dev_t dev) { + struct udev *udev; + struct udev_enumerate *e = NULL; + struct udev_device *parent = NULL, *d = NULL; + struct udev_list_entry *first, *item; + unsigned home_nr = (unsigned) -1; + _cleanup_free_ char *home = NULL, *home_fstype = NULL; + int r; + + udev = udev_new(); + if (!udev) + return log_oom(); + + e = udev_enumerate_new(udev); + if (!e) { + r = log_oom(); + goto finish; + } + + d = udev_device_new_from_devnum(udev, 'b', dev); + if (!d) { + r = log_oom(); + goto finish; + } + + parent = udev_device_get_parent(d); + if (!parent) { + r = log_oom(); + goto finish; + } + + r = udev_enumerate_add_match_parent(e, parent); + if (r < 0) { + r = log_oom(); + goto finish; + } + + r = udev_enumerate_add_match_subsystem(e, "block"); + if (r < 0) { + r = log_oom(); + goto finish; + } + + r = udev_enumerate_scan_devices(e); + if (r < 0) { + log_error("Failed to enumerate partitions: %s", strerror(-r)); + goto finish; + } + + first = udev_enumerate_get_list_entry(e); + udev_list_entry_foreach(item, first) { + _cleanup_free_ char *fstype = NULL; + const char *node = NULL; + struct udev_device *q; + sd_id128_t type_id; + unsigned nr; + + q = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item)); + if (!q) { + r = log_oom(); + goto finish; + } + + if (udev_device_get_devnum(q) == udev_device_get_devnum(d)) + goto skip; + + if (udev_device_get_devnum(q) == udev_device_get_devnum(parent)) + goto skip; + + node = udev_device_get_devnode(q); + if (!node) { + r = log_oom(); + goto finish; + } + + r = verify_gpt_partition(udev_device_get_devnum(q), &type_id, &nr, &fstype); + if (r < 0) { + log_error("Failed to verify GPT partition: %s", strerror(-r)); + udev_device_unref(q); + goto finish; + } + if (r == 0) + goto skip; + + if (sd_id128_equal(type_id, SD_ID128_MAKE(06,57,fd,6d,a4,ab,43,c4,84,e5,09,33,c8,4b,4f,4f))) + add_swap(node, fstype); + else if (sd_id128_equal(type_id, SD_ID128_MAKE(93,3a,c7,e1,2e,b4,4f,13,b8,44,0e,14,e2,ae,f9,15))) { + + if (!home || nr < home_nr) { + free(home); + home = strdup(node); + if (!home) { + r = log_oom(); + goto finish; + } + + home_nr = nr; + + free(home_fstype); + home_fstype = fstype; + fstype = NULL; + } + } + + skip: + udev_device_unref(q); + } + + if (home && home_fstype) + add_home(home, home_fstype); + +finish: + if (d) + udev_device_unref(d); + + if (e) + udev_enumerate_unref(e); + + if (udev) + udev_unref(udev); + + return r; +} + +static int get_btrfs_block_device(const char *path, dev_t *dev) { + struct btrfs_ioctl_fs_info_args fsi; + _cleanup_close_ int fd = -1; + uint64_t id; + + assert(path); + assert(dev); + + fd = open(path, O_DIRECTORY|O_CLOEXEC); + if (fd < 0) + return -errno; + + zero(fsi); + if (ioctl(fd, BTRFS_IOC_FS_INFO, &fsi) < 0) + return -errno; + + /* We won't do this for btrfs RAID */ + if (fsi.num_devices != 1) + return 0; + + for (id = 1; id <= fsi.max_id; id++) { + struct btrfs_ioctl_dev_info_args di; + struct stat st; + + zero(di); + di.devid = id; + + if (ioctl(fd, BTRFS_IOC_DEV_INFO, &di) < 0) { + if (errno == ENODEV) + continue; + + return -errno; + } + + if (stat((char*) di.path, &st) < 0) + return -errno; + + if (!S_ISBLK(st.st_mode)) + return -ENODEV; + + if (major(st.st_rdev) == 0) + return -ENODEV; + + *dev = st.st_rdev; + return 1; + } + + return -ENODEV; +} + +static int get_block_device(const char *path, dev_t *dev) { + struct stat st; + struct statfs sfs; + + assert(path); + assert(dev); + + if (lstat("/", &st)) + return -errno; + + if (major(st.st_dev) != 0) { + *dev = st.st_dev; + return 1; + } + + if (statfs("/", &sfs) < 0) + return -errno; + + if (F_TYPE_CMP(sfs.f_type, BTRFS_SUPER_MAGIC)) + return get_btrfs_block_device(path, dev); + + return 0; +} + +int main(int argc, char *argv[]) { + dev_t dev; + int r; + + if (argc > 1 && argc != 4) { + log_error("This program takes three or no arguments."); + return EXIT_FAILURE; + } + + if (argc > 1) + arg_dest = argv[3]; + + log_set_target(LOG_TARGET_SAFE); + log_parse_environment(); + log_open(); + + umask(0022); + + if (in_initrd()) + return EXIT_SUCCESS; + + r = get_block_device("/", &dev); + if (r < 0) { + log_error("Failed to determine block device of root file system: %s", strerror(-r)); + return EXIT_FAILURE; + } + if (r == 0) { + log_debug("Root file system not on a (single) block device."); + return EXIT_SUCCESS; + } + + log_debug("Root device %u:%u.", major(dev), minor(dev)); + + r = verify_gpt_partition(dev, NULL, NULL, NULL); + if (r < 0) { + log_error("Failed to verify GPT partition: %s", strerror(-r)); + return EXIT_FAILURE; + } + if (r == 0) + return EXIT_SUCCESS; + + r = enumerate_partitions(dev); + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} -- cgit v1.2.1 From 4b1b14a6a6acb1640596d5e9542829d32989d385 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 13 Aug 2013 10:21:16 +0200 Subject: gpt-auto-generator: Skip /home mounting if /home is not empty --- src/gpt-auto-generator/gpt-auto-generator.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index 0c7635bfe4..60fb19ee07 100644 --- a/src/gpt-auto-generator/gpt-auto-generator.c +++ b/src/gpt-auto-generator/gpt-auto-generator.c @@ -40,6 +40,7 @@ * * - Properly handle cryptsetup partitions * - Define new partition type for encrypted swap + * - Make /home automount rather than mount * */ @@ -201,6 +202,9 @@ static int add_home(const char *path, const char *fstype) { _cleanup_free_ char *unit = NULL, *lnk = NULL; _cleanup_fclose_ FILE *f = NULL; + if (dir_is_empty("/home") <= 0) + return 0; + log_debug("Adding home: %s %s", path, fstype); unit = strappend(arg_dest, "/home.mount"); -- cgit v1.2.1 From 00aa179e3944286d6837fe8534de071033e02eab Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 13 Aug 2013 10:22:02 +0200 Subject: build-sys: add two makefile symlinks --- hwdb/Makefile | 1 + src/gpt-auto-generator/Makefile | 1 + 2 files changed, 2 insertions(+) create mode 120000 hwdb/Makefile create mode 120000 src/gpt-auto-generator/Makefile diff --git a/hwdb/Makefile b/hwdb/Makefile new file mode 120000 index 0000000000..bd1047548b --- /dev/null +++ b/hwdb/Makefile @@ -0,0 +1 @@ +../src/Makefile \ No newline at end of file diff --git a/src/gpt-auto-generator/Makefile b/src/gpt-auto-generator/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/gpt-auto-generator/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file -- cgit v1.2.1 From 38563c1947e34b71bf5557f2cd22fb7806c60077 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 13 Aug 2013 10:32:24 +0200 Subject: update TODO --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index b845255d03..fdf9d7b88a 100644 --- a/TODO +++ b/TODO @@ -54,6 +54,8 @@ CGroup Rework Completion: Features: +* better error message if you run systemctl without systemd running + * rename F_TYPE_CMP() to F_TYPE_EQUAL() * unlink PID files of units after exit -- cgit v1.2.1 From ee530d8b73246f29781bd54a707ca75c7ef5a6cb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 13 Aug 2013 17:48:42 +0200 Subject: gpt-auto-generator: fix swap unit generation --- src/gpt-auto-generator/gpt-auto-generator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index 60fb19ee07..81d692c513 100644 --- a/src/gpt-auto-generator/gpt-auto-generator.c +++ b/src/gpt-auto-generator/gpt-auto-generator.c @@ -175,7 +175,7 @@ static int add_swap(const char *path, const char *fstype) { "DefaultDependencies=no\n" "Conflicts=" SPECIAL_UMOUNT_TARGET "\n" "Before=" SPECIAL_UMOUNT_TARGET " " SPECIAL_SWAP_TARGET "\n\n" - "[Mount]\n" + "[Swap]\n" "What=%s\n", path); -- cgit v1.2.1 From 405e0255d5e6950180d9563f1a26294b5360db03 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 13 Aug 2013 17:59:28 +0200 Subject: logind: restore logic to kill user processes when session ends --- man/logind.conf.xml | 101 +++++++++++++-------------------------------- src/core/dbus-kill.c | 27 ++++++++++-- src/login/logind-dbus.c | 13 ++++++ src/login/logind-session.c | 60 ++++++++++++++------------- src/login/logind-session.h | 2 + src/login/logind-user.c | 58 ++++++++++++++++---------- src/login/logind-user.h | 4 +- src/login/logind.c | 18 ++++++++ src/login/logind.h | 4 +- 9 files changed, 157 insertions(+), 130 deletions(-) diff --git a/man/logind.conf.xml b/man/logind.conf.xml index 8ab6d729a9..54cc379048 100644 --- a/man/logind.conf.xml +++ b/man/logind.conf.xml @@ -138,7 +138,34 @@ processes of a user should be killed when she or he completely logs out (i.e. after her/his last session ended). Defaults to - no. + no. + + Note that setting + KillUserProcesses=1 + will break tools like + screen1. + + + + KillOnlyUsers= + KillExcludeUsers= + + These settings take + space-separated lists of usernames + that influence the effect of + KillUserProcesses=. If + not empty, only processes of users + listed in + KillOnlyUsers= will + be killed when they log out + entirely. Processes of users listed in + KillExcludeUsers= + are excluded from being + killed. KillExcludeUsers= + defaults to root + and takes precedence over + KillOnlyUsers=, + which defaults to the empty list. @@ -179,64 +206,6 @@ idle. - - KillOnlyUsers= - KillExcludeUsers= - - These settings take - space-separated lists of usernames - that influence the effect of - KillUserProcesses=. If - not empty, only processes of users - listed in - KillOnlyUsers will - be killed when they log out - entirely. Processes of users listed in - KillExcludeUsers= - are excluded from being - killed. KillExcludeUsers= - defaults to root - and takes precedence over - KillOnlyUsers=, - which defaults to the empty list. - - - - Controllers= - ResetControllers= - - These settings control - the default control group hierarchies - users logging in are added to, in - addition to the - name=systemd named - hierarchy. These settings take - space-separated lists of controller - names. Pass the empty string to ensure - that logind does not touch any - hierarchies but systemd's own. When - logging in, user sessions will get - private control groups in all - hierarchies listed in - Controllers= and be - reset to the root control group in all - hierarchies listed in - ResetControllers=. - Controllers= - defaults to the empty list. - ResetControllers= - defaults to - cpu. Note that for - all controllers that are not listed in - either Controllers= - or - ResetControllers=, - newly created sessions will be part of - the control groups of the system - service that created the - session. - - InhibitDelayMaxSec= @@ -323,20 +292,6 @@ - - Note that setting - KillUserProcesses=1 will break tools - like - screen1. - - Note that KillUserProcesses=1 - is a weaker version of - kill-session-processes=1, which may - be configured per-service for - pam_systemd8. The - latter kills processes of a session as soon as it - ends, the former kills processes as soon as the last - session of the user ends. diff --git a/src/core/dbus-kill.c b/src/core/dbus-kill.c index 80e15e3fca..811adb1b5a 100644 --- a/src/core/dbus-kill.c +++ b/src/core/dbus-kill.c @@ -48,7 +48,28 @@ int bus_kill_context_set_transient_property( assert(name); assert(i); - if (streq(name, "SendSIGHUP")) { + if (streq(name, "KillMode")) { + const char *m; + KillMode k; + + if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(i, &m); + + k = kill_mode_from_string(m); + if (k < 0) + return -EINVAL; + + if (mode != UNIT_CHECK) { + c->kill_mode = k; + + unit_write_drop_in_private_format(u, mode, name, "KillMode=%s\n", kill_mode_to_string(k)); + } + + return 1; + + } else if (streq(name, "SendSIGHUP")) { if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_BOOLEAN) return -EINVAL; @@ -59,7 +80,7 @@ int bus_kill_context_set_transient_property( dbus_message_iter_get_basic(i, &b); c->send_sighup = b; - unit_write_drop_in_format(u, mode, name, "[Scope]\nSendSIGHUP=%s\n", yes_no(b)); + unit_write_drop_in_private_format(u, mode, name, "SendSIGHUP=%s\n", yes_no(b)); } return 1; @@ -75,7 +96,7 @@ int bus_kill_context_set_transient_property( dbus_message_iter_get_basic(i, &b); c->send_sigkill = b; - unit_write_drop_in_format(u, mode, name, "[Scope]\nSendSIGKILL4=%s\n", yes_no(b)); + unit_write_drop_in_private_format(u, mode, name, "SendSIGKILL=%s\n", yes_no(b)); } return 1; diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index ed5d8d888c..345df9f1cc 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -2523,6 +2523,7 @@ int manager_start_scope( const char *slice, const char *description, const char *after, + const char *kill_mode, DBusError *error, char **job) { @@ -2594,6 +2595,18 @@ int manager_start_scope( return log_oom(); } + if (!isempty(kill_mode)) { + const char *kill_mode_property = "KillMode"; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &kill_mode_property) || + !dbus_message_iter_open_container(&sub2, DBUS_TYPE_VARIANT, "s", &sub3) || + !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, &kill_mode) || + !dbus_message_iter_close_container(&sub2, &sub3) || + !dbus_message_iter_close_container(&sub, &sub2)) + return log_oom(); + } + /* cgroup empty notification is not available in containers * currently. To make this less problematic, let's shorten the * stop timeout for sessions, so that we don't wait diff --git a/src/login/logind-session.c b/src/login/logind-session.c index db22150825..1fea4745b6 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -32,7 +32,6 @@ #include "util.h" #include "mkdir.h" #include "path-util.h" -#include "cgroup-util.h" #include "fileio.h" #include "dbus-common.h" #include "logind-session.h" @@ -466,15 +465,20 @@ static int session_start_scope(Session *s) { if (!s->scope) { _cleanup_free_ char *description = NULL; + const char *kill_mode; char *scope, *job; + description = strjoin("Session ", s->id, " of user ", s->user->name, NULL); + if (!description) + return log_oom(); + scope = strjoin("session-", s->id, ".scope", NULL); if (!scope) return log_oom(); - description = strjoin("Session ", s->id, " of user ", s->user->name, NULL); + kill_mode = manager_shall_kill(s->manager, s->user->name) ? "control-group" : "none"; - r = manager_start_scope(s->manager, scope, s->leader, s->user->slice, description, "systemd-user-sessions.service", &error, &job); + r = manager_start_scope(s->manager, scope, s->leader, s->user->slice, description, "systemd-user-sessions.service", kill_mode, &error, &job); if (r < 0) { log_error("Failed to start session scope: %s %s", bus_error(&error, r), error.name); dbus_error_free(&error); @@ -554,21 +558,6 @@ int session_start(Session *s) { return 0; } -/* static bool session_shall_kill(Session *s) { */ -/* assert(s); */ - -/* if (!s->kill_processes) */ -/* return false; */ - -/* if (strv_contains(s->manager->kill_exclude_users, s->user->name)) */ -/* return false; */ - -/* if (strv_isempty(s->manager->kill_only_users)) */ -/* return true; */ - -/* return strv_contains(s->manager->kill_only_users, s->user->name); */ -/* } */ - static int session_stop_scope(Session *s) { DBusError error; char *job; @@ -617,7 +606,23 @@ static int session_unlink_x11_socket(Session *s) { } int session_stop(Session *s) { - int r = 0, k; + int r; + + assert(s); + + if (!s->user) + return -ESTALE; + + /* Kill cgroup */ + r = session_stop_scope(s); + + session_save(s); + + return r; +} + +int session_finalize(Session *s) { + int r = 0; assert(s); @@ -633,11 +638,6 @@ int session_stop(Session *s) { "MESSAGE=Removed session %s.", s->id, NULL); - /* Kill cgroup */ - k = session_stop_scope(s); - if (k < 0) - r = k; - /* Remove X11 symlink */ session_unlink_x11_socket(s); @@ -645,10 +645,10 @@ int session_stop(Session *s) { session_add_to_gc_queue(s); user_add_to_gc_queue(s->user); - if (s->started) + if (s->started) { session_send_signal(s, false); - - s->started = false; + s->started = false; + } if (s->seat) { if (s->seat->active == s) @@ -871,7 +871,6 @@ int session_check_gc(Session *s, bool drop_not_started) { return 0; if (s->fifo_fd >= 0) { - r = pipe_eof(s->fifo_fd); if (r < 0) return r; @@ -902,8 +901,11 @@ void session_add_to_gc_queue(Session *s) { SessionState session_get_state(Session *s) { assert(s); + if (s->closing) + return SESSION_CLOSING; + if (s->scope_job) - return s->started ? SESSION_OPENING : SESSION_CLOSING; + return SESSION_OPENING; if (s->fifo_fd < 0) return SESSION_CLOSING; diff --git a/src/login/logind-session.h b/src/login/logind-session.h index e2a46d5907..edaae8d20a 100644 --- a/src/login/logind-session.h +++ b/src/login/logind-session.h @@ -101,6 +101,7 @@ struct Session { bool in_gc_queue:1; bool started:1; + bool closing:1; DBusMessage *create_message; @@ -123,6 +124,7 @@ int session_create_fifo(Session *s); void session_remove_fifo(Session *s); int session_start(Session *s); int session_stop(Session *s); +int session_finalize(Session *s); int session_save(Session *s); int session_load(Session *s); int session_kill(Session *s, KillWho who, int signo); diff --git a/src/login/logind-user.c b/src/login/logind-user.c index 0a985a53ec..adbe638d46 100644 --- a/src/login/logind-user.c +++ b/src/login/logind-user.c @@ -490,21 +490,6 @@ static int user_stop_service(User *u) { return r; } -/* static int user_shall_kill(User *u) { */ -/* assert(u); */ - -/* if (!u->manager->kill_user_processes) */ -/* return false; */ - -/* if (strv_contains(u->manager->kill_exclude_users, u->name)) */ -/* return false; */ - -/* if (strv_isempty(u->manager->kill_only_users)) */ -/* return true; */ - -/* return strv_contains(u->manager->kill_only_users, u->name); */ -/* } */ - static int user_remove_runtime_path(User *u) { int r; @@ -528,9 +513,6 @@ int user_stop(User *u) { int r = 0, k; assert(u); - if (u->started) - log_debug("User %s logged out.", u->name); - LIST_FOREACH(sessions_by_user, s, u->sessions) { k = session_stop(s); if (k < 0) @@ -547,6 +529,26 @@ int user_stop(User *u) { if (k < 0) r = k; + user_save(u); + + return r; +} + +int user_finalize(User *u) { + Session *s; + int r = 0, k; + + assert(u); + + if (u->started) + log_debug("User %s logged out.", u->name); + + LIST_FOREACH(sessions_by_user, s, u->sessions) { + k = session_finalize(s); + if (k < 0) + r = k; + } + /* Kill XDG_RUNTIME_DIR */ k = user_remove_runtime_path(u); if (k < 0) @@ -555,10 +557,10 @@ int user_stop(User *u) { unlink(u->state_file); user_add_to_gc_queue(u); - if (u->started) + if (u->started) { user_send_signal(u, false); - - u->started = false; + u->started = false; + } return r; } @@ -624,6 +626,15 @@ int user_check_gc(User *u, bool drop_not_started) { if (user_check_linger_file(u) > 0) return 1; + if (u->slice_job || u->service_job) + return 1; + + if (u->slice && manager_unit_is_active(u->manager, u->slice) != 0) + return 1; + + if (u->service && manager_unit_is_active(u->manager, u->service) != 0) + return 1; + return 0; } @@ -643,8 +654,11 @@ UserState user_get_state(User *u) { assert(u); + if (u->closing) + return USER_CLOSING; + if (u->slice_job || u->service_job) - return u->started ? USER_OPENING : USER_CLOSING; + return USER_OPENING; LIST_FOREACH(sessions_by_user, i, u->sessions) { if (session_is_active(i)) diff --git a/src/login/logind-user.h b/src/login/logind-user.h index 889f828c42..b9171d345d 100644 --- a/src/login/logind-user.h +++ b/src/login/logind-user.h @@ -61,8 +61,7 @@ struct User { bool in_gc_queue:1; bool started:1; - bool slice_created:1; - bool service_created:1; + bool closing:1; LIST_HEAD(Session, sessions); LIST_FIELDS(User, gc_queue); @@ -74,6 +73,7 @@ int user_check_gc(User *u, bool drop_not_started); void user_add_to_gc_queue(User *u); int user_start(User *u); int user_stop(User *u); +int user_finalize(User *u); UserState user_get_state(User *u); int user_get_idle_hint(User *u, dual_timestamp *t); int user_save(User *u); diff --git a/src/login/logind.c b/src/login/logind.c index a79ba333d2..0002d262c1 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -1244,6 +1244,7 @@ void manager_gc(Manager *m, bool drop_not_started) { if (session_check_gc(session, drop_not_started) == 0) { session_stop(session); + session_finalize(session); session_free(session); } } @@ -1254,6 +1255,7 @@ void manager_gc(Manager *m, bool drop_not_started) { if (user_check_gc(user, drop_not_started) == 0) { user_stop(user); + user_finalize(user); user_free(user); } } @@ -1298,6 +1300,22 @@ int manager_get_idle_hint(Manager *m, dual_timestamp *t) { return idle_hint; } +bool manager_shall_kill(Manager *m, const char *user) { + assert(m); + assert(user); + + if (!m->kill_user_processes) + return false; + + if (strv_contains(m->kill_exclude_users, user)) + return false; + + if (strv_isempty(m->kill_only_users)) + return true; + + return strv_contains(m->kill_only_users, user); +} + int manager_dispatch_idle_action(Manager *m) { struct dual_timestamp since; struct itimerspec its = {}; diff --git a/src/login/logind.h b/src/login/logind.h index 9c41cdf70c..e9838a8afd 100644 --- a/src/login/logind.h +++ b/src/login/logind.h @@ -163,6 +163,8 @@ int manager_spawn_autovt(Manager *m, int vtnr); void manager_gc(Manager *m, bool drop_not_started); +bool manager_shall_kill(Manager *m, const char *user); + int manager_get_idle_hint(Manager *m, dual_timestamp *t); int manager_get_user_by_pid(Manager *m, pid_t pid, User **user); @@ -178,7 +180,7 @@ int manager_send_changed(Manager *manager, const char *properties); int manager_dispatch_delayed(Manager *manager); -int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, const char *after, DBusError *error, char **job); +int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, const char *after, const char *kill_mode, DBusError *error, char **job); int manager_start_unit(Manager *manager, const char *unit, DBusError *error, char **job); int manager_stop_unit(Manager *manager, const char *unit, DBusError *error, char **job); int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, DBusError *error); -- cgit v1.2.1 From 3731acf1acfb4a6eb68374a5b137f3b368f63381 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 14 Aug 2013 01:57:02 +0200 Subject: backlight: add minimal tool to save/restore screen brightness across reboots As many laptops don't save/restore screen brightness across reboots, let's do this in systemd with a minimal tool, that restores the brightness as early as possible, and saves it as late as possible. This will cover consoles and graphical logins, but graphical desktops should do their own per-user stuff probably. This only touches firmware brightness controls for now. --- .gitignore | 1 + Makefile.am | 20 ++++++ configure.ac | 9 +++ rules/99-systemd.rules.in | 4 ++ rules/Makefile | 1 + src/backlight/Makefile | 1 + src/backlight/backlight.c | 126 ++++++++++++++++++++++++++++++++++++ units/.gitignore | 1 + units/systemd-backlight@.service.in | 21 ++++++ 9 files changed, 184 insertions(+) create mode 120000 rules/Makefile create mode 120000 src/backlight/Makefile create mode 100644 src/backlight/backlight.c create mode 100644 units/systemd-backlight@.service.in diff --git a/.gitignore b/.gitignore index dc5d735f08..61bc2a3494 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ /systemd-ac-power /systemd-analyze /systemd-ask-password +/systemd-backlight /systemd-binfmt /systemd-bootchart /systemd-cat diff --git a/Makefile.am b/Makefile.am index c19d596120..fa4fea95ee 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3313,6 +3313,26 @@ endif EXTRA_DIST += \ units/systemd-random-seed.service.in +# ------------------------------------------------------------------------------ +if ENABLE_BACKLIGHT +rootlibexec_PROGRAMS += \ + systemd-backlight + +nodist_systemunit_DATA += \ + units/systemd-backlight@.service + +systemd_backlight_SOURCES = \ + src/backlight/backlight.c + +systemd_backlight_LDADD = \ + libsystemd-label.la \ + libsystemd-shared.la \ + libudev-private.la +endif + +EXTRA_DIST += \ + units/systemd-backlight@.service.in + # ------------------------------------------------------------------------------ if HAVE_LIBCRYPTSETUP rootlibexec_PROGRAMS += \ diff --git a/configure.ac b/configure.ac index 0ecc71632b..6ef6382c4c 100644 --- a/configure.ac +++ b/configure.ac @@ -670,6 +670,14 @@ if test "x$enable_randomseed" != "xno"; then fi AM_CONDITIONAL(ENABLE_RANDOMSEED, [test "$have_randomseed" = "yes"]) +# ------------------------------------------------------------------------------ +have_backlight=no +AC_ARG_ENABLE(backlight, AS_HELP_STRING([--disable-backlight], [disable backlight tools])) +if test "x$enable_backlight" != "xno"; then + have_backlight=yes +fi +AM_CONDITIONAL(ENABLE_BACKLIGHT, [test "$have_backlight" = "yes"]) + # ------------------------------------------------------------------------------ have_logind=no AC_ARG_ENABLE(logind, AS_HELP_STRING([--disable-logind], [disable login daemon])) @@ -1001,6 +1009,7 @@ AC_MSG_RESULT([ quotacheck: ${have_quotacheck} tmpfiles: ${have_tmpfiles} randomseed: ${have_randomseed} + backlight: ${have_backlight} logind: ${have_logind} machined: ${have_machined} hostnamed: ${have_hostnamed} diff --git a/rules/99-systemd.rules.in b/rules/99-systemd.rules.in index e9b2da7b39..ac4bc86c81 100644 --- a/rules/99-systemd.rules.in +++ b/rules/99-systemd.rules.in @@ -51,6 +51,10 @@ SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{ID_USB_INTERFACES}=="*:0701??: ACTION=="add", SUBSYSTEM=="net", KERNEL!="lo", RUN+="@rootlibexecdir@/systemd-sysctl --prefix=/proc/sys/net/ipv4/conf/$name --prefix=/proc/sys/net/ipv4/neigh/$name --prefix=/proc/sys/net/ipv6/conf/$name --prefix=/proc/sys/net/ipv6/neigh/$name" +# Pull in backlight save/restore for all firmware backlight devices + +ACTION=="add", SUBSYSTEM=="backlight", ATTR{type}=="firmware", TAG+="systemd", ENV{SYSTEMD_WANTS}+="systemd-backlight@sys%p.service" + # Asynchronously mount file systems implemented by these modules as # soon as they are loaded. diff --git a/rules/Makefile b/rules/Makefile new file mode 120000 index 0000000000..bd1047548b --- /dev/null +++ b/rules/Makefile @@ -0,0 +1 @@ +../src/Makefile \ No newline at end of file diff --git a/src/backlight/Makefile b/src/backlight/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/backlight/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/backlight/backlight.c b/src/backlight/backlight.c new file mode 100644 index 0000000000..3378907f91 --- /dev/null +++ b/src/backlight/backlight.c @@ -0,0 +1,126 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include + +#include "util.h" +#include "mkdir.h" +#include "fileio.h" + +int main(int argc, char *argv[]) { + struct udev *udev = NULL; + struct udev_device *device = NULL; + _cleanup_free_ char *saved = NULL; + int r; + + if (argc != 3) { + log_error("This program requires two arguments."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + r = mkdir_p("/var/lib/backlight", 0755); + if (r < 0) { + log_error("Failed to create backlight directory: %s", strerror(-r)); + goto finish; + } + + udev = udev_new(); + if (!udev) { + r = log_oom(); + goto finish; + } + + device = udev_device_new_from_syspath(udev, argv[2]); + if (!device) { + r = log_oom(); + goto finish; + } + + if (!streq_ptr(udev_device_get_subsystem(device), "backlight")) { + log_error("Not a backlight device: %s", argv[2]); + r = -ENODEV; + goto finish; + } + + saved = strappend("/var/lib/backlight/", udev_device_get_sysname(device)); + if (!saved) { + r = log_oom(); + goto finish; + } + + if (streq(argv[1], "load")) { + _cleanup_free_ char *value = NULL; + + r = read_one_line_file(saved, &value); + if (r < 0) { + + if (r == -ENOENT) { + r = 0; + goto finish; + } + + log_error("Failed to read %s: %s", saved, strerror(-r)); + goto finish; + } + + r = udev_device_set_sysattr_value(device, "brightness", value); + if (r < 0) { + log_error("Failed to write system attribute: %s", strerror(-r)); + goto finish; + } + + } else if (streq(argv[1], "save")) { + const char *value; + + value = udev_device_get_sysattr_value(device, "brightness"); + if (!value) { + log_error("Failed to read system attribute: %s", strerror(-r)); + goto finish; + } + + r = write_string_file(saved, value); + if (r < 0) { + log_error("Failed to write %s: %s", saved, strerror(-r)); + goto finish; + } + + } else { + log_error("Unknown verb %s.", argv[1]); + r = -EINVAL; + goto finish; + } + +finish: + if (device) + udev_device_unref(device); + + if (udev) + udev_unref(udev); + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; + +} diff --git a/units/.gitignore b/units/.gitignore index 9aee00f2a4..9c65075c0a 100644 --- a/units/.gitignore +++ b/units/.gitignore @@ -1,3 +1,4 @@ +/systemd-backlight@.service /halt-local.service /rc-local.service /systemd-hybrid-sleep.service diff --git a/units/systemd-backlight@.service.in b/units/systemd-backlight@.service.in new file mode 100644 index 0000000000..14b12198e8 --- /dev/null +++ b/units/systemd-backlight@.service.in @@ -0,0 +1,21 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Load/Save Screen Backlight Brightness of %f +Documentation=man:systemd-backlight@.service(8) +DefaultDependencies=no +RequiresMountsFor=/var/lib/backlight +Conflicts=shutdown.target +After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service +Before=sysinit.target shutdown.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=@rootlibexecdir@/systemd-backlight load %f +ExecStop=@rootlibexecdir@/systemd-backlight save %f -- cgit v1.2.1 From 875c6e1b48f37a07dfbb80d6653c73f205e94260 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 14 Aug 2013 02:55:57 +0200 Subject: backlight: instead of syspath use sysname for identifying backlight devices This makes the description string of the backlight service a bit nicer. --- rules/99-systemd.rules.in | 2 +- src/backlight/backlight.c | 10 ++++++++-- units/systemd-backlight@.service.in | 6 +++--- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/rules/99-systemd.rules.in b/rules/99-systemd.rules.in index ac4bc86c81..bbb7d0c2c3 100644 --- a/rules/99-systemd.rules.in +++ b/rules/99-systemd.rules.in @@ -53,7 +53,7 @@ ACTION=="add", SUBSYSTEM=="net", KERNEL!="lo", RUN+="@rootlibexecdir@/systemd-sy # Pull in backlight save/restore for all firmware backlight devices -ACTION=="add", SUBSYSTEM=="backlight", ATTR{type}=="firmware", TAG+="systemd", ENV{SYSTEMD_WANTS}+="systemd-backlight@sys%p.service" +ACTION=="add", SUBSYSTEM=="backlight", ATTR{type}=="firmware", TAG+="systemd", ENV{SYSTEMD_WANTS}+="systemd-backlight@$name.service" # Asynchronously mount file systems implemented by these modules as # soon as they are loaded. diff --git a/src/backlight/backlight.c b/src/backlight/backlight.c index 3378907f91..1ef0b45cc6 100644 --- a/src/backlight/backlight.c +++ b/src/backlight/backlight.c @@ -54,9 +54,15 @@ int main(int argc, char *argv[]) { goto finish; } - device = udev_device_new_from_syspath(udev, argv[2]); + errno = 0; + device = udev_device_new_from_subsystem_sysname(udev, "backlight", argv[2]); if (!device) { - r = log_oom(); + if (errno != 0) { + log_error("Failed to get backlight device: %m"); + r = -errno; + } else + r = log_oom(); + goto finish; } diff --git a/units/systemd-backlight@.service.in b/units/systemd-backlight@.service.in index 14b12198e8..b0e75db39e 100644 --- a/units/systemd-backlight@.service.in +++ b/units/systemd-backlight@.service.in @@ -6,7 +6,7 @@ # (at your option) any later version. [Unit] -Description=Load/Save Screen Backlight Brightness of %f +Description=Load/Save Screen Backlight Brightness of %I Documentation=man:systemd-backlight@.service(8) DefaultDependencies=no RequiresMountsFor=/var/lib/backlight @@ -17,5 +17,5 @@ Before=sysinit.target shutdown.target [Service] Type=oneshot RemainAfterExit=yes -ExecStart=@rootlibexecdir@/systemd-backlight load %f -ExecStop=@rootlibexecdir@/systemd-backlight save %f +ExecStart=@rootlibexecdir@/systemd-backlight load %I +ExecStop=@rootlibexecdir@/systemd-backlight save %I -- cgit v1.2.1 From 38e19f93501d5a23d2176be30eea82e1be999f3d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 14 Aug 2013 03:11:30 +0200 Subject: man: add man page for systemd-backlight@.service --- Makefile-man.am | 11 ++++++ man/systemd-backlight@.service.xml | 73 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 man/systemd-backlight@.service.xml diff --git a/Makefile-man.am b/Makefile-man.am index a8d418fda6..4ebc76837e 100644 --- a/Makefile-man.am +++ b/Makefile-man.am @@ -601,6 +601,17 @@ man/systemd-user.conf.html: man/systemd-system.conf.html $(html-alias) +if ENABLE_BACKLIGHT +MANPAGES += \ + man/systemd-backlight@.service.8 +MANPAGES_ALIAS += \ + man/systemd-backlight.8 +man/systemd-backlight.8: man/systemd-backlight@.service.8 +man/systemd-backlight.html: man/systemd-backlight@.service.html + $(html-alias) + +endif + if ENABLE_BINFMT MANPAGES += \ man/binfmt.d.5 \ diff --git a/man/systemd-backlight@.service.xml b/man/systemd-backlight@.service.xml new file mode 100644 index 0000000000..f2f54728a3 --- /dev/null +++ b/man/systemd-backlight@.service.xml @@ -0,0 +1,73 @@ + + + + + + + + systemd-backlight@.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-backlight@.service + 8 + + + + systemd-backlight@.service + systemd-backlight + Load and save the display backlight brightness at boot and shutdown + + + + systemd-backlight@.service + /usr/lib/systemd/systemd-backlight + + + + Description + + systemd-backlight@.service + is a service that restores the display backlight + brightness at early-boot and saves it at shutdown. On + disk the backlight brightness is stored in + /var/lib/backlight/. Note that by + default only firmware backlight devices are + saved/restored. + + + + See Also + + systemd1 + + + + -- cgit v1.2.1 From 22d0d443b6fbdd319e4c6e0124e6acec086db3fa Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 14 Aug 2013 03:31:06 +0200 Subject: man: document systemd-efi-boot-generator --- Makefile-man.am | 1 + man/systemd-efi-boot-generator.xml | 87 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 man/systemd-efi-boot-generator.xml diff --git a/Makefile-man.am b/Makefile-man.am index 4ebc76837e..235b5a1342 100644 --- a/Makefile-man.am +++ b/Makefile-man.am @@ -52,6 +52,7 @@ MANPAGES += \ man/systemd-cgtop.1 \ man/systemd-delta.1 \ man/systemd-detect-virt.1 \ + man/systemd-efi-boot-generator.8 \ man/systemd-fsck@.service.8 \ man/systemd-fstab-generator.8 \ man/systemd-getty-generator.8 \ diff --git a/man/systemd-efi-boot-generator.xml b/man/systemd-efi-boot-generator.xml new file mode 100644 index 0000000000..d5e5aeff3e --- /dev/null +++ b/man/systemd-efi-boot-generator.xml @@ -0,0 +1,87 @@ + + + + + + + + systemd-efi-boot-generator + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-efi-boot-generator + 8 + + + + systemd-efi-boot-generator + Generator for automatically mounting the + EFI System Partition used by the current boot to + /boot + + + + /usr/lib/systemd/system-generators/systemd-efi-boot-generator + + + + Description + + systemd-efi-boot-generator + is a generator that automatically creates mount and + automount units for the EFI System Partition (ESP) + mounting it to /boot. Note that + this generator will execute no operation on non-EFI + systems, on systems where the boot loader does not + communicate the used ESP to the OS, on systems where + /boot is an explicitly configured + mount (for example, listed in fstab5) or where the /boot mount + point is non-empty. Since this generator creates an + automount unit the mount will only be activated + on-demand, when accessed. + + systemd-efi-boot-generator + implements the generator + specification. + + + + See Also + + systemd1, + systemd.mount5, + systemd.automount5, + gummiboot8, + fstab5 + + + + -- cgit v1.2.1 From d67ca9ab8472ab012ac460555225924f6337e962 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 13 Aug 2013 21:57:43 +0200 Subject: man; document gpt-auto-generator --- Makefile-man.am | 1 + man/systemd-efi-boot-generator.xml | 1 + man/systemd-gpt-auto-generator.xml | 99 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 man/systemd-gpt-auto-generator.xml diff --git a/Makefile-man.am b/Makefile-man.am index 235b5a1342..1c264fa3fb 100644 --- a/Makefile-man.am +++ b/Makefile-man.am @@ -56,6 +56,7 @@ MANPAGES += \ man/systemd-fsck@.service.8 \ man/systemd-fstab-generator.8 \ man/systemd-getty-generator.8 \ + man/systemd-gpt-auto-generator.8 \ man/systemd-halt.service.8 \ man/systemd-inhibit.1 \ man/systemd-initctl.service.8 \ diff --git a/man/systemd-efi-boot-generator.xml b/man/systemd-efi-boot-generator.xml index d5e5aeff3e..03a4fdd0b8 100644 --- a/man/systemd-efi-boot-generator.xml +++ b/man/systemd-efi-boot-generator.xml @@ -79,6 +79,7 @@ systemd1, systemd.mount5, systemd.automount5, + systemd-gpt-auto-generator8, gummiboot8, fstab5 diff --git a/man/systemd-gpt-auto-generator.xml b/man/systemd-gpt-auto-generator.xml new file mode 100644 index 0000000000..fb25444645 --- /dev/null +++ b/man/systemd-gpt-auto-generator.xml @@ -0,0 +1,99 @@ + + + + + + + + systemd-gpt-auto-generator + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-gpt-auto-generator + 8 + + + + systemd-gpt-auto-generator + Generator for automatically discovering + and mounting /home as well as + discovering and enabling swap partitions, based on GPT + partition type GUIDs. + + + + /usr/lib/systemd/system-generators/systemd-gpt-auto-generator + + + + Description + + systemd-gpt-auto-generator + is a generator that automatically discovers + /home and swap partitions and + creates mount and swap units for them, based on the + the partition type GUIDs of GUID partition tables + (GPT). Note that this generator will execute no + operation on non-GPT systems, on systems where the + units are explicitly configured (for example, listed + in + fstab5) + or where the mount point is non-empty. + + This generator will only look for partitions on + the same physical disk the root file system is stored + on. This generator has no effect on systems where the + root file system is distributed on multiple disks, for + example via btrfs RAID. + + This generator is useful for centralizing file + system configuration in the partition table and making + manual configuration in + /etc/fstab or suchlike + unnecessary. + + systemd-gpt-auto-generator + implements the generator + specification. + + + + See Also + + systemd1, + systemd.mount5, + systemd.swap5, + systemd-efi-boot-generator8, + fstab5 + + + + -- cgit v1.2.1 From ce1794704574e73efb813c6ed113554870f2e747 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 13 Aug 2013 22:01:55 +0200 Subject: random-seed: a few modernizations --- src/random-seed/random-seed.c | 87 ++++++++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 35 deletions(-) diff --git a/src/random-seed/random-seed.c b/src/random-seed/random-seed.c index fdcaa1e154..4776c071ca 100644 --- a/src/random-seed/random-seed.c +++ b/src/random-seed/random-seed.c @@ -32,11 +32,11 @@ #define POOL_SIZE_MIN 512 int main(int argc, char *argv[]) { - int seed_fd = -1, random_fd = -1; - int ret = EXIT_FAILURE; - void* buf; + _cleanup_close_ int seed_fd = -1, random_fd = -1; + _cleanup_free_ void* buf = NULL; size_t buf_size = 0; - ssize_t r; + ssize_t k; + int r; FILE *f; if (argc != 2) { @@ -51,7 +51,8 @@ int main(int argc, char *argv[]) { umask(0022); /* Read pool size, if possible */ - if ((f = fopen("/proc/sys/kernel/random/poolsize", "re"))) { + f = fopen("/proc/sys/kernel/random/poolsize", "re"); + if (f) { if (fscanf(f, "%zu", &buf_size) > 0) { /* poolsize is in bits on 2.6, but we want bytes */ buf_size /= 8; @@ -63,13 +64,15 @@ int main(int argc, char *argv[]) { if (buf_size <= POOL_SIZE_MIN) buf_size = POOL_SIZE_MIN; - if (!(buf = malloc(buf_size))) { - log_error("Failed to allocate buffer."); + buf = malloc(buf_size); + if (!buf) { + r = log_oom(); goto finish; } - if (mkdir_parents_label(RANDOM_SEED, 0755) < 0) { - log_error("Failed to create directories parents of %s: %m", RANDOM_SEED); + r = mkdir_parents_label(RANDOM_SEED, 0755); + if (r < 0) { + log_error("Failed to create parent directory of " RANDOM_SEED ": %s", strerror(-r)); goto finish; } @@ -79,45 +82,64 @@ int main(int argc, char *argv[]) { if (streq(argv[1], "load")) { - if ((seed_fd = open(RANDOM_SEED, O_RDWR|O_CLOEXEC|O_NOCTTY|O_CREAT, 0600)) < 0) { - if ((seed_fd = open(RANDOM_SEED, O_RDONLY|O_CLOEXEC|O_NOCTTY)) < 0) { + seed_fd = open(RANDOM_SEED, O_RDWR|O_CLOEXEC|O_NOCTTY|O_CREAT, 0600); + if (seed_fd < 0) { + seed_fd = open(RANDOM_SEED, O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (seed_fd < 0) { log_error("Failed to open random seed: %m"); + r = -errno; goto finish; } } - if ((random_fd = open("/dev/urandom", O_RDWR|O_CLOEXEC|O_NOCTTY, 0600)) < 0) { - if ((random_fd = open("/dev/urandom", O_WRONLY|O_CLOEXEC|O_NOCTTY, 0600)) < 0) { + random_fd = open("/dev/urandom", O_RDWR|O_CLOEXEC|O_NOCTTY, 0600); + if (random_fd < 0) { + random_fd = open("/dev/urandom", O_WRONLY|O_CLOEXEC|O_NOCTTY, 0600); + if (random_fd < 0) { log_error("Failed to open /dev/urandom: %m"); + r = -errno; goto finish; } } - if ((r = loop_read(seed_fd, buf, buf_size, false)) <= 0) { + k = loop_read(seed_fd, buf, buf_size, false); + if (k <= 0) { if (r != 0) log_error("Failed to read seed file: %m"); + + r = k == 0 ? -EIO : (int) k; + } else { lseek(seed_fd, 0, SEEK_SET); - if ((r = loop_write(random_fd, buf, (size_t) r, false)) <= 0) - log_error("Failed to write seed to /dev/urandom: %s", - r < 0 ? strerror(errno) : "short write"); + k = loop_write(random_fd, buf, (size_t) k, false); + if (k <= 0) { + log_error("Failed to write seed to /dev/urandom: %s", r < 0 ? strerror(-r) : "short write"); + + r = k == 0 ? -EIO : (int) k; + } } } else if (streq(argv[1], "save")) { - if ((seed_fd = open(RANDOM_SEED, O_WRONLY|O_CLOEXEC|O_NOCTTY|O_CREAT, 0600)) < 0) { + seed_fd = open(RANDOM_SEED, O_WRONLY|O_CLOEXEC|O_NOCTTY|O_CREAT, 0600); + if (seed_fd < 0) { log_error("Failed to open random seed: %m"); + r = -errno; goto finish; } - if ((random_fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY)) < 0) { + random_fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (random_fd < 0) { log_error("Failed to open /dev/urandom: %m"); + r = -errno; goto finish; } + } else { log_error("Unknown verb %s.", argv[1]); + r = -EINVAL; goto finish; } @@ -127,23 +149,18 @@ int main(int argc, char *argv[]) { fchmod(seed_fd, 0600); fchown(seed_fd, 0, 0); - if ((r = loop_read(random_fd, buf, buf_size, false)) <= 0) - log_error("Failed to read new seed from /dev/urandom: %s", r < 0 ? strerror(errno) : "EOF"); - else { - if ((r = loop_write(seed_fd, buf, (size_t) r, false)) <= 0) - log_error("Failed to write new random seed file: %s", r < 0 ? strerror(errno) : "short write"); + k = loop_read(random_fd, buf, buf_size, false); + if (k <= 0) { + log_error("Failed to read new seed from /dev/urandom: %s", r < 0 ? strerror(-r) : "EOF"); + r = k == 0 ? -EIO : (int) k; + } else { + r = loop_write(seed_fd, buf, (size_t) k, false); + if (r <= 0) { + log_error("Failed to write new random seed file: %s", r < 0 ? strerror(-r) : "short write"); + r = k == 0 ? -EIO : (int) k; + } } - ret = EXIT_SUCCESS; - finish: - if (random_fd >= 0) - close_nointr_nofail(random_fd); - - if (seed_fd >= 0) - close_nointr_nofail(seed_fd); - - free(buf); - - return ret; + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; } -- cgit v1.2.1 From 8410d73f06cbd80a6918dd2b6d90ef95bbd18de7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 13 Aug 2013 22:09:45 +0200 Subject: man: document the GPT partition types gpt-auto-generator looks for --- man/systemd-gpt-auto-generator.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/man/systemd-gpt-auto-generator.xml b/man/systemd-gpt-auto-generator.xml index fb25444645..95c0c35046 100644 --- a/man/systemd-gpt-auto-generator.xml +++ b/man/systemd-gpt-auto-generator.xml @@ -79,6 +79,11 @@ /etc/fstab or suchlike unnecessary. + This generator looks for swap partitions using + GPT type 0657fd6d-a4ab-43c4-84e50933c84b4f4f. It looks + for /home partitions using GPT + type 933ac7e1-2eb4-4f13-b8440e14e2aef915. + systemd-gpt-auto-generator implements the generator -- cgit v1.2.1 From 03e22642617f360a6b55cb853bcf59604754ea5d Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 14 Aug 2013 22:34:41 +0200 Subject: selinux-access: move GPL to LGPL licence On Wed, Aug 14, 2013 at 10:31 PM, Daniel J Walsh wrote: > On 08/14/2013 04:17 PM, Kay Sievers wrote: > > > > this patch added GPL code to systemd, which otherwise is all LGPL. We need > > to make sure we can always split out any code to a separate shared library > > ... > > > > Mind if I switch your src/core/selinux-access.[ch] files to LGPL? > I have no problem with it. Should be LGPL anyways. --- src/core/selinux-access.c | 8 ++++---- src/core/selinux-access.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/core/selinux-access.c b/src/core/selinux-access.c index 426aed07d2..0a3ee18bb9 100644 --- a/src/core/selinux-access.c +++ b/src/core/selinux-access.c @@ -6,16 +6,16 @@ Copyright 2012 Dan Walsh 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 + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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. + Lesser General Public License for more details. - You should have received a copy of the GNU General Public License + You should have received a copy of the GNU Lesser General Public License along with systemd; If not, see . ***/ diff --git a/src/core/selinux-access.h b/src/core/selinux-access.h index 9183cbc9a6..2d7ac64c8f 100644 --- a/src/core/selinux-access.h +++ b/src/core/selinux-access.h @@ -8,16 +8,16 @@ Copyright 2012 Dan Walsh 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 + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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. + Lesser General Public License for more details. - You should have received a copy of the GNU General Public License + You should have received a copy of the GNU Lesser General Public License along with systemd; If not, see . ***/ -- cgit v1.2.1 From 0228a7e56a618aed45940f6ec61b24d34fff7dc5 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 14 Aug 2013 22:55:40 +0200 Subject: test: add licence header and switch to LGPL Checked with and got OK from Martin. --- test/rule-syntax-check.py | 21 ++++++++++----------- test/rules-test.sh | 13 +++++++++++++ 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/test/rule-syntax-check.py b/test/rule-syntax-check.py index b18f8780cb..ce4f5c75ad 100755 --- a/test/rule-syntax-check.py +++ b/test/rule-syntax-check.py @@ -4,19 +4,18 @@ # (C) 2010 Canonical Ltd. # Author: Martin Pitt # -# 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 +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 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 +# Lesser General Public License for more details. # -# 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. +# You should have received a copy of the GNU Lesser General Public License +# along with systemd; If not, see . import re import sys diff --git a/test/rules-test.sh b/test/rules-test.sh index 1e224ff8b5..47d42cb3fa 100755 --- a/test/rules-test.sh +++ b/test/rules-test.sh @@ -3,6 +3,19 @@ # # (C) 2010 Canonical Ltd. # Author: Martin Pitt +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with systemd; If not, see . [ -n "$srcdir" ] || srcdir=`dirname $0`/.. -- cgit v1.2.1 From 85424725d1870e2c218e3e2d53971f7e5dc3f0ae Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 14 Aug 2013 22:58:21 +0200 Subject: README: update list of used LICENSEs --- README | 4 +++- TODO | 3 --- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/README b/README index 0d7db41160..a16f342ecf 100644 --- a/README +++ b/README @@ -31,7 +31,9 @@ AUTHOR: LICENSE: LGPLv2.1+ for all code - except sd-daemon.[ch] and sd-readahead.[ch] which are MIT - - except src/udev/ which is (currently still) GPLv2+ + - except src/shared/MurmurHash3.c which is Public Domain + - except src/journal/lookup3.c which is Public Domain + - except src/udev/* which is (currently still) GPLv2, GPLv2+ REQUIREMENTS: Linux kernel >= 3.0 diff --git a/TODO b/TODO index fdf9d7b88a..f6e7566bb6 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,4 @@ Bugfixes: -* update COPYRIGHT in our README: - http://ftp-master.metadata.debian.org/changelogs//main/s/systemd/systemd_204-2_copyright - * the running hwdb seems not to pick up updated database files without an explicit: udevadm control --reload -- cgit v1.2.1 From 960787ae27af395c28fb1ce9de5a575ebfb27a4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 14 Aug 2013 18:55:11 -0400 Subject: hostnamectl: show only specific hostname when requested Existing --pretty, --transient, --static options, used previously for 'set-hostname' verb, are reused for the 'status' verb. If one of them is given, only the specified hostname is printed. This way there's no need to employ awk to get the hostname in a script. --- man/hostnamectl.xml | 25 ++++++++--- src/hostname/hostnamectl.c | 106 ++++++++++++++++++++++++++++++++++----------- src/test/test-libudev.c | 2 +- 3 files changed, 100 insertions(+), 33 deletions(-) diff --git a/man/hostnamectl.xml b/man/hostnamectl.xml index f28e430a42..b39fb5502b 100644 --- a/man/hostnamectl.xml +++ b/man/hostnamectl.xml @@ -49,7 +49,9 @@ - hostnamectl OPTIONS COMMAND + hostnamectl + OPTIONS + COMMAND @@ -81,7 +83,7 @@ /etc/hostname, see hostname5 for more information. The pretty hostname, chassis - type and icon name are stored in + type, and icon name are stored in /etc/machine-info, see machine-id5. @@ -141,11 +143,20 @@ If - set-hostname is - invoked and one or more of these - options are passed, only the selected - hostname(s) is/are - updated. + status is used (or + no explicit command is given) and one + of those fields is given, + hostnamectl will + print out just this selected + hostname. + + If used with + set-hostname, only + the selected hostname(s) will be + updated. When more than one of those + options is used, all the specified + hostnames will be updated. + diff --git a/src/hostname/hostnamectl.c b/src/hostname/hostnamectl.c index f7d844b975..66015c2f4c 100644 --- a/src/hostname/hostnamectl.c +++ b/src/hostname/hostnamectl.c @@ -46,9 +46,9 @@ static enum transport { static bool arg_ask_password = true; static char *arg_host = NULL; static char *arg_user = NULL; -static bool arg_set_transient = false; -static bool arg_set_pretty = false; -static bool arg_set_static = false; +static bool arg_transient = false; +static bool arg_pretty = false; +static bool arg_static = false; static void polkit_agent_open_if_enabled(void) { @@ -152,15 +152,52 @@ static int status_property(const char *name, DBusMessageIter *iter, StatusInfo * return 0; } -static int show_status(DBusConnection *bus, char **args, unsigned n) { +static int show_one_name(DBusConnection *bus, const char* attr) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + const char *interface = "org.freedesktop.hostname1", *s; + DBusMessageIter iter, sub; + int r; + + r = bus_method_call_with_reply( + bus, + "org.freedesktop.hostname1", + "/org/freedesktop/hostname1", + "org.freedesktop.DBus.Properties", + "Get", + &reply, + NULL, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_STRING, &attr, + DBUS_TYPE_INVALID); + if (r < 0) + return r; + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) { + log_error("Failed to parse reply."); + return -EIO; + } + + dbus_message_iter_recurse(&iter, &sub); + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) { + log_error("Failed to parse reply."); + return -EIO; + } + + dbus_message_iter_get_basic(&sub, &s); + printf("%s\n", s); + + return 0; +} + +static int show_all_names(DBusConnection *bus) { _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; const char *interface = ""; int r; DBusMessageIter iter, sub, sub2, sub3; StatusInfo info = {}; - assert(args); - r = bus_method_call_with_reply( bus, "org.freedesktop.hostname1", @@ -218,6 +255,25 @@ static int show_status(DBusConnection *bus, char **args, unsigned n) { return 0; } +static int show_status(DBusConnection *bus, char **args, unsigned n) { + assert(args); + + if (arg_pretty || arg_static || arg_transient) { + const char *attr; + + if (!!arg_static + !!arg_pretty + !!arg_transient > 1) { + log_error("Cannot query more than one name type at a time"); + return -EINVAL; + } + + attr = arg_pretty ? "PrettyHostname" : + arg_static ? "StaticHostname" : "Hostname"; + + return show_one_name(bus, attr); + } else + return show_all_names(bus); +} + static int set_hostname(DBusConnection *bus, char **args, unsigned n) { _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; dbus_bool_t interactive = arg_ask_password; @@ -230,7 +286,10 @@ static int set_hostname(DBusConnection *bus, char **args, unsigned n) { polkit_agent_open_if_enabled(); - if (arg_set_pretty) { + if (!arg_pretty && !arg_static && !arg_transient) + arg_pretty = arg_static = arg_transient = true; + + if (arg_pretty) { const char *p; /* If the passed hostname is already valid, then @@ -245,7 +304,7 @@ static int set_hostname(DBusConnection *bus, char **args, unsigned n) { hostname_cleanup(h, true); - if (arg_set_static && streq(h, hostname)) + if (arg_static && streq(h, hostname)) p = ""; else { p = hostname; @@ -270,7 +329,7 @@ static int set_hostname(DBusConnection *bus, char **args, unsigned n) { reply = NULL; } - if (arg_set_static) { + if (arg_static) { r = bus_method_call_with_reply( bus, "org.freedesktop.hostname1", @@ -290,7 +349,7 @@ static int set_hostname(DBusConnection *bus, char **args, unsigned n) { reply = NULL; } - if (arg_set_transient) { + if (arg_transient) { r = bus_method_call_with_reply( bus, "org.freedesktop.hostname1", @@ -381,17 +440,17 @@ static int parse_argv(int argc, char *argv[]) { enum { ARG_VERSION = 0x100, ARG_NO_ASK_PASSWORD, - ARG_SET_TRANSIENT, - ARG_SET_STATIC, - ARG_SET_PRETTY + ARG_TRANSIENT, + ARG_STATIC, + ARG_PRETTY }; static const struct option options[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, ARG_VERSION }, - { "transient", no_argument, NULL, ARG_SET_TRANSIENT }, - { "static", no_argument, NULL, ARG_SET_STATIC }, - { "pretty", no_argument, NULL, ARG_SET_PRETTY }, + { "transient", no_argument, NULL, ARG_TRANSIENT }, + { "static", no_argument, NULL, ARG_STATIC }, + { "pretty", no_argument, NULL, ARG_PRETTY }, { "host", required_argument, NULL, 'H' }, { "privileged", no_argument, NULL, 'P' }, { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD }, @@ -425,16 +484,16 @@ static int parse_argv(int argc, char *argv[]) { parse_user_at_host(optarg, &arg_user, &arg_host); break; - case ARG_SET_TRANSIENT: - arg_set_transient = true; + case ARG_TRANSIENT: + arg_transient = true; break; - case ARG_SET_PRETTY: - arg_set_pretty = true; + case ARG_PRETTY: + arg_pretty = true; break; - case ARG_SET_STATIC: - arg_set_static = true; + case ARG_STATIC: + arg_static = true; break; case ARG_NO_ASK_PASSWORD: @@ -450,9 +509,6 @@ static int parse_argv(int argc, char *argv[]) { } } - if (!arg_set_transient && !arg_set_pretty && !arg_set_static) - arg_set_transient = arg_set_pretty = arg_set_static = true; - return 1; } diff --git a/src/test/test-libudev.c b/src/test/test-libudev.c index caa3b4d14c..716767ba5f 100644 --- a/src/test/test-libudev.c +++ b/src/test/test-libudev.c @@ -430,7 +430,7 @@ static int test_enumerate(struct udev *udev, const char *subsystem) } static int test_hwdb(struct udev *udev, const char *modalias) { - struct udev_hwdb * hwdb; + struct udev_hwdb *hwdb; struct udev_list_entry *entry; hwdb = udev_hwdb_new(udev); -- cgit v1.2.1 From 087a30417dd9eca855ef1e22a20093a5674bd915 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 14 Aug 2013 21:47:38 -0400 Subject: bootchart: remove +x permissions on .c file --- src/bootchart/store.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 src/bootchart/store.c diff --git a/src/bootchart/store.c b/src/bootchart/store.c old mode 100755 new mode 100644 -- cgit v1.2.1 From ca08063781666a530993f7c88db1256044689c24 Mon Sep 17 00:00:00 2001 From: William Giokas <1007380@gmail.com> Date: Wed, 14 Aug 2013 13:29:58 -0500 Subject: zsh_completion: Correctly display journal fields Show equals and field values when used with _journal_none, don't show anything if we're not using _journal_none. --- shell-completion/zsh/_journalctl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/shell-completion/zsh/_journalctl b/shell-completion/zsh/_journalctl index 61983d5b6d..212bfdbc2a 100644 --- a/shell-completion/zsh/_journalctl +++ b/shell-completion/zsh/_journalctl @@ -19,13 +19,18 @@ _list_fields() { _KERNEL_{DEVICE,SUBSYSTEM} _UDEV_{SYSNAME,DEVNODE,DEVLINK} __CURSOR __{REALTIME,MONOTONIC}_TIMESTAMP) - _describe 'possible fields' journal_fields + case $_jrnl_none in + yes) _values -s '=' 'possible fields' \ + "${journal_fields[@]}:value:_journal_fields ${words[CURRENT]%%=*}" ;; + *) _describe 'possible fields' journal_fields ;; + esac } _journal_none() { - local -a _commands _files + local -a _commands _files _jrnl_none # Setting use-cache will slow this down considerably _commands=( ${"$(_call_program commands "$service" -F _EXE 2>/dev/null)"} ) + _jrnl_none='yes' _alternative : \ 'files:/dev files:_files -W /dev -P /dev/' \ "commands:commands:($_commands[@])" \ -- cgit v1.2.1 From 01264ad1cc27ecaa059857429ed1b4f3994b26c3 Mon Sep 17 00:00:00 2001 From: WANG Chao Date: Tue, 13 Aug 2013 16:38:19 +0800 Subject: fstab-generator: log_oom() if automount_name is null --- src/fstab-generator/fstab-generator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index 5a2074ec7f..2a779bbccf 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -351,7 +351,7 @@ static int add_mount( if (automount && !path_equal(where, "/")) { automount_name = unit_name_from_path(where, ".automount"); - if (!name) + if (!automount_name) return log_oom(); automount_unit = strjoin(arg_dest, "/", automount_name, NULL); -- cgit v1.2.1 From 693093c6db9d8510729b7566e74182b4ff50e31c Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Mon, 12 Aug 2013 21:59:41 +0200 Subject: systemd.unit(5): clarify the Description= contents --- man/systemd.unit.xml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index c6325d373a..17141576d0 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -359,7 +359,15 @@ describing the unit. This is intended for use in UIs to show descriptive information along with the unit - name. + name. The description should contain a name + that means something to the end user. + Apache2 Web Server is a good + example. Bad examples are + high-performance light-weight HTTP + server (too generic) or + Apache2 (too specific and + meaningless for people who do not know + Apache). -- cgit v1.2.1 From 3e7f60ab32fc2a7d5244d10a0c4e1c3be838409d Mon Sep 17 00:00:00 2001 From: William Giokas <1007380@gmail.com> Date: Mon, 12 Aug 2013 12:41:18 -0500 Subject: zsh_completion: Move helper function to autoload _hosts_or_user_at_host was used by 6 different completions, and previously was in all 6 of those files. I moved it out to its own file, _sd_hosts_or_user_at_host. This will be autoloaded for use in other completion functions. It also allows external completions to use this function by simply calling _sd_hosts_or_user_at_host as in the systemd completions. --- Makefile.am | 1 + shell-completion/zsh/_hostnamectl | 8 +------- shell-completion/zsh/_localectl | 8 +------- shell-completion/zsh/_loginctl | 8 +------- shell-completion/zsh/_machinectl | 2 +- shell-completion/zsh/_sd_hosts_or_user_at_host | 5 +++++ shell-completion/zsh/_systemctl | 8 +------- shell-completion/zsh/_timedatectl | 8 +------- 8 files changed, 12 insertions(+), 36 deletions(-) create mode 100644 shell-completion/zsh/_sd_hosts_or_user_at_host diff --git a/Makefile.am b/Makefile.am index fa4fea95ee..641e92fd79 100644 --- a/Makefile.am +++ b/Makefile.am @@ -350,6 +350,7 @@ dist_zshcompletion_DATA = \ shell-completion/zsh/_kernel-install \ shell-completion/zsh/_systemd-nspawn \ shell-completion/zsh/_systemd-analyze \ + shell-completion/zsh/_sd_hosts_or_user_at_host \ shell-completion/zsh/_systemd dist_sysctl_DATA = \ diff --git a/shell-completion/zsh/_hostnamectl b/shell-completion/zsh/_hostnamectl index bc4441d560..9d01495ea5 100644 --- a/shell-completion/zsh/_hostnamectl +++ b/shell-completion/zsh/_hostnamectl @@ -1,11 +1,5 @@ #compdef hostnamectl -_hosts_or_user_at_host() { - _alternative \ - 'users-hosts:: _user_at_host' \ - 'hosts:: _hosts' -} - _hostnamectl_command() { local -a _hostnamectl_cmds _hostnamectl_cmds=( @@ -34,5 +28,5 @@ _arguments -s \ '--static[Only set static hostname]' \ '--pretty[Only set pretty hostname]' \ '--no-ask-password[Do not prompt for password]' \ - {-H,--host=}'[Operate on remote host]:userathost:_hosts_or_user_at_host' \ + {-H,--host=}'[Operate on remote host]:userathost:_sd_hosts_or_user_at_host' \ '*::hostnamectl commands:_hostnamectl_command' diff --git a/shell-completion/zsh/_localectl b/shell-completion/zsh/_localectl index 0beed4f5c4..321e418b50 100644 --- a/shell-completion/zsh/_localectl +++ b/shell-completion/zsh/_localectl @@ -73,17 +73,11 @@ _localectl_command() { fi } -_hosts_or_user_at_host() { - _alternative \ - 'users-hosts:: _user_at_host' \ - 'hosts:: _hosts' -} - _arguments \ {-h,--help}'[Show this help]' \ '--version[Show package version]' \ "--no-convert[Don't convert keyboard mappings]" \ '--no-pager[Do not pipe output into a pager]' \ '--no-ask-password[Do not prompt for password]' \ - {-H,--host=}'[Operate on remote host]:userathost:_hosts_or_user_at_host' \ + {-H,--host=}'[Operate on remote host]:userathost:_sd_hosts_or_user_at_host' \ '*::localectl commands:_localectl_command' diff --git a/shell-completion/zsh/_loginctl b/shell-completion/zsh/_loginctl index d121a2550c..6d88685ed5 100644 --- a/shell-completion/zsh/_loginctl +++ b/shell-completion/zsh/_loginctl @@ -1,11 +1,5 @@ #compdef loginctl -_hosts_or_user_at_host() { - _alternative \ - 'users-hosts:: _user_at_host' \ - 'hosts:: _hosts' -} - _loginctl_all_sessions(){_sys_all_sessions=($(loginctl list-sessions | { while read a b; do echo " $a"; done; }) )} _loginctl_all_users() {_sys_all_users=( $(loginctl list-users | { while read a b; do echo " $a"; done; }) )} _loginctl_all_seats() {_sys_all_seats=( $(loginctl list-seats | { while read a b; do echo " $a"; done; }) )} @@ -106,7 +100,7 @@ _arguments -s \ '--kill-who=[Who to send signal to]:killwho:(main control all)' \ {-s,--signal=}'[Which signal to send]:signal:_signals' \ '--no-ask-password[Do not ask for system passwords]' \ - {-H,--host=}'[Show information for remote host]:userathost:_hosts_or_user_at_host' \ + {-H,--host=}'[Show information for remote host]:userathost:_sd_hosts_or_user_at_host' \ {-P,--privileged}'[Acquire privileges before execution]' \ '--no-pager[Do not pipe output into a pager]' \ '*::loginctl command:_loginctl_command' diff --git a/shell-completion/zsh/_machinectl b/shell-completion/zsh/_machinectl index 89196a568f..aa568e5746 100644 --- a/shell-completion/zsh/_machinectl +++ b/shell-completion/zsh/_machinectl @@ -42,6 +42,6 @@ _arguments \ '--no-ask-password[Do not ask for system passwords]' \ '--kill-who=[Who to send signal to]:killwho:(leader all)' \ {-s,--signal=}'[Which signal to send]:signal:_signals' \ - {-H,--host=}'[Show information for remote host]:userathost:_hosts_or_user_at_host' \ + {-H,--host=}'[Show information for remote host]:userathost:_sd_hosts_or_user_at_host' \ {-P,--privileged}'[Acquire privileges before execution]' \ '*::machinectl command:_machinectl_command' diff --git a/shell-completion/zsh/_sd_hosts_or_user_at_host b/shell-completion/zsh/_sd_hosts_or_user_at_host new file mode 100644 index 0000000000..282f7328e4 --- /dev/null +++ b/shell-completion/zsh/_sd_hosts_or_user_at_host @@ -0,0 +1,5 @@ +#autoload + +_alternative \ + 'users-hosts:: _user_at_host' \ + 'hosts:: _hosts' diff --git a/shell-completion/zsh/_systemctl b/shell-completion/zsh/_systemctl index f78dc19b7e..dbe168a609 100644 --- a/shell-completion/zsh/_systemctl +++ b/shell-completion/zsh/_systemctl @@ -288,12 +288,6 @@ _systemctl_caching_policy() return 1 } -_hosts_or_user_at_host() { - _alternative \ - 'users-hosts:: _user_at_host' \ - 'hosts:: _hosts' -} - _outputmodes() { local -a _output_opts _output_opts=(short short-monotonic verbose export json json-pretty json-see cat) @@ -332,7 +326,7 @@ _arguments -s \ {-f,--force}'[When enabling unit files, override existing symlinks. When shutting down, execute action immediately]' \ '--root=[Enable unit files in the specified root directory]:directory:_directories' \ '--runtime[Enable unit files only temporarily until next reboot]' \ - {-H,--host=}'[Show information for remote host]:userathost:_hosts_or_user_at_host' \ + {-H,--host=}'[Show information for remote host]:userathost:_sd_hosts_or_user_at_host' \ {-P,--privileged}'[Acquire privileges before execution]' \ {-n,--lines=}'[Journal entries to show]:number of entries' \ {-o,--output=}'[Change journal output mode]:modes:_outputmodes' \ diff --git a/shell-completion/zsh/_timedatectl b/shell-completion/zsh/_timedatectl index 091b6f10ce..9e24b86080 100644 --- a/shell-completion/zsh/_timedatectl +++ b/shell-completion/zsh/_timedatectl @@ -55,17 +55,11 @@ _timedatectl_command(){ fi } -_hosts_or_user_at_host() { - _alternative \ - 'users-hosts:: _user_at_host' \ - 'hosts:: _hosts' -} - _arguments -s \ {-h,--help}'[Show this help]' \ '--version[Show package version]' \ '--adjust-system-clock[Adjust system clock when changing local RTC mode]' \ '--no-pager[Do not pipe output into a pager]' \ '--no-ask-password[Do not prompt for password]' \ - {-H,--host=}'[Operate on remote host]:userathost:_hosts_or_user_at_host' \ + {-H,--host=}'[Operate on remote host]:userathost:_sd_hosts_or_user_at_host' \ '*::timedatectl commands:_timedatectl_command' -- cgit v1.2.1 From 1acbb95c2b58373909d1e7a09a2eed0f6595cf6e Mon Sep 17 00:00:00 2001 From: Ondrej Balaz Date: Fri, 9 Aug 2013 20:37:52 +0200 Subject: =?UTF-8?q?systemd-cryptsetup:=20makes=20=E2=80=9Cdiscard=E2=80=9D?= =?UTF-8?q?=20a=20synonym=20for=20=E2=80=9Callow-discards=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit systemd-cryptsetup recognizes option 'allow-discards' in /etc/crypttab to enable TRIM passthrough to underlying encrypted device. In Debian this option was changed to 'discard' to avoid hyphen in option name. (see: #648868 and `man crypttab`). [zj: update crypttab(5) too, making "discard" the default.] --- man/crypttab.xml | 2 +- src/cryptsetup/cryptsetup.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/man/crypttab.xml b/man/crypttab.xml index 5aade57c42..15c86d3897 100644 --- a/man/crypttab.xml +++ b/man/crypttab.xml @@ -112,7 +112,7 @@ - allow-discards + discard Allow discard requests to be passed through the encrypted block device. This diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c index 3a2cfe459b..ba0fdbc8e8 100644 --- a/src/cryptsetup/cryptsetup.c +++ b/src/cryptsetup/cryptsetup.c @@ -129,7 +129,7 @@ static int parse_one_option(const char *option) { opt_readonly = true; else if (streq(option, "verify")) opt_verify = true; - else if (streq(option, "allow-discards")) + else if (streq(option, "allow-discards") || streq(option, "discard")) opt_discards = true; else if (streq(option, "luks")) opt_type = CRYPT_LUKS1; -- cgit v1.2.1 From 298b9e23a6e21161a7fe486aab94944a58d5e90c Mon Sep 17 00:00:00 2001 From: William Giokas <1007380@gmail.com> Date: Wed, 14 Aug 2013 22:09:14 -0500 Subject: zsh_completion: Allow specifying multiple arguments Some of the options in systemd can take multiple arguments, such as systemctl's --type option. Previously, you would only be able to complete a single type after the -t, but now zsh will continue to complete the types, separating them by commas. systemd-inhibit's --what command has colon (:), and that has been taken into account. --- Makefile.am | 1 + shell-completion/zsh/_systemctl | 16 ++++++++++++++-- shell-completion/zsh/_systemd | 11 +---------- shell-completion/zsh/_systemd-delta | 15 +++++++++++++++ shell-completion/zsh/_systemd-inhibit | 8 +++++++- 5 files changed, 38 insertions(+), 13 deletions(-) create mode 100644 shell-completion/zsh/_systemd-delta diff --git a/Makefile.am b/Makefile.am index 641e92fd79..5d3599386f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -351,6 +351,7 @@ dist_zshcompletion_DATA = \ shell-completion/zsh/_systemd-nspawn \ shell-completion/zsh/_systemd-analyze \ shell-completion/zsh/_sd_hosts_or_user_at_host \ + shell-completion/zsh/_systemd-delta \ shell-completion/zsh/_systemd dist_sysctl_DATA = \ diff --git a/shell-completion/zsh/_systemctl b/shell-completion/zsh/_systemctl index dbe168a609..cc2df3c828 100644 --- a/shell-completion/zsh/_systemctl +++ b/shell-completion/zsh/_systemctl @@ -294,11 +294,23 @@ _outputmodes() { _describe -t output 'output mode' _output_opts || compadd "$@" } +_unit_states() { + local -a _states + _states=(loaded failed active inactive not-found listening running waiting plugged mounted exited dead masked) + _values -s , "${_states[@]}" +} + +_unit_types() { + local -a _types + _types=(automount device mount path service snapshot socket swap target timer) + _values -s , "${_types[@]}" +} + _arguments -s \ {-h,--help}'[Show help]' \ '--version[Show package version]' \ - {-t,--type=}'[List only units of a particular type]:unit type:(automount device mount path service snapshot socket swap target timer)' \ - '--state=[Display units in the specified state]:unit state:(loaded failed active inactive not-found listening running waiting plugged mounted exited dead masked)' \ + {-t,--type=}'[List only units of a particular type]:unit type:_unit_types' \ + '--state=[Display units in the specifyied state]:unit state:_unit_states' \ \*{-p,--property=}'[Show only properties by specific name]:unit property' \ {-a,--all}'[Show all units/properties, including dead/empty ones]' \ '--reverse[Show reverse dependencies]' \ diff --git a/shell-completion/zsh/_systemd b/shell-completion/zsh/_systemd index 7aab52d5b6..fe39de8c38 100644 --- a/shell-completion/zsh/_systemd +++ b/shell-completion/zsh/_systemd @@ -1,4 +1,4 @@ -#compdef systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-machine-id-setup systemd-notify systemd-tty-ask-password-agent +#compdef systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-detect-virt systemd-machine-id-setup systemd-notify systemd-tty-ask-password-agent _ctls() { @@ -45,15 +45,6 @@ _ctls() {-b,--batch}'[Run in batch mode, accepting no input]' \ '--depth=[Maximum traversal depth]' ;; - systemd-delta) - _arguments \ - {-h,--help}'[Show this help]' \ - '--version[Show package version]' \ - '--no-pager[Do not pipe output into a pager]' \ - '--diff=[Show a diff when overridden files differ]:boolean:(1 0)' \ - {-t,--type=}'[Only display a selected set of override types]:types:(masked equivalent redirected overridden unchanged)' \ - ':SUFFIX:(tmpfiles.d sysctl.d systemd/system)' - ;; systemd-detect-virt) _arguments \ {-h,--help}'[Show this help]' \ diff --git a/shell-completion/zsh/_systemd-delta b/shell-completion/zsh/_systemd-delta new file mode 100644 index 0000000000..6abb6fc217 --- /dev/null +++ b/shell-completion/zsh/_systemd-delta @@ -0,0 +1,15 @@ +#compdef systemd-delta + +_delta_type() { + local -a _delta_types + _delta_types=(masked equivalent redirected overridden unchanged) + _values -s , "${_delta_types[@]}" +} + +_arguments \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + '--no-pager[Do not pipe output into a pager]' \ + '--diff=[Show a diff when overridden files differ]:boolean:(1 0)' \ + {-t,--type=}'[Only display a selected set of override types]:types:_delta_type' \ + ':SUFFIX:(tmpfiles.d sysctl.d systemd/system)' diff --git a/shell-completion/zsh/_systemd-inhibit b/shell-completion/zsh/_systemd-inhibit index 7953455d40..1ecb6dc7ee 100644 --- a/shell-completion/zsh/_systemd-inhibit +++ b/shell-completion/zsh/_systemd-inhibit @@ -16,10 +16,16 @@ _systemd_inhibit_command(){ fi } +_inhibit_what() { + local _inhibit + _inhibit=(shutdown sleep idle handle-power-key handle-suspend-key handle-hibernate-key handle-lid-switch) + _values -s : "${_inhibit[@]}" +} + _arguments \ {-h,--help}'[Show this help]' \ '--version[Show package version]' \ - '--what=[Operations to inhibit]:options:(shutdown sleep idle handle-power-key handle-suspend-key handle-hibernate-key handle-lid-switch)' \ + '--what=[Operations to inhibit]:options:_inhibit_what' \ '--who=[A descriptive string who is inhibiting]' \ '--why=[A descriptive string why is being inhibited]' \ '--mode=[One of block or delay]' \ -- cgit v1.2.1 From 789b904a45b98115c45fc219162772a57dae5b3e Mon Sep 17 00:00:00 2001 From: William Giokas <1007380@gmail.com> Date: Wed, 14 Aug 2013 22:09:15 -0500 Subject: zsh_completion: machinectl properties can be stacked --- shell-completion/zsh/_machinectl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell-completion/zsh/_machinectl b/shell-completion/zsh/_machinectl index aa568e5746..abdf46fa44 100644 --- a/shell-completion/zsh/_machinectl +++ b/shell-completion/zsh/_machinectl @@ -35,7 +35,7 @@ _arguments \ {-h,--help}'[Prints a short help text and exits.]' \ '--version[Prints a short version string and exits.]' \ - {-p,--property=}'[Limit output to specified property.]:property:(Name Id Timestamp TimestampMonotonic Service Scope Leader Class State RootDirectory)' \ + \*{-p,--property=}'[Limit output to specified property.]:property:(Name Id Timestamp TimestampMonotonic Service Scope Leader Class State RootDirectory)' \ {-a,--all}'[Show all proerties]' \ (-l,--full)'[Do not ellipsize cgroup members]' \ '--no-pager[Do not pipe output into a pager]' \ -- cgit v1.2.1 From 24a0282324d774b2f3c7b16070015598c1665ab8 Mon Sep 17 00:00:00 2001 From: William Giokas <1007380@gmail.com> Date: Wed, 14 Aug 2013 22:09:16 -0500 Subject: zsh_completion: Remove ctls function from _systemd The _ctls function in the main _systemd file is not needed. --- shell-completion/zsh/_systemd | 163 ++++++++++++++++++++---------------------- 1 file changed, 79 insertions(+), 84 deletions(-) diff --git a/shell-completion/zsh/_systemd b/shell-completion/zsh/_systemd index fe39de8c38..e954c3e653 100644 --- a/shell-completion/zsh/_systemd +++ b/shell-completion/zsh/_systemd @@ -1,88 +1,83 @@ #compdef systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-detect-virt systemd-machine-id-setup systemd-notify systemd-tty-ask-password-agent -_ctls() -{ - local curcontext="$curcontext" state lstate line - case "$service" in - systemd-ask-password) - _arguments \ - {-h,--help}'[Show this help]' \ - '--icon=[Icon name]' \ - '--timeout=[Timeout in sec]' \ - '--no-tty[Ask question via agent even on TTY]' \ - '--accept-cached[Accept cached passwords]' \ - '--multiple[List multiple passwords if available]' - ;; - systemd-cat) - _arguments \ - {-h,--help}'[Show this help]' \ - '--version[Show package version.]' \ - {-t,--identifier=}'[Set syslog identifier.]' \ - {-p,--priority=}'[Set priority value.]:value:({0..7})' \ - '--level-prefix=[Control whether level prefix shall be parsed.]:boolean:(1 0)' \ - ':Message' - ;; - systemd-cgls) - _arguments \ - {-h,--help}'[Show this help]' \ - '--version[Show package version]' \ - '--no-pager[Do not pipe output into a pager]' \ - {-a,--all}'[Show all groups, including empty]' \ - '-k[Include kernel threads in output]' \ - ':cgroups:(cpuset cpu cpuacct memory devices freezer net_cls blkio)' - ;; - systemd-cgtop) - _arguments \ - {-h,--help}'[Show this help]' \ - '--version[Print version and exit]' \ - '(-c -m -i -t)-p[Order by path]' \ - '(-c -p -m -i)-t[Order by number of tasks]' \ - '(-m -p -i -t)-c[Order by CPU load]' \ - '(-c -p -i -t)-m[Order by memory load]' \ - '(-c -m -p -t)-i[Order by IO load]' \ - {-d,--delay=}'[Specify delay]' \ - {-n,--iterations=}'[Run for N iterations before exiting]' \ - {-b,--batch}'[Run in batch mode, accepting no input]' \ - '--depth=[Maximum traversal depth]' - ;; - systemd-detect-virt) - _arguments \ - {-h,--help}'[Show this help]' \ - '--version[Show package version]' \ - {-c,--container}'[Only detect whether we are run in a container]' \ - {-v,--vm}'[Only detect whether we are run in a VM]' \ - {-q,--quiet}"[Don't output anything, just set return value]" - ;; - systemd-machine-id-setup) - _arguments \ - {-h,--help}'[Show this help]' \ - '--version[Show package version]' - ;; - systemd-notify) - _arguments \ - {-h,--help}'[Show this help]' \ - '--version[Show package version]' \ - '--ready[Inform the init system about service start-up completion.]' \ - '--pid=[Inform the init system about the main PID of the daemon]' \ - '--status=[Send a free-form status string for the daemon to the init systemd]' \ - '--booted[Returns 0 if the system was booted up with systemd]' \ - '--readahead=[Controls disk read-ahead operations]:arguments:(cancel done noreply)' - ;; - systemd-tty-ask-password-agent) - _arguments \ - {-h,--help}'[Prints a short help text and exits.]' \ - '--version[Prints a short version string and exits.]' \ - '--list[Lists all currently pending system password requests.]' \ - '--query[Process all currently pending system password requests by querying the user on the calling TTY.]' \ - '--watch[Continuously process password requests.]' \ - '--wall[Forward password requests to wall(1).]' \ - '--plymouth[Ask question with plymouth(8).]' \ - '--console[Ask question on /dev/console.]' - ;; - *) _message 'eh?' ;; - esac -} - -_ctls "$@" +local curcontext="$curcontext" state lstate line +case "$service" in + systemd-ask-password) + _arguments \ + {-h,--help}'[Show this help]' \ + '--icon=[Icon name]' \ + '--timeout=[Timeout in sec]' \ + '--no-tty[Ask question via agent even on TTY]' \ + '--accept-cached[Accept cached passwords]' \ + '--multiple[List multiple passwords if available]' + ;; + systemd-cat) + _arguments \ + {-h,--help}'[Show this help]' \ + '--version[Show package version.]' \ + {-t,--identifier=}'[Set syslog identifier.]' \ + {-p,--priority=}'[Set priority value.]:value:({0..7})' \ + '--level-prefix=[Control whether level prefix shall be parsed.]:boolean:(1 0)' \ + ':Message' + ;; + systemd-cgls) + _arguments \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + '--no-pager[Do not pipe output into a pager]' \ + {-a,--all}'[Show all groups, including empty]' \ + '-k[Include kernel threads in output]' \ + ':cgroups:(cpuset cpu cpuacct memory devices freezer net_cls blkio)' + ;; + systemd-cgtop) + _arguments \ + {-h,--help}'[Show this help]' \ + '--version[Print version and exit]' \ + '(-c -m -i -t)-p[Order by path]' \ + '(-c -p -m -i)-t[Order by number of tasks]' \ + '(-m -p -i -t)-c[Order by CPU load]' \ + '(-c -p -i -t)-m[Order by memory load]' \ + '(-c -m -p -t)-i[Order by IO load]' \ + {-d,--delay=}'[Specify delay]' \ + {-n,--iterations=}'[Run for N iterations before exiting]' \ + {-b,--batch}'[Run in batch mode, accepting no input]' \ + '--depth=[Maximum traversal depth]' + ;; + systemd-detect-virt) + _arguments \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + {-c,--container}'[Only detect whether we are run in a container]' \ + {-v,--vm}'[Only detect whether we are run in a VM]' \ + {-q,--quiet}"[Don't output anything, just set return value]" + ;; + systemd-machine-id-setup) + _arguments \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' + ;; + systemd-notify) + _arguments \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + '--ready[Inform the init system about service start-up completion.]' \ + '--pid=[Inform the init system about the main PID of the daemon]' \ + '--status=[Send a free-form status string for the daemon to the init systemd]' \ + '--booted[Returns 0 if the system was booted up with systemd]' \ + '--readahead=[Controls disk read-ahead operations]:arguments:(cancel done noreply)' + ;; + systemd-tty-ask-password-agent) + _arguments \ + {-h,--help}'[Prints a short help text and exits.]' \ + '--version[Prints a short version string and exits.]' \ + '--list[Lists all currently pending system password requests.]' \ + '--query[Process all currently pending system password requests by querying the user on the calling TTY.]' \ + '--watch[Continuously process password requests.]' \ + '--wall[Forward password requests to wall(1).]' \ + '--plymouth[Ask question with plymouth(8).]' \ + '--console[Ask question on /dev/console.]' + ;; + *) _message 'eh?' ;; +esac #vim: set ft=zsh sw=4 ts=4 et -- cgit v1.2.1 From 585275000ccd522f403365236492dc924778d286 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 15 Aug 2013 15:15:36 +0200 Subject: hashmap: remove empty lines --- src/shared/hashmap.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/shared/hashmap.c b/src/shared/hashmap.c index 9f7db34397..4ea1a0f4cb 100644 --- a/src/shared/hashmap.c +++ b/src/shared/hashmap.c @@ -373,13 +373,10 @@ int hashmap_put(Hashmap *h, const void *key, void *value) { assert(h); hash = h->hash_func(key) % NBUCKETS; - e = hash_scan(h, hash, key); if (e) { - if (e->value == value) return 0; - return -EEXIST; } @@ -534,7 +531,6 @@ int hashmap_remove_and_replace(Hashmap *h, const void *old_key, const void *new_ return -ENOENT; new_hash = h->hash_func(new_key) % NBUCKETS; - if ((k = hash_scan(h, new_hash, new_key))) if (e != k) remove_entry(h, k); -- cgit v1.2.1 From 2dd30e7da94b32df03451df8cf602e9454a376cb Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 15 Aug 2013 16:07:51 +0200 Subject: hwdb: keyboard - remove stray " kay, hwdb/60-keyboard.hwdb line 147 it says KEYBOARD_KEY_ee=screenlock" with a " at the end. I guess that's a typo? --- hwdb/60-keyboard.hwdb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index 0c6f293a81..a77aa00d48 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -144,7 +144,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*4720*:pvr* keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate 6593:* keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire 1640:* KEYBOARD_KEY_b2=www - KEYBOARD_KEY_ee=screenlock" + KEYBOARD_KEY_ee=screenlock ########################################################### # Alienware -- cgit v1.2.1 From de562e00feb773ea9cb01b1aa6a377409fc90611 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 15 Aug 2013 18:07:47 +0200 Subject: man: remove "wine" from unrelated man pages --- man/systemd-modules-load.service.xml | 1 - man/systemd-sysctl.service.xml | 1 - 2 files changed, 2 deletions(-) diff --git a/man/systemd-modules-load.service.xml b/man/systemd-modules-load.service.xml index f8dfab351a..28dd8ecb42 100644 --- a/man/systemd-modules-load.service.xml +++ b/man/systemd-modules-load.service.xml @@ -94,7 +94,6 @@ systemd1, modules-load.d5, - wine8 diff --git a/man/systemd-sysctl.service.xml b/man/systemd-sysctl.service.xml index 72a102c128..a9a4765630 100644 --- a/man/systemd-sysctl.service.xml +++ b/man/systemd-sysctl.service.xml @@ -71,7 +71,6 @@ systemd1, sysctl.d5, sysctl8, - wine8 -- cgit v1.2.1 From 04bf3c1a60d82791e0320381e9268f727708f776 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 15 Aug 2013 18:35:03 +0200 Subject: sysctl: allow overwriting of values specified in "later" files --- NEWS | 9 +++++++++ src/sysctl/sysctl.c | 16 ++++++++-------- units/systemd-sysctl.service.in | 1 - 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/NEWS b/NEWS index f9929d0725..9d989d33f5 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,14 @@ systemd System and Service Manager +CHANGES WITH 206: + + * The systemd-sysctl tool does no longer natively read the + file /etc/sysctl.conf. If desired, the file should be + symlinked from /etc/sysctl.d/99-sysctl.conf. Apart from + providing legacy support by a symlink rather than built-in + code, it also makes the otherwise hidden order of application + of the different files visible. + CHANGES WITH 206: * The documentation has been updated to cover the various new diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c index db18dd9f6e..b5670dbb86 100644 --- a/src/sysctl/sysctl.c +++ b/src/sysctl/sysctl.c @@ -135,6 +135,7 @@ static int parse_file(Hashmap *sysctl_options, const char *path, bool ignore_eno log_debug("parse: %s\n", path); while (!feof(f)) { char l[LINE_MAX], *p, *value, *new_value, *property, *existing; + void *v; int k; if (!fgets(l, sizeof(l), f)) { @@ -167,13 +168,14 @@ static int parse_file(Hashmap *sysctl_options, const char *path, bool ignore_eno p = normalize_sysctl(strstrip(p)); value = strstrip(value); - existing = hashmap_get(sysctl_options, p); + existing = hashmap_get2(sysctl_options, p, &v); if (existing) { - if (!streq(value, existing)) - log_warning("Duplicate assignment of %s in file '%s', ignoring.", - p, path); + if (streq(value, existing)) + continue; - continue; + log_info("Overwriting earlier assignment of %s in file '%s'.", p, path); + free(hashmap_remove(sysctl_options, p)); + free(v); } property = strdup(p); @@ -188,7 +190,7 @@ static int parse_file(Hashmap *sysctl_options, const char *path, bool ignore_eno k = hashmap_put(sysctl_options, property, new_value); if (k < 0) { - log_error("Failed to add sysctl variable %s to hashmap: %s", property, strerror(-r)); + log_error("Failed to add sysctl variable %s to hashmap: %s", property, strerror(-k)); free(property); free(new_value); return k; @@ -304,8 +306,6 @@ int main(int argc, char *argv[]) { goto finish; } - r = parse_file(sysctl_options, "/etc/sysctl.conf", true); - STRV_FOREACH(f, files) { k = parse_file(sysctl_options, *f, true); if (k < 0 && r == 0) diff --git a/units/systemd-sysctl.service.in b/units/systemd-sysctl.service.in index 45e1ceb25c..5baf22c183 100644 --- a/units/systemd-sysctl.service.in +++ b/units/systemd-sysctl.service.in @@ -13,7 +13,6 @@ Conflicts=shutdown.target After=systemd-readahead-collect.service systemd-readahead-replay.service Before=sysinit.target shutdown.target ConditionPathIsReadWrite=/proc/sys/ -ConditionPathExists=|/etc/sysctl.conf ConditionDirectoryNotEmpty=|/lib/sysctl.d ConditionDirectoryNotEmpty=|/usr/lib/sysctl.d ConditionDirectoryNotEmpty=|/usr/local/lib/sysctl.d -- cgit v1.2.1 From c2748ce28c7111037f312c5446335f5538e673e8 Mon Sep 17 00:00:00 2001 From: Steven Hiscocks Date: Thu, 15 Aug 2013 12:50:32 -0400 Subject: systemd-python: fix initialization of _Reader objects https://bugzilla.redhat.com/show_bug.cgi?id=995575 --- src/python-systemd/_reader.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/python-systemd/_reader.c b/src/python-systemd/_reader.c index a678f69318..3b1003ba71 100644 --- a/src/python-systemd/_reader.c +++ b/src/python-systemd/_reader.c @@ -64,6 +64,10 @@ static PyStructSequence_Desc Monotonic_desc = { }; #endif +/** + * Convert a Python sequence object into a strv (char**), and + * None into a NULL pointer. + */ static int strv_converter(PyObject* obj, void *_result) { char ***result = _result; Py_ssize_t i, len; @@ -73,6 +77,11 @@ static int strv_converter(PyObject* obj, void *_result) { if (!obj) goto cleanup; + if (obj == Py_None) { + *result = NULL; + return 1; + } + if (!PySequence_Check(obj)) return 0; -- cgit v1.2.1 From 31f49d022aee9bbb356e52e5483f182d7ffa8d2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 15 Aug 2013 12:51:20 -0400 Subject: systemd-python: check for oom, give nicer error messages --- src/python-systemd/_reader.c | 8 ++++++-- src/python-systemd/login.c | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/python-systemd/_reader.c b/src/python-systemd/_reader.c index 3b1003ba71..bc5db19049 100644 --- a/src/python-systemd/_reader.c +++ b/src/python-systemd/_reader.c @@ -75,7 +75,7 @@ static int strv_converter(PyObject* obj, void *_result) { assert(result); if (!obj) - goto cleanup; + return 0; if (obj == Py_None) { *result = NULL; @@ -87,6 +87,10 @@ static int strv_converter(PyObject* obj, void *_result) { len = PySequence_Length(obj); *result = new0(char*, len + 1); + if (!*result) { + set_error(-ENOMEM, NULL, NULL); + return 0; + } for (i = 0; i < len; i++) { PyObject *item; @@ -154,7 +158,7 @@ static int Reader_init(Reader *self, PyObject *args, PyObject *keywds) char **files = NULL; static const char* const kwlist[] = {"flags", "path", "files", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, keywds, "|izO&", (char**) kwlist, + if (!PyArg_ParseTupleAndKeywords(args, keywds, "|izO&:__init__", (char**) kwlist, &flags, &path, strv_converter, &files)) return -1; diff --git a/src/python-systemd/login.c b/src/python-systemd/login.c index 1e86193f6b..dd2edbca00 100644 --- a/src/python-systemd/login.c +++ b/src/python-systemd/login.c @@ -159,7 +159,7 @@ static int Monitor_init(Monitor *self, PyObject *args, PyObject *keywds) int r; static const char* const kwlist[] = {"category", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, keywds, "|z", (char**) kwlist, + if (!PyArg_ParseTupleAndKeywords(args, keywds, "|z:__init__", (char**) kwlist, &category)) return -1; -- cgit v1.2.1 From f5853dafa1b3486f3ac77fccee3cbf377baa8d95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 15 Aug 2013 12:54:54 -0400 Subject: build-sys: add clean-python target Building for a different version of Python requires removing all build products for the old version. There's no nice way to do it, short of doing 'make clean'. The new 'clean-python' target is a bit hacky, but seems to work: ./configure PYTHON=python2 && make && make install make clean-python ./configure PYTHON=python3 --disable-gtk-doc --disable-man-pages && make && make install should install modules for both versions of Python. --- Makefile.am | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Makefile.am b/Makefile.am index 5d3599386f..fdfdd6515e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4136,6 +4136,11 @@ CLEAN_LOCAL_HOOKS += clean-sphinx clean-sphinx: -rm -rf docs/html/python-systemd/ +# Remove Python stuff, e.g. to force rebuilding for a different Python version. +clean-python: + -rm -rf src/python-systemd/.libs src/python-systemd/*.l[ao] + -rm -f _daemon.la id128.la _journal.la login.la _reader.la + # ------------------------------------------------------------------------------ substitutions = \ '|rootlibexecdir=$(rootlibexecdir)|' \ -- cgit v1.2.1 From 47e737dc13bf4251ae5a2249ec29b34503ed92e1 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 15 Aug 2013 19:51:08 +0200 Subject: udevd: simplify sigterm check --- src/udev/udevd.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/udev/udevd.c b/src/udev/udevd.c index 7c6c5d6a87..fd799cc910 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -314,13 +314,11 @@ static void worker_new(struct event *event) udev_device_unref(dev); dev = NULL; - if (udev_event->sigterm) { - udev_event_unref(udev_event); - goto out; - } - udev_event_unref(udev_event); + if (udev_event->sigterm) + goto out; + /* wait for more device messages from main udevd, or term signal */ while (dev == NULL) { struct epoll_event ev[4]; -- cgit v1.2.1 From cabaa37a602ea787d3b3d1f6ec402de7918a4823 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 15 Aug 2013 19:54:03 +0200 Subject: libudev: fix hwdb validation to look for the *new* file --- src/libudev/libudev-hwdb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libudev/libudev-hwdb.c b/src/libudev/libudev-hwdb.c index 5645a11437..de1cb83188 100644 --- a/src/libudev/libudev-hwdb.c +++ b/src/libudev/libudev-hwdb.c @@ -358,7 +358,7 @@ bool udev_hwdb_validate(struct udev_hwdb *hwdb) { return false; if (!hwdb->f) return false; - if (fstat(fileno(hwdb->f), &st) < 0) + if (stat("/etc/udev/hwdb.bin", &st) < 0) return true; if (timespec_load(&hwdb->st.st_mtim) != timespec_load(&st.st_mtim)) return true; -- cgit v1.2.1 From 998b087f70505decbfe55afd27fc4ade3d60ce52 Mon Sep 17 00:00:00 2001 From: Thomas Hindoe Paaboel Andersen Date: Thu, 15 Aug 2013 23:32:38 +0200 Subject: tests: fix indentation --- src/test/test-util.c | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/src/test/test-util.c b/src/test/test-util.c index 315bc419c2..875aeab3d5 100644 --- a/src/test/test-util.c +++ b/src/test/test-util.c @@ -192,41 +192,40 @@ static void test_safe_atod(void) { } static void test_strappend(void) { - _cleanup_free_ char *t1, *t2, *t3, *t4; + _cleanup_free_ char *t1, *t2, *t3, *t4; - t1 = strappend(NULL, NULL); - assert_se(streq(t1, "")); + t1 = strappend(NULL, NULL); + assert_se(streq(t1, "")); - t2 = strappend(NULL, "suf"); - assert_se(streq(t2, "suf")); + t2 = strappend(NULL, "suf"); + assert_se(streq(t2, "suf")); - t3 = strappend("pre", NULL); - assert_se(streq(t3, "pre")); + t3 = strappend("pre", NULL); + assert_se(streq(t3, "pre")); - t4 = strappend("pre", "suf"); - assert_se(streq(t4, "presuf")); + t4 = strappend("pre", "suf"); + assert_se(streq(t4, "presuf")); } static void test_strstrip(void) { - char *r; - char input[] = " hello, waldo. "; - - r = strstrip(input); - assert_se(streq(r, "hello, waldo.")); + char *r; + char input[] = " hello, waldo. "; + r = strstrip(input); + assert_se(streq(r, "hello, waldo.")); } static void test_delete_chars(void) { - char *r; - char input[] = " hello, waldo. abc"; + char *r; + char input[] = " hello, waldo. abc"; - r = delete_chars(input, WHITESPACE); - assert_se(streq(r, "hello,waldo.abc")); + r = delete_chars(input, WHITESPACE); + assert_se(streq(r, "hello,waldo.abc")); } static void test_in_charset(void) { - assert_se(in_charset("dddaaabbbcccc", "abcd")); - assert_se(!in_charset("dddaaabbbcccc", "abc f")); + assert_se(in_charset("dddaaabbbcccc", "abcd")); + assert_se(!in_charset("dddaaabbbcccc", "abc f")); } static void test_hexchar(void) { -- cgit v1.2.1 From 5eec7de6ad91bcfbb2c8dabaf592d0f5151730a7 Mon Sep 17 00:00:00 2001 From: Thomas Hindoe Paaboel Andersen Date: Thu, 15 Aug 2013 23:38:09 +0200 Subject: typo fixes in man and comments --- man/systemd.xml | 2 +- src/libudev/libudev-device.c | 2 +- units/systemd-journald.socket | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/man/systemd.xml b/man/systemd.xml index 32bca0b607..9f58bc2f82 100644 --- a/man/systemd.xml +++ b/man/systemd.xml @@ -374,7 +374,7 @@ Slice units may be used to group units which manage system processes (such as service and scope units) in a - hierachial tree for resource management + hierarchical tree for resource management purposes. See systemd.slice5. diff --git a/src/libudev/libudev-device.c b/src/libudev/libudev-device.c index eb43668c56..a644904757 100644 --- a/src/libudev/libudev-device.c +++ b/src/libudev/libudev-device.c @@ -42,7 +42,7 @@ * * Representation of kernel sys devices. Devices are uniquely identified * by their syspath, every device has exactly one path in the kernel sys - * filesystem. Devices usually belong to a kernel subsystem, and and have + * filesystem. Devices usually belong to a kernel subsystem, and have * a unique name inside that subsystem. */ diff --git a/units/systemd-journald.socket b/units/systemd-journald.socket index 4f0619d258..fbeb10baae 100644 --- a/units/systemd-journald.socket +++ b/units/systemd-journald.socket @@ -12,7 +12,7 @@ DefaultDependencies=no Before=sockets.target # Mount and swap units need this. If this socket unit is removed by an -# isolate request the mount and and swap units would be removed too, +# isolate request the mount and swap units would be removed too, # hence let's exclude this from isolate requests. IgnoreOnIsolate=yes -- cgit v1.2.1 From d0a2d726f0b6a02077c178d446f89839be474d41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 15 Aug 2013 15:07:57 -0400 Subject: units: make fsck units remain after exit Without this, fsck would be re-run if any other service which pulls in a target requiring one of the mounts was started after fsck was done but before the initial transaction was done. https://bugs.freedesktop.org/show_bug.cgi?id=66784 --- units/systemd-fsck-root.service.in | 4 ++-- units/systemd-fsck@.service.in | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/units/systemd-fsck-root.service.in b/units/systemd-fsck-root.service.in index 563129badb..4388314079 100644 --- a/units/systemd-fsck-root.service.in +++ b/units/systemd-fsck-root.service.in @@ -7,7 +7,7 @@ [Unit] Description=File System Check on Root Device -Documentation=man:systemd-fsck@.service(8) +Documentation=man:systemd-fsck-root.service(8) DefaultDependencies=no After=systemd-readahead-collect.service systemd-readahead-replay.service Before=local-fs.target shutdown.target @@ -16,7 +16,7 @@ ConditionPathIsReadWrite=!/ [Service] Type=oneshot -RemainAfterExit=no +RemainAfterExit=yes ExecStart=@rootlibexecdir@/systemd-fsck StandardOutput=journal+console FsckPassNo=1 diff --git a/units/systemd-fsck@.service.in b/units/systemd-fsck@.service.in index b3c71eb250..e229cdcb83 100644 --- a/units/systemd-fsck@.service.in +++ b/units/systemd-fsck@.service.in @@ -15,7 +15,7 @@ Before=shutdown.target [Service] Type=oneshot -RemainAfterExit=no +RemainAfterExit=yes ExecStart=@rootlibexecdir@/systemd-fsck %f StandardOutput=journal+console TimeoutSec=0 -- cgit v1.2.1 From 4b357e15876b730343db08719c877fdb45b6ad42 Mon Sep 17 00:00:00 2001 From: Michael Marineau Date: Thu, 15 Aug 2013 11:50:57 -0400 Subject: build-sys: Add configure check for linux/btrfs.h btrfs.h was added to uapi in Linux 3.9. To fix building with older header versions this adds a configure check for the header and re-adds btrfs definitions to missing.h which was removed in bed2e820 along with two other ioctls used by gpt-auto-generator. [ Apparently, btrfs.h was only added recently: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=55e301fd57a6239ec14b91a1cf2e70b3dd135194 let's re-add it for now -- kay ] --- configure.ac | 2 + src/gpt-auto-generator/gpt-auto-generator.c | 5 ++- src/readahead/readahead-collect.c | 5 ++- src/shared/missing.h | 57 +++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 6ef6382c4c..2541344f0c 100644 --- a/configure.ac +++ b/configure.ac @@ -192,6 +192,7 @@ AM_CONDITIONAL([HAVE_PYTHON_DEVEL], [test "$have_python_devel" = "yes"]) AC_SEARCH_LIBS([dlsym], [dl], [], [AC_MSG_ERROR([*** Dynamic linking loader library not found])]) AC_CHECK_HEADERS([sys/capability.h], [], [AC_MSG_ERROR([*** POSIX caps headers not found])]) +AC_CHECK_HEADERS([linux/btrfs.h], [], []) # unconditionally pull-in librt with old glibc versions AC_SEARCH_LIBS([clock_gettime], [rt], [], []) @@ -220,6 +221,7 @@ m4_pattern_forbid([^_?PKG_[A-Z_]+$],[*** pkg.m4 missing, please install pkg-conf PKG_CHECK_MODULES(DBUS, [dbus-1 >= 1.3.2]) + # ------------------------------------------------------------------------------ have_coverage=no AC_ARG_ENABLE(coverage, AS_HELP_STRING([--enable-coverage], [enable test coverage])) diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index 81d692c513..a26655f096 100644 --- a/src/gpt-auto-generator/gpt-auto-generator.c +++ b/src/gpt-auto-generator/gpt-auto-generator.c @@ -22,11 +22,14 @@ #include #include #include -#include #include #include #include +#ifdef HAVE_LINUX_BTRFS_H +#include +#endif + #include "path-util.h" #include "util.h" #include "mkdir.h" diff --git a/src/readahead/readahead-collect.c b/src/readahead/readahead-collect.c index 658c230d65..5d37bb75f3 100644 --- a/src/readahead/readahead-collect.c +++ b/src/readahead/readahead-collect.c @@ -38,13 +38,16 @@ #include #include #include -#include #include #include #include #include #include +#ifdef HAVE_LINUX_BTRFS_H +#include +#endif + #ifdef HAVE_FANOTIFY_INIT #include #endif diff --git a/src/shared/missing.h b/src/shared/missing.h index 6e4b398fcb..d1ca135c55 100644 --- a/src/shared/missing.h +++ b/src/shared/missing.h @@ -154,6 +154,63 @@ static inline int fanotify_mark(int fanotify_fd, unsigned int flags, uint64_t ma } #endif +#ifndef BTRFS_IOCTL_MAGIC +#define BTRFS_IOCTL_MAGIC 0x94 +#endif + +#ifndef BTRFS_PATH_NAME_MAX +#define BTRFS_PATH_NAME_MAX 4087 +#endif + +#ifndef BTRFS_DEVICE_PATH_NAME_MAX +#define BTRFS_DEVICE_PATH_NAME_MAX 1024 +#endif + +#ifndef BTRFS_FSID_SIZE +#define BTRFS_FSID_SIZE 16 +#endif + +#ifndef BTRFS_UUID_SIZE +#define BTRFS_UUID_SIZE 16 +#endif + +#ifndef HAVE_LINUX_BTRFS_H +struct btrfs_ioctl_vol_args { + int64_t fd; + char name[BTRFS_PATH_NAME_MAX + 1]; +}; + +struct btrfs_ioctl_dev_info_args { + uint64_t devid; /* in/out */ + uint8_t uuid[BTRFS_UUID_SIZE]; /* in/out */ + uint64_t bytes_used; /* out */ + uint64_t total_bytes; /* out */ + uint64_t unused[379]; /* pad to 4k */ + char path[BTRFS_DEVICE_PATH_NAME_MAX]; /* out */ +}; + +struct btrfs_ioctl_fs_info_args { + uint64_t max_id; /* out */ + uint64_t num_devices; /* out */ + uint8_t fsid[BTRFS_FSID_SIZE]; /* out */ + uint64_t reserved[124]; /* pad to 1k */ +}; +#endif + +#ifndef BTRFS_IOC_DEFRAG +#define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, struct btrfs_ioctl_vol_args) +#endif + +#ifndef BTRFS_IOC_DEV_INFO +#define BTRFS_IOC_DEV_INFO _IOWR(BTRFS_IOCTL_MAGIC, 30, \ + struct btrfs_ioctl_dev_info_args) +#endif + +#ifndef BTRFS_IOC_FS_INFO +#define BTRFS_IOC_FS_INFO _IOR(BTRFS_IOCTL_MAGIC, 31, \ + struct btrfs_ioctl_fs_info_args) +#endif + #ifndef BTRFS_SUPER_MAGIC #define BTRFS_SUPER_MAGIC 0x9123683E #endif -- cgit v1.2.1 From 4bb3a126b7a683a537d4279270c1a22ce6cf5e9f Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 17 Aug 2013 19:07:42 +0200 Subject: udev: replace CAP_MKNOD by writable /sys condition --- units/systemd-udev-settle.service.in | 2 +- units/systemd-udev-trigger.service.in | 2 +- units/systemd-udevd-control.socket | 2 +- units/systemd-udevd-kernel.socket | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/units/systemd-udev-settle.service.in b/units/systemd-udev-settle.service.in index 037dd9a872..0817803a39 100644 --- a/units/systemd-udev-settle.service.in +++ b/units/systemd-udev-settle.service.in @@ -16,7 +16,7 @@ DefaultDependencies=no Wants=systemd-udevd.service After=systemd-udev-trigger.service Before=sysinit.target -ConditionCapability=CAP_MKNOD +ConditionPathIsReadWrite=/sys [Service] Type=oneshot diff --git a/units/systemd-udev-trigger.service.in b/units/systemd-udev-trigger.service.in index 604c369a1b..0c33909cee 100644 --- a/units/systemd-udev-trigger.service.in +++ b/units/systemd-udev-trigger.service.in @@ -12,7 +12,7 @@ DefaultDependencies=no Wants=systemd-udevd.service After=systemd-udevd-kernel.socket systemd-udevd-control.socket Before=sysinit.target -ConditionCapability=CAP_MKNOD +ConditionPathIsReadWrite=/sys [Service] Type=oneshot diff --git a/units/systemd-udevd-control.socket b/units/systemd-udevd-control.socket index ca17102dfa..8330a1c035 100644 --- a/units/systemd-udevd-control.socket +++ b/units/systemd-udevd-control.socket @@ -10,7 +10,7 @@ Description=udev Control Socket Documentation=man:systemd-udevd.service(8) man:udev(7) DefaultDependencies=no Before=sockets.target -ConditionCapability=CAP_MKNOD +ConditionPathIsReadWrite=/sys [Socket] Service=systemd-udevd.service diff --git a/units/systemd-udevd-kernel.socket b/units/systemd-udevd-kernel.socket index 4b8a5b0fb5..39b7809204 100644 --- a/units/systemd-udevd-kernel.socket +++ b/units/systemd-udevd-kernel.socket @@ -10,7 +10,7 @@ Description=udev Kernel Socket Documentation=man:systemd-udevd.service(8) man:udev(7) DefaultDependencies=no Before=sockets.target -ConditionCapability=CAP_MKNOD +ConditionPathIsReadWrite=/sys [Socket] Service=systemd-udevd.service -- cgit v1.2.1 From 763a24a3b62f0eaac43fb58202ad3594f1af09ac Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Mon, 19 Aug 2013 15:18:43 +0200 Subject: libudev-enumerate.c:udev_enumerate_get_list_entry() fixed possible stale pointer If a realloc() happens in syspath_add(), the move_later pointer could point to an invalid memory region. Let move_later store the array index, instead of the pointer to the entry. --- src/libudev/libudev-enumerate.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/libudev/libudev-enumerate.c b/src/libudev/libudev-enumerate.c index 5ccaabdc6c..3e791074f3 100644 --- a/src/libudev/libudev-enumerate.c +++ b/src/libudev/libudev-enumerate.c @@ -270,8 +270,9 @@ _public_ struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enume return NULL; if (!udev_enumerate->devices_uptodate) { unsigned int i; + int move_later = -1; unsigned int max; - struct syspath *prev = NULL, *move_later = NULL; + struct syspath *prev = NULL; size_t move_later_prefix = 0; udev_list_cleanup(&udev_enumerate->devices_list); @@ -303,23 +304,25 @@ _public_ struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enume move_later_prefix = devices_delay_later(udev_enumerate->udev, entry->syspath); if (move_later_prefix > 0) { - move_later = entry; + move_later = i; continue; } } - if (move_later && - !strneq(entry->syspath, move_later->syspath, move_later_prefix)) { + if ((move_later >= 0) && + !strneq(entry->syspath, udev_enumerate->devices[move_later].syspath, move_later_prefix)) { - udev_list_entry_add(&udev_enumerate->devices_list, move_later->syspath, NULL); - move_later = NULL; + udev_list_entry_add(&udev_enumerate->devices_list, + udev_enumerate->devices[move_later].syspath, NULL); + move_later = -1; } udev_list_entry_add(&udev_enumerate->devices_list, entry->syspath, NULL); } - if (move_later) - udev_list_entry_add(&udev_enumerate->devices_list, move_later->syspath, NULL); + if (move_later >= 0) + udev_list_entry_add(&udev_enumerate->devices_list, + udev_enumerate->devices[move_later].syspath, NULL); /* add and cleanup delayed devices from end of list */ for (i = max; i < udev_enumerate->devices_cur; i++) { -- cgit v1.2.1 From ac50788b0f5aeee09e7d45db28ae8ab7f39cd52e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 26 Jul 2013 12:57:33 -0400 Subject: journal: fix parsing of facility in syslog messages In 49998b383 (journald: do not overwrite syslog facility when parsing priority) journald started ignoring facility part when reading service stderr to convert to syslog messages. In this case it is fine, because only the priority is allowed. But the same codepath is used for syslog messages, where the facility should be used. Split the two codepaths by explicitly specyfing whether the facility should be ignored or not. https://bugzilla.redhat.com/show_bug.cgi?id=988814 --- src/journal/journald-stream.c | 2 +- src/journal/journald-syslog.c | 12 ++++++++---- src/journal/journald-syslog.h | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c index e98fe94b46..9c4efec9bc 100644 --- a/src/journal/journald-stream.c +++ b/src/journal/journald-stream.c @@ -90,7 +90,7 @@ static int stdout_stream_log(StdoutStream *s, const char *p) { priority = s->priority; if (s->level_prefix) - syslog_parse_priority((char**) &p, &priority); + syslog_parse_priority((char**) &p, &priority, false); if (s->forward_to_syslog || s->server->forward_to_syslog) server_forward_syslog(s->server, syslog_fixup_facility(priority), s->identifier, p, &s->ucred, NULL); diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c index 7cbb34608b..c2770a53d0 100644 --- a/src/journal/journald-syslog.c +++ b/src/journal/journald-syslog.c @@ -236,7 +236,7 @@ size_t syslog_parse_identifier(const char **buf, char **identifier, char **pid) return e; } -void syslog_parse_priority(char **p, int *priority) { +void syslog_parse_priority(char **p, int *priority, bool with_facility) { int a = 0, b = 0, c = 0; int k; @@ -265,10 +265,14 @@ void syslog_parse_priority(char **p, int *priority) { } else return; - if (a < 0 || b < 0 || c < 0) + if (a < 0 || b < 0 || c < 0 || + (!with_facility && (a || b || c > 7))) return; - *priority = (*priority & LOG_FACMASK) | (a*100 + b*10 + c); + if (with_facility) + *priority = a*100 + b*10 + c; + else + *priority = (*priority & LOG_FACMASK) | c; *p += k; } @@ -361,7 +365,7 @@ void server_process_syslog_message( assert(buf); orig = buf; - syslog_parse_priority((char**) &buf, &priority); + syslog_parse_priority((char**) &buf, &priority, true); if (s->forward_to_syslog) forward_syslog_raw(s, priority, orig, ucred, tv); diff --git a/src/journal/journald-syslog.h b/src/journal/journald-syslog.h index 324b70eef0..8ccdb77a09 100644 --- a/src/journal/journald-syslog.h +++ b/src/journal/journald-syslog.h @@ -25,7 +25,7 @@ int syslog_fixup_facility(int priority) _const_; -void syslog_parse_priority(char **p, int *priority); +void syslog_parse_priority(char **p, int *priority, bool with_facility); size_t syslog_parse_identifier(const char **buf, char **identifier, char **pid); void server_forward_syslog(Server *s, int priority, const char *identifier, const char *message, struct ucred *ucred, struct timeval *tv); -- cgit v1.2.1 From 58a25dac28b14b798299935ed0fd400965da4623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 19 Aug 2013 19:24:01 -0400 Subject: build-sys: use no-tmpl flavour of gtkdocization "tmpl" flavour is deprecated. Also this way we avoid a warning during installation with older gtkdoc. https://bugzilla.gnome.org/show_bug.cgi?id=701259 --- autogen.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autogen.sh b/autogen.sh index 86fe9b3785..eeb0c1b5e3 100755 --- a/autogen.sh +++ b/autogen.sh @@ -25,7 +25,7 @@ if [ -f .git/hooks/pre-commit.sample ] && [ ! -f .git/hooks/pre-commit ]; then fi if which gtkdocize >/dev/null 2>/dev/null; then - gtkdocize --docdir docs/ + gtkdocize --docdir docs/ --flavour no-tmpl gtkdocargs=--enable-gtk-doc else echo "You don't have gtk-doc installed, and thus won't be able to generate the documentation." -- cgit v1.2.1 From 04ac799283f517672a5424e7c5bf066cfa4ca020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 19 Aug 2013 16:00:13 -0400 Subject: man: fix spacing issue in systemd-nspawn(1) Same as 1e158d273. --- TODO | 4 ++++ man/systemd-nspawn.xml | 9 ++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/TODO b/TODO index f6e7566bb6..5c5e4b46f9 100644 --- a/TODO +++ b/TODO @@ -23,6 +23,10 @@ Bugfixes: - make the resulting line the requested number of *characters*, not *bytes*, - avoid truncuating multi-byte sequences in the middle. +* shorten the message to sane length: + + Cannot add dependency job for unit display-manager.service, ignoring: Unit display-manager.service failed to load: No such file or directory. See system logs and 'systemctl status display-manager.service' for details. + Fedora 20: * external: ps should gain colums for slice and machine diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml index f4c5d77eed..e55933d069 100644 --- a/man/systemd-nspawn.xml +++ b/man/systemd-nspawn.xml @@ -97,14 +97,13 @@ involved with boot and systems management. In contrast to - chroot1 - systemd-nspawn may be used to boot - full Linux-based operating systems in a - container. + chroot1 systemd-nspawn + may be used to boot full Linux-based operating systems + in a container. Use a tool like yum8, - debootstrap8 + debootstrap8, or pacman8 to set up an OS directory tree suitable as file system -- cgit v1.2.1 From 219061dc524368179b2e65cfe91d4d6b23396ba8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 19 Aug 2013 16:59:42 -0400 Subject: units: disable kmod-static-nodes.service in containers Fixes https://bugzilla.redhat.com/show_bug.cgi?id=998122. Note: upstream kmod has a patch [1] to exit with a warning if modules.devname is missing. We could use new %v specifier to make this service conditional on the existence of this file, but this could mask a kernel installation error, hence we should let kmod run even if the file doesn't exist. [1] http://git.kernel.org/cgit/utils/kernel/kmod/kmod.git/commit/?id=ae17710117 --- units/kmod-static-nodes.service.in | 1 + 1 file changed, 1 insertion(+) diff --git a/units/kmod-static-nodes.service.in b/units/kmod-static-nodes.service.in index cdfc6e56e1..98664ea18a 100644 --- a/units/kmod-static-nodes.service.in +++ b/units/kmod-static-nodes.service.in @@ -9,6 +9,7 @@ Description=Create list of required static device nodes for the current kernel DefaultDependencies=no Before=sysinit.target systemd-tmpfiles-setup-dev.service +ConditionVirtualization=!container [Service] Type=oneshot -- cgit v1.2.1 From d98cc1c019651b895464161072894a02cc43daab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 15 Aug 2013 18:05:04 -0400 Subject: gpt-auto-generator: include device name in error reports --- src/gpt-auto-generator/gpt-auto-generator.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index a26655f096..60cbd7ee25 100644 --- a/src/gpt-auto-generator/gpt-auto-generator.c +++ b/src/gpt-auto-generator/gpt-auto-generator.c @@ -299,7 +299,8 @@ static int enumerate_partitions(dev_t dev) { r = udev_enumerate_scan_devices(e); if (r < 0) { - log_error("Failed to enumerate partitions: %s", strerror(-r)); + log_error("Failed to enumerate partitions on /dev/block/%u:%u: %s", + major(dev), minor(dev), strerror(-r)); goto finish; } @@ -310,6 +311,7 @@ static int enumerate_partitions(dev_t dev) { struct udev_device *q; sd_id128_t type_id; unsigned nr; + dev_t sub; q = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item)); if (!q) { @@ -329,9 +331,12 @@ static int enumerate_partitions(dev_t dev) { goto finish; } - r = verify_gpt_partition(udev_device_get_devnum(q), &type_id, &nr, &fstype); + sub = udev_device_get_devnum(q); + + r = verify_gpt_partition(sub, &type_id, &nr, &fstype); if (r < 0) { - log_error("Failed to verify GPT partition: %s", strerror(-r)); + log_error("Failed to verify GPT partition /dev/block/%u:%u: %s", + major(sub), minor(sub), strerror(-r)); udev_device_unref(q); goto finish; } @@ -483,11 +488,12 @@ int main(int argc, char *argv[]) { return EXIT_SUCCESS; } - log_debug("Root device %u:%u.", major(dev), minor(dev)); + log_debug("Root device /dev/block/%u:%u.", major(dev), minor(dev)); r = verify_gpt_partition(dev, NULL, NULL, NULL); if (r < 0) { - log_error("Failed to verify GPT partition: %s", strerror(-r)); + log_error("Failed to verify GPT partition /dev/block/%u:%u: %s", + major(dev), minor(dev), strerror(-r)); return EXIT_FAILURE; } if (r == 0) -- cgit v1.2.1 From 7384146530ac083efbef62b9ef5bb82c56565cd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 15 Aug 2013 18:24:10 -0400 Subject: gpt-auto-generator: use _cleanup_ for blkid_free_probe --- src/gpt-auto-generator/gpt-auto-generator.c | 68 +++++++++++------------------ 1 file changed, 25 insertions(+), 43 deletions(-) diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index 60cbd7ee25..222d6a0da7 100644 --- a/src/gpt-auto-generator/gpt-auto-generator.c +++ b/src/gpt-auto-generator/gpt-auto-generator.c @@ -49,9 +49,15 @@ static const char *arg_dest = "/tmp"; +static inline void blkid_free_probep(blkid_probe *b) { + if (*b) + blkid_free_probe(*b); +} +#define _cleanup_blkid_freep_probe_ _cleanup_(blkid_free_probep) + static int verify_gpt_partition(dev_t dev, sd_id128_t *type, unsigned *nr, char **fstype) { _cleanup_free_ char *t = NULL; - blkid_probe b = NULL; + _cleanup_blkid_freep_probe_ blkid_probe b = NULL; const char *v; int r; @@ -61,12 +67,8 @@ static int verify_gpt_partition(dev_t dev, sd_id128_t *type, unsigned *nr, char errno = 0; b = blkid_new_probe_from_filename(t); - if (!b) { - if (errno != 0) - return -errno; - - return -ENOMEM; - } + if (!b) + return errno != 0 ? -errno : -ENOMEM; blkid_probe_enable_superblocks(b, 1); blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE); @@ -75,36 +77,26 @@ static int verify_gpt_partition(dev_t dev, sd_id128_t *type, unsigned *nr, char errno = 0; r = blkid_do_safeprobe(b); - if (r == -2) { - r = -ENODEV; - goto finish; - } else if (r == 1) { - r = -ENODEV; - goto finish; - } else if (r != 0) { - r = errno ? -errno : -EIO; - goto finish; - } + if (r == -2) + return -ENODEV; + else if (r == 1) + return -ENODEV; + else if (r != 0) + return errno ? -errno : -EIO; errno = 0; r = blkid_probe_lookup_value(b, "PART_ENTRY_SCHEME", &v, NULL); - if (r != 0) { - r = errno ? -errno : -EIO; - goto finish; - } + if (r != 0) + return errno ? -errno : -EIO; - if (strcmp(v, "gpt") != 0) { - r = 0; - goto finish; - } + if (strcmp(v, "gpt") != 0) + return 0; if (type) { errno = 0; r = blkid_probe_lookup_value(b, "PART_ENTRY_TYPE", &v, NULL); - if (r != 0) { - r = errno ? -errno : -EIO; - goto finish; - } + if (r != 0) + return errno ? -errno : -EIO; r = sd_id128_from_string(v, type); if (r < 0) @@ -114,10 +106,8 @@ static int verify_gpt_partition(dev_t dev, sd_id128_t *type, unsigned *nr, char if (nr) { errno = 0; r = blkid_probe_lookup_value(b, "PART_ENTRY_NUMBER", &v, NULL); - if (r != 0) { - r = errno ? -errno : -EIO; - goto finish; - } + if (r != 0) + return errno ? -errno : -EIO; r = safe_atou(v, nr); if (r < 0) @@ -134,22 +124,14 @@ static int verify_gpt_partition(dev_t dev, sd_id128_t *type, unsigned *nr, char *fstype = NULL; else { fst = strdup(v); - if (!fst) { - r = -ENOMEM; - goto finish; - } + if (!fst) + return -ENOMEM; *fstype = fst; } } return 1; - -finish: - if (b) - blkid_free_probe(b); - - return r; } static int add_swap(const char *path, const char *fstype) { -- cgit v1.2.1 From 091526ab20485492124852dcf629787f35816df8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 15 Aug 2013 18:42:42 -0400 Subject: gpt-auto-generator: do not show error for non-GPT disks --- src/gpt-auto-generator/gpt-auto-generator.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index 222d6a0da7..5c0e455338 100644 --- a/src/gpt-auto-generator/gpt-auto-generator.c +++ b/src/gpt-auto-generator/gpt-auto-generator.c @@ -87,7 +87,8 @@ static int verify_gpt_partition(dev_t dev, sd_id128_t *type, unsigned *nr, char errno = 0; r = blkid_probe_lookup_value(b, "PART_ENTRY_SCHEME", &v, NULL); if (r != 0) - return errno ? -errno : -EIO; + /* return 0 if we're not on GPT */ + return errno ? -errno : 0; if (strcmp(v, "gpt") != 0) return 0; -- cgit v1.2.1 From 1291bc895b3dc52fbf7f4c3a04507c14428c4152 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 15 Aug 2013 20:01:19 -0400 Subject: udev: when complaining about invalid characters, print them out systemd-udevd[6260]: invalid key/value pair in file /usr/lib/udev/rules.d/60-ffado.rules on line 46,starting at character 84 ('#') --- src/udev/udev-rules.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index e4facd7bd2..16348126ee 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -34,6 +34,7 @@ #include "conf-files.h" #include "strbuf.h" #include "strv.h" +#include "util.h" #define PREALLOC_TOKEN 2048 @@ -1069,10 +1070,17 @@ static int add_rule(struct udev_rules *rules, char *line, if (get_key(rules->udev, &linepos, &key, &op, &value) != 0) { /* If we aren't at the end of the line, this is a parsing error. * Make a best effort to describe where the problem is. */ - if (*linepos != '\n') + if (*linepos != '\n') { + char buf[2] = {linepos[1]}; + _cleanup_free_ char *tmp; + + tmp = cescape(buf); log_error("invalid key/value pair in file %s on line %u," - "starting at character %lu\n", - filename, lineno, linepos - line + 1); + "starting at character %lu ('%s')\n", + filename, lineno, linepos - line + 1, tmp); + if (linepos[1] == '#') + log_info("hint: comments can only start at beginning of line"); + } break; } -- cgit v1.2.1 From e7627e14dc883ab0ad73c931e4ff0caa1cad6860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 15 Aug 2013 21:40:56 -0400 Subject: keymap: add Pavilion dv7 keys --- hwdb/60-keyboard.hwdb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index a77aa00d48..4e7c1a2968 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -374,12 +374,19 @@ keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[tT][aA][bB][lL][eE][tT]*:pvr* KEYBOARD_KEY_86=pageup KEYBOARD_KEY_87=pagedown -# Pavillion +# Pavilion keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[pP][aA][vV][iI][lL][iI][oO][nN]*:pvr* KEYBOARD_KEY_88=media # FIXME: quick play + KEYBOARD_KEY_b7=print KEYBOARD_KEY_d8=!f23 # touchpad off KEYBOARD_KEY_d9=!f22 # touchpad on +keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP Pavilion dv7 Notebook PC:pvr* + KEYBOARD_KEY_b7=print + KEYBOARD_KEY_c2=media # FIXME: quick play + KEYBOARD_KEY_c6=break + KEYBOARD_KEY_94=0 + # Elitebook keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*Compaq*:pvr* keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*EliteBook*:pvr* -- cgit v1.2.1 From c51cf05646a11c65daf65c1123c77efb068f4f7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 15 Aug 2013 23:13:48 -0400 Subject: Rename F_TYPE_CMP() to F_TYPE_EQUAL() --- TODO | 2 -- src/gpt-auto-generator/gpt-auto-generator.c | 2 +- src/journal/sd-journal.c | 10 +++++----- src/readahead/readahead-collect.c | 2 +- src/shared/macro.h | 2 +- src/shared/util.c | 4 ++-- 6 files changed, 10 insertions(+), 12 deletions(-) diff --git a/TODO b/TODO index 5c5e4b46f9..9bc14fdbf5 100644 --- a/TODO +++ b/TODO @@ -57,8 +57,6 @@ Features: * better error message if you run systemctl without systemd running -* rename F_TYPE_CMP() to F_TYPE_EQUAL() - * unlink PID files of units after exit * tiny tool that saves/restores backlight diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index 5c0e455338..880661e277 100644 --- a/src/gpt-auto-generator/gpt-auto-generator.c +++ b/src/gpt-auto-generator/gpt-auto-generator.c @@ -434,7 +434,7 @@ static int get_block_device(const char *path, dev_t *dev) { if (statfs("/", &sfs) < 0) return -errno; - if (F_TYPE_CMP(sfs.f_type, BTRFS_SUPER_MAGIC)) + if (F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC)) return get_btrfs_block_device(path, dev); return 0; diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index a83c0c25bf..7700d6cb12 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -1266,11 +1266,11 @@ static void check_network(sd_journal *j, int fd) { return; j->on_network = - F_TYPE_CMP(sfs.f_type, CIFS_MAGIC_NUMBER) || - F_TYPE_CMP(sfs.f_type, CODA_SUPER_MAGIC) || - F_TYPE_CMP(sfs.f_type, NCP_SUPER_MAGIC) || - F_TYPE_CMP(sfs.f_type, NFS_SUPER_MAGIC) || - F_TYPE_CMP(sfs.f_type, SMB_SUPER_MAGIC); + F_TYPE_EQUAL(sfs.f_type, CIFS_MAGIC_NUMBER) || + F_TYPE_EQUAL(sfs.f_type, CODA_SUPER_MAGIC) || + F_TYPE_EQUAL(sfs.f_type, NCP_SUPER_MAGIC) || + F_TYPE_EQUAL(sfs.f_type, NFS_SUPER_MAGIC) || + F_TYPE_EQUAL(sfs.f_type, SMB_SUPER_MAGIC); } static bool file_has_type_prefix(const char *prefix, const char *filename) { diff --git a/src/readahead/readahead-collect.c b/src/readahead/readahead-collect.c index 5d37bb75f3..32888add01 100644 --- a/src/readahead/readahead-collect.c +++ b/src/readahead/readahead-collect.c @@ -510,7 +510,7 @@ done: on_ssd = fs_on_ssd(root) > 0; log_debug("On SSD: %s", yes_no(on_ssd)); - on_btrfs = statfs(root, &sfs) >= 0 && F_TYPE_CMP(sfs.f_type, BTRFS_SUPER_MAGIC); + on_btrfs = statfs(root, &sfs) >= 0 && F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC); log_debug("On btrfs: %s", yes_no(on_btrfs)); if (asprintf(&pack_fn_new, "%s/.readahead.new", root) < 0) { diff --git a/src/shared/macro.h b/src/shared/macro.h index 969329d152..0d3ff1cda5 100644 --- a/src/shared/macro.h +++ b/src/shared/macro.h @@ -273,7 +273,7 @@ do { \ * the const magic to the type, otherwise the compiler warns about * signed/unsigned comparison, because the magic can be 32 bit unsigned. */ -#define F_TYPE_CMP(a, b) (a == (typeof(a)) b) +#define F_TYPE_EQUAL(a, b) (a == (typeof(a)) b) /* Returns the number of chars needed to format variables of the diff --git a/src/shared/util.c b/src/shared/util.c index f23dd92a6b..ca9c2eb9d1 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -2830,8 +2830,8 @@ int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct _pure_ static int is_temporary_fs(struct statfs *s) { assert(s); return - F_TYPE_CMP(s->f_type, TMPFS_MAGIC) || - F_TYPE_CMP(s->f_type, RAMFS_MAGIC); + F_TYPE_EQUAL(s->f_type, TMPFS_MAGIC) || + F_TYPE_EQUAL(s->f_type, RAMFS_MAGIC); } int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) { -- cgit v1.2.1 From f02d836794d519e717e51d81501557da55915ce2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 4 Aug 2013 09:04:20 -0400 Subject: logs-show: add short-precise mode with us timestamps Also, always show us timestamps in verbose mode. https://bugzilla.redhat.com/show_bug.cgi?id=991678 --- man/journalctl.xml | 25 +++++++++++++++++++------ src/journal/journalctl.c | 5 +++-- src/shared/logs-show.c | 25 +++++++++++++++++++------ src/shared/output-mode.h | 3 ++- src/shared/time-util.c | 22 ++++++++++++++++++++++ src/shared/time-util.h | 1 + 6 files changed, 66 insertions(+), 15 deletions(-) diff --git a/man/journalctl.xml b/man/journalctl.xml index dcc6d5dce9..8680e53285 100644 --- a/man/journalctl.xml +++ b/man/journalctl.xml @@ -253,12 +253,11 @@ - + - is very similar - but shows monotonic - timestamps instead of + is very similar, + but shows ISO 8601 wallclock timestamps. @@ -266,11 +265,25 @@ - + is very similar, - but shows ISO 8601 + but shows timestamps + with full microsecond + precision. + + + + + + + + + + is very similar + but shows monotonic + timestamps instead of wallclock timestamps. diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 5cf9390249..27c148e689 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -134,8 +134,9 @@ static int help(void) { " -n --lines[=INTEGER] Number of journal entries to show\n" " --no-tail Show all lines, even in follow mode\n" " -r --reverse Show the newest entries first\n" - " -o --output=STRING Change journal output mode (short, short-monotonic, short-iso\n" - " verbose, export, json, json-pretty, json-sse, cat)\n" + " -o --output=STRING Change journal output mode (short, short-iso,\n" + " short-precise, short-monotonic, verbose,\n" + " export, json, json-pretty, json-sse, cat)\n" " -x --catalog Add message explanations where available\n" " -l --full Do not ellipsize fields\n" " -a --all Show all fields, including long and unprintable\n" diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index af738a313e..7002675301 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -318,10 +318,21 @@ static int output_short( } t = (time_t) (x / USEC_PER_SEC); - if (mode == OUTPUT_SHORT_ISO) + + switch(mode) { + case OUTPUT_SHORT_ISO: r = strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S%z", localtime_r(&t, &tm)); - else + break; + case OUTPUT_SHORT_PRECISE: + r = strftime(buf, sizeof(buf), "%b %d %H:%M:%S", localtime_r(&t, &tm)); + if (r > 0) { + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), + ".%06llu", x % USEC_PER_SEC); + } + break; + default: r = strftime(buf, sizeof(buf), "%b %d %H:%M:%S", localtime_r(&t, &tm)); + } if (r <= 0) { log_error("Failed to format time."); @@ -380,7 +391,7 @@ static int output_verbose( size_t length; _cleanup_free_ char *cursor = NULL; uint64_t realtime; - char ts[FORMAT_TIMESTAMP_MAX]; + char ts[FORMAT_TIMESTAMP_MAX + 7]; int r; assert(f); @@ -402,7 +413,7 @@ static int output_verbose( } fprintf(f, "%s [%s]\n", - format_timestamp(ts, sizeof(ts), realtime), + format_timestamp_us(ts, sizeof(ts), realtime), cursor); JOURNAL_FOREACH_DATA_RETVAL(j, data, length, r) { @@ -849,8 +860,9 @@ static int (*output_funcs[_OUTPUT_MODE_MAX])( OutputFlags flags) = { [OUTPUT_SHORT] = output_short, - [OUTPUT_SHORT_MONOTONIC] = output_short, [OUTPUT_SHORT_ISO] = output_short, + [OUTPUT_SHORT_PRECISE] = output_short, + [OUTPUT_SHORT_MONOTONIC] = output_short, [OUTPUT_VERBOSE] = output_verbose, [OUTPUT_EXPORT] = output_export, [OUTPUT_JSON] = output_json, @@ -1131,8 +1143,9 @@ int show_journal_by_unit( static const char *const output_mode_table[_OUTPUT_MODE_MAX] = { [OUTPUT_SHORT] = "short", - [OUTPUT_SHORT_MONOTONIC] = "short-monotonic", [OUTPUT_SHORT_ISO] = "short-iso", + [OUTPUT_SHORT_PRECISE] = "short-precise", + [OUTPUT_SHORT_MONOTONIC] = "short-monotonic", [OUTPUT_VERBOSE] = "verbose", [OUTPUT_EXPORT] = "export", [OUTPUT_JSON] = "json", diff --git a/src/shared/output-mode.h b/src/shared/output-mode.h index 4012889b65..9da789db76 100644 --- a/src/shared/output-mode.h +++ b/src/shared/output-mode.h @@ -23,8 +23,9 @@ typedef enum OutputMode { OUTPUT_SHORT, - OUTPUT_SHORT_MONOTONIC, OUTPUT_SHORT_ISO, + OUTPUT_SHORT_PRECISE, + OUTPUT_SHORT_MONOTONIC, OUTPUT_VERBOSE, OUTPUT_EXPORT, OUTPUT_JSON, diff --git a/src/shared/time-util.c b/src/shared/time-util.c index 9ee711a49e..860be61e8b 100644 --- a/src/shared/time-util.c +++ b/src/shared/time-util.c @@ -168,6 +168,28 @@ char *format_timestamp(char *buf, size_t l, usec_t t) { return buf; } +char *format_timestamp_us(char *buf, size_t l, usec_t t) { + struct tm tm; + time_t sec; + + assert(buf); + assert(l > 0); + + if (t <= 0) + return NULL; + + sec = (time_t) (t / USEC_PER_SEC); + localtime_r(&sec, &tm); + + if (strftime(buf, l, "%a %Y-%m-%d %H:%M:%S", &tm) <= 0) + return NULL; + snprintf(buf + strlen(buf), l - strlen(buf), ".%06llu", t % USEC_PER_SEC); + if (strftime(buf + strlen(buf), l - strlen(buf), " %Z", &tm) <= 0) + return NULL; + + return buf; +} + char *format_timestamp_relative(char *buf, size_t l, usec_t t) { usec_t n, d; diff --git a/src/shared/time-util.h b/src/shared/time-util.h index f27a006891..7660fe1872 100644 --- a/src/shared/time-util.h +++ b/src/shared/time-util.h @@ -73,6 +73,7 @@ usec_t timeval_load(const struct timeval *tv) _pure_; struct timeval *timeval_store(struct timeval *tv, usec_t u); char *format_timestamp(char *buf, size_t l, usec_t t); +char *format_timestamp_us(char *buf, size_t l, usec_t t); char *format_timestamp_relative(char *buf, size_t l, usec_t t); char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy); -- cgit v1.2.1 From cf40f0be1acc73ea7dfb9aabc213f6a762ea62d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 7 Aug 2013 22:55:29 -0400 Subject: logs-show: show source timestamp in verbose mode This makes verbose behave like short mode, i.e. try to show the source timestamp, and fall back to journald timestamp only if unavailable or unparsable. I think verbose should be like short, only showing more fields, and showing different timestamps would be confusing. --- src/shared/logs-show.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index 7002675301..89a73a5860 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -399,11 +399,35 @@ static int output_verbose( sd_journal_set_data_threshold(j, 0); - r = sd_journal_get_realtime_usec(j, &realtime); - if (r < 0) { + r = sd_journal_get_data(j, "_SOURCE_REALTIME_TIMESTAMP", &data, &length); + if (r == -ENOENT) + log_debug("Source realtime timestamp not found"); + else if (r < 0) { log_full(r == -EADDRNOTAVAIL ? LOG_DEBUG : LOG_ERR, - "Failed to get realtime timestamp: %s", strerror(-r)); + "Failed to get source realtime timestamp: %s", strerror(-r)); return r; + } else { + _cleanup_free_ char *value = NULL; + size_t size; + + r = parse_field(data, length, "_SOURCE_REALTIME_TIMESTAMP=", &value, &size); + if (r < 0) + log_debug("_SOURCE_REALTIME_TIMESTAMP invalid: %s", strerror(-r)); + else { + r = safe_atou64(value, &realtime); + if (r < 0) + log_debug("Failed to parse realtime timestamp: %s", + strerror(-r)); + } + } + + if (r < 0) { + r = sd_journal_get_realtime_usec(j, &realtime); + if (r < 0) { + log_full(r == -EADDRNOTAVAIL ? LOG_DEBUG : LOG_ERR, + "Failed to get realtime timestamp: %s", strerror(-r)); + return r; + } } r = sd_journal_get_cursor(j, &cursor); -- cgit v1.2.1 From 2526d6269112ba8b4f771a2c42fa1aa28563cd48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 21 Aug 2013 01:34:57 -0400 Subject: logs-show: fix condition for ellipsizing multi-line messages falconindy> the ellipsizing seems a bit wrong here.... I got a bit carried away with putting dots everywhere :) --- src/shared/logs-show.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index 89a73a5860..f0236eeae5 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -132,14 +132,14 @@ static bool print_multiline(FILE *f, unsigned prefix, unsigned n_columns, Output len = end - pos; assert(len >= 0); - /* We need to figure out when we are showing the last line, and + /* We need to figure out when we are showing not-last line, *and* * will skip subsequent lines. In that case, we will put the dots * at the end of the line, instead of putting dots in the middle * or not at all. */ tail_line = line + 1 == PRINT_LINE_THRESHOLD || - end + 1 >= message + message_len; + end + 1 >= message + PRINT_CHAR_THRESHOLD; if (flags & (OUTPUT_FULL_WIDTH | OUTPUT_SHOW_ALL) || (prefix + len + 1 < n_columns && !tail_line)) { -- cgit v1.2.1 From 0611ef5cc132784f79bb411fac137615a5b94582 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 21 Aug 2013 13:09:50 +0200 Subject: add freenode verification --- freenode.ver | 1 + 1 file changed, 1 insertion(+) create mode 100644 freenode.ver diff --git a/freenode.ver b/freenode.ver new file mode 100644 index 0000000000..769337fc8f --- /dev/null +++ b/freenode.ver @@ -0,0 +1 @@ +Verification for #systemd - 20130821 oidet6OnteegNidJiff1Ziervov0 -- cgit v1.2.1 From 67ccd1c4b821b142ccd7b4bb292d9947aea8c581 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 21 Aug 2013 14:11:43 +0200 Subject: remove freenode verification file --- freenode.ver | 1 - 1 file changed, 1 deletion(-) delete mode 100644 freenode.ver diff --git a/freenode.ver b/freenode.ver deleted file mode 100644 index 769337fc8f..0000000000 --- a/freenode.ver +++ /dev/null @@ -1 +0,0 @@ -Verification for #systemd - 20130821 oidet6OnteegNidJiff1Ziervov0 -- cgit v1.2.1 From 143bfdaf0b890fa7acadf02d1eafacaef1b696bd Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Thu, 18 Jul 2013 08:30:06 +0200 Subject: test: Make testing work on systems without or old systemd * Introduce a macro to conditionally execute tests. This avoids skipping the entire test if some parts require systemd * Skip the journal tests when no /etc/machine-id is present * Change test-catalog to load the catalog from the source directory of systemd. * /proc/PID/comm got introduced in v2.6.33 but travis is still using v2.6.32. * Enable make check and make distcheck on the travis build * Use -D"CATALOG_DIR=STR($(abs_top_srcdir)/catalog)" as a STRINGIY would result in the path '/home/ich/source/linux' to be expanded to '/home/ich/source/1' as linux is defined to 1. --- .travis.yml | 5 +++-- Makefile.am | 13 +++++++++++-- src/journal/test-catalog.c | 20 +++++++++++++++++--- src/journal/test-journal-interleaving.c | 4 ++++ src/journal/test-journal-stream.c | 4 ++++ src/journal/test-journal-verify.c | 4 ++++ src/journal/test-journal.c | 4 ++++ src/test/test-cgroup-util.c | 5 +++-- src/test/test-helper.h | 31 +++++++++++++++++++++++++++++++ src/test/test-id128.c | 11 +++++++---- src/test/test-unit-file.c | 3 ++- src/test/test-unit-name.c | 5 ++++- src/test/test-util.c | 9 +++++++-- 13 files changed, 101 insertions(+), 17 deletions(-) create mode 100644 src/test/test-helper.h diff --git a/.travis.yml b/.travis.yml index 42433fd4d0..7e5251cfb0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,8 +3,9 @@ compiler: - gcc before_install: - sudo apt-get update -qq - - sudo apt-get install autotools-dev automake autoconf libtool libdbus-1-dev libcap-dev libblkid-dev libpam-dev libcryptsetup-dev libaudit-dev libacl1-dev libattr1-dev libselinux-dev liblzma-dev libgcrypt-dev libqrencode-dev libmicrohttpd-dev gtk-doc-tools gperf -script: ./autogen.sh && ./configure --enable-gtk-doc --enable-gtk-doc-pdf && make V=1 && make dist V=1 + - sudo apt-get install autotools-dev automake autoconf libtool libdbus-1-dev libcap-dev libblkid-dev libpam-dev libcryptsetup-dev libaudit-dev libacl1-dev libattr1-dev libselinux-dev liblzma-dev libgcrypt-dev libqrencode-dev libmicrohttpd-dev gtk-doc-tools gperf python2.7-dev +script: ./autogen.sh && ./configure --enable-gtk-doc --enable-gtk-doc-pdf && make V=1 && sudo ./systemd-machine-id-setup && make check && make distcheck +after_failure: cat test-suite.log notifications: irc: channels: diff --git a/Makefile.am b/Makefile.am index fdfdd6515e..fd38e8201f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1143,6 +1143,9 @@ EXTRA_DIST += \ test/sched_rr_ok.service \ test/sched_rr_change.service +EXTRA_DIST += \ + src/test/test-helper.h + test_engine_SOURCES = \ src/test/test-engine.c @@ -1341,7 +1344,8 @@ test_cgroup_util_SOURCES = \ test_cgroup_util_LDADD = \ libsystemd-label.la \ - libsystemd-shared.la + libsystemd-shared.la \ + libsystemd-daemon.la test_env_replace_SOURCES = \ src/test/test-env-replace.c @@ -2680,7 +2684,8 @@ test_id128_SOURCES = \ test_id128_LDADD = \ libsystemd-shared.la \ - libsystemd-id128-internal.la + libsystemd-id128-internal.la \ + libsystemd-daemon.la tests += \ test-id128 @@ -2852,6 +2857,10 @@ test_mmap_cache_LDADD = \ test_catalog_SOURCES = \ src/journal/test-catalog.c +test_catalog_CFLAGS = \ + $(AM_CFLAGS) \ + -DCATALOG_DIR=\"$(abs_top_srcdir)/catalog\" + test_catalog_LDADD = \ libsystemd-shared.la \ libsystemd-label.la \ diff --git a/src/journal/test-catalog.c b/src/journal/test-catalog.c index 987867f0c8..5db5bed8de 100644 --- a/src/journal/test-catalog.c +++ b/src/journal/test-catalog.c @@ -31,6 +31,16 @@ #include "sd-messages.h" #include "catalog.h" +static const char *catalog_dirs[] = { + CATALOG_DIR, + NULL, +}; + +static const char *no_catalog_dirs[] = { + "/bin/hopefully/with/no/catalog", + NULL +}; + static void test_import(Hashmap *h, struct strbuf *sb, const char* contents, ssize_t size, int code) { int r; @@ -100,9 +110,13 @@ static void test_catalog_update(void) { r = catalog_update(database, NULL, NULL); assert(r >= 0); - /* Note: this might actually not find anything, if systemd was - * not installed before. That should be fine too. */ - r = catalog_update(database, NULL, catalog_file_dirs); + /* Test what happens if there are no files in the directory. */ + r = catalog_update(database, NULL, no_catalog_dirs); + assert(r >= 0); + + /* Make sure that we at least have some files loaded or the + catalog_list below will fail. */ + r = catalog_update(database, NULL, catalog_dirs); assert(r >= 0); } diff --git a/src/journal/test-journal-interleaving.c b/src/journal/test-journal-interleaving.c index 069d297a9f..2b21523f57 100644 --- a/src/journal/test-journal-interleaving.c +++ b/src/journal/test-journal-interleaving.c @@ -288,6 +288,10 @@ static void test_sequence_numbers(void) { int main(int argc, char *argv[]) { log_set_max_level(LOG_DEBUG); + /* journal_file_open requires a valid machine id */ + if (access("/etc/machine-id", F_OK) != 0) + return EXIT_TEST_SKIP; + arg_keep = argc > 1; test_skip(setup_sequential); diff --git a/src/journal/test-journal-stream.c b/src/journal/test-journal-stream.c index 6b32b252e8..8e1d08d596 100644 --- a/src/journal/test-journal-stream.c +++ b/src/journal/test-journal-stream.c @@ -80,6 +80,10 @@ int main(int argc, char *argv[]) { const void *data; size_t l; + /* journal_file_open requires a valid machine id */ + if (access("/etc/machine-id", F_OK) != 0) + return EXIT_TEST_SKIP; + log_set_max_level(LOG_DEBUG); assert_se(mkdtemp(t)); diff --git a/src/journal/test-journal-verify.c b/src/journal/test-journal-verify.c index 6b7414a4b1..0540074207 100644 --- a/src/journal/test-journal-verify.c +++ b/src/journal/test-journal-verify.c @@ -77,6 +77,10 @@ int main(int argc, char *argv[]) { struct stat st; uint64_t p; + /* journal_file_open requires a valid machine id */ + if (access("/etc/machine-id", F_OK) != 0) + return EXIT_TEST_SKIP; + log_set_max_level(LOG_DEBUG); assert_se(mkdtemp(t)); diff --git a/src/journal/test-journal.c b/src/journal/test-journal.c index 534fd28fa6..190c426eba 100644 --- a/src/journal/test-journal.c +++ b/src/journal/test-journal.c @@ -174,6 +174,10 @@ static void test_empty(void) { int main(int argc, char *argv[]) { arg_keep = argc > 1; + /* journal_file_open requires a valid machine id */ + if (access("/etc/machine-id", F_OK) != 0) + return EXIT_TEST_SKIP; + test_non_empty(); test_empty(); diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c index 295bb02e3b..16bf968340 100644 --- a/src/test/test-cgroup-util.c +++ b/src/test/test-cgroup-util.c @@ -23,6 +23,7 @@ #include "util.h" #include "cgroup-util.h" +#include "test-helper.h" static void check_p_d_u(const char *path, int code, const char *result) { _cleanup_free_ char *unit = NULL; @@ -239,9 +240,9 @@ int main(void) { test_path_get_session(); test_path_get_owner_uid(); test_path_get_machine_name(); - test_get_paths(); + TEST_REQ_RUNNING_SYSTEMD(test_get_paths()); test_proc(); - test_escape(); + TEST_REQ_RUNNING_SYSTEMD(test_escape()); test_controller_is_valid(); test_slice_to_path(); diff --git a/src/test/test-helper.h b/src/test/test-helper.h new file mode 100644 index 0000000000..92864edb54 --- /dev/null +++ b/src/test/test-helper.h @@ -0,0 +1,31 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2013 Holger Hans Peter Freyther + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include "sd-daemon.h" + +#define TEST_REQ_RUNNING_SYSTEMD(x) \ + if (sd_booted() > 0) { \ + x; \ + } else { \ + printf("systemd not booted skipping '%s'\n", #x); \ + } diff --git a/src/test/test-id128.c b/src/test/test-id128.c index 2ed8e292e6..7b92758174 100644 --- a/src/test/test-id128.c +++ b/src/test/test-id128.c @@ -25,6 +25,7 @@ #include "util.h" #include "macro.h" +#include "sd-daemon.h" #define ID128_WALDI SD_ID128_MAKE(01, 02, 03, 04, 05, 06, 07, 08, 09, 0a, 0b, 0c, 0d, 0e, 0f, 10) #define STR_WALDI "0102030405060708090a0b0c0d0e0f10" @@ -41,11 +42,13 @@ int main(int argc, char *argv[]) { assert_se(sd_id128_from_string(t, &id2) == 0); assert_se(sd_id128_equal(id, id2)); - assert_se(sd_id128_get_machine(&id) == 0); - printf("machine: %s\n", sd_id128_to_string(id, t)); + if (sd_booted() > 0) { + assert_se(sd_id128_get_machine(&id) == 0); + printf("machine: %s\n", sd_id128_to_string(id, t)); - assert_se(sd_id128_get_boot(&id) == 0); - printf("boot: %s\n", sd_id128_to_string(id, t)); + assert_se(sd_id128_get_boot(&id) == 0); + printf("boot: %s\n", sd_id128_to_string(id, t)); + } printf("waldi: %s\n", sd_id128_to_string(ID128_WALDI, t)); assert_se(streq(t, STR_WALDI)); diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c index 2075e86115..dc6bc55244 100644 --- a/src/test/test-unit-file.c +++ b/src/test/test-unit-file.c @@ -35,6 +35,7 @@ #include "load-fragment.h" #include "strv.h" #include "fileio.h" +#include "test-helper.h" static int test_unit_file_get_set(void) { int r; @@ -366,7 +367,7 @@ int main(int argc, char *argv[]) { test_load_env_file_2(); test_load_env_file_3(); test_load_env_file_4(); - test_install_printf(); + TEST_REQ_RUNNING_SYSTEMD(test_install_printf()); return r; } diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c index 6776ef0857..c17692b845 100644 --- a/src/test/test-unit-name.c +++ b/src/test/test-unit-name.c @@ -34,6 +34,7 @@ #include "specifier.h" #include "util.h" #include "macro.h" +#include "test-helper.h" static void test_replacements(void) { #define expect(pattern, repl, expected) \ @@ -196,6 +197,8 @@ static int test_unit_printf(void) { } int main(int argc, char* argv[]) { + int rc = 0; test_replacements(); - return test_unit_printf(); + TEST_REQ_RUNNING_SYSTEMD(rc = test_unit_printf()); + return rc; } diff --git a/src/test/test-util.c b/src/test/test-util.c index 875aeab3d5..dd7768d36c 100644 --- a/src/test/test-util.c +++ b/src/test/test-util.c @@ -397,6 +397,7 @@ static void test_u64log2(void) { } static void test_get_process_comm(void) { + struct stat st; _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL; unsigned long long b; pid_t e; @@ -405,8 +406,12 @@ static void test_get_process_comm(void) { dev_t h; int r; - assert_se(get_process_comm(1, &a) >= 0); - log_info("pid1 comm: '%s'", a); + if (stat("/proc/1/comm", &st) == 0) { + assert_se(get_process_comm(1, &a) >= 0); + log_info("pid1 comm: '%s'", a); + } else { + log_warning("/proc/1/comm does not exist."); + } assert_se(get_starttime_of_pid(1, &b) >= 0); log_info("pid1 starttime: '%llu'", b); -- cgit v1.2.1 From d83c224da0aedcec9a432fe51fa27a3fed7be4b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 21 Aug 2013 23:02:46 -0400 Subject: man: typo ohsix> ooh theres a typo in the example --- man/systemd-analyze.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml index a8adf87713..60377093d0 100644 --- a/man/systemd-analyze.xml +++ b/man/systemd-analyze.xml @@ -285,7 +285,7 @@ $ eog avahi.svg This plots the dependencies between all known target units: - systemd-analyze dot --to-pattern='*.target' --from-patter='*.target' | dot -Tsvg > targets.svg + systemd-analyze dot --to-pattern='*.target' --from-pattern='*.target' | dot -Tsvg > targets.svg $ eog targets.svg -- cgit v1.2.1 From 67c15b9a7ac016ac5c9b885756b2eaa7f44a0509 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Wed, 21 Aug 2013 20:35:44 -0700 Subject: use CAP_MKNOD ConditionCapability Fixes errors seen when booting VMs on QEMU like systemd[1]: kmod-static-nodes.service: main process exited, code=exited, status=203/EXEC systemd[1]: Failed to start Create list of required static device nodes for the current kernel. systemd[1]: Unit kmod-static-nodes.service entered failed state. Make sure that mknod capability is available Signed-off-by: Khem Raj --- units/kmod-static-nodes.service.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/units/kmod-static-nodes.service.in b/units/kmod-static-nodes.service.in index 98664ea18a..d8a84204a7 100644 --- a/units/kmod-static-nodes.service.in +++ b/units/kmod-static-nodes.service.in @@ -9,7 +9,7 @@ Description=Create list of required static device nodes for the current kernel DefaultDependencies=no Before=sysinit.target systemd-tmpfiles-setup-dev.service -ConditionVirtualization=!container +ConditionCapability=CAP_MKNOD [Service] Type=oneshot -- cgit v1.2.1 From 2a0e0692565f0435657c93498e09cbb2d3517152 Mon Sep 17 00:00:00 2001 From: Shawn Landden Date: Wed, 21 Aug 2013 18:20:55 -0700 Subject: remove hasprefix(), use startswith() --- TODO | 2 -- src/journal/journal-send.c | 2 +- src/journal/journald-native.c | 12 ++++++------ src/libsystemd-bus/bus-match.c | 26 +++++++++++++------------- src/shared/logs-show.c | 2 +- src/shared/macro.h | 2 -- 6 files changed, 21 insertions(+), 25 deletions(-) diff --git a/TODO b/TODO index 9bc14fdbf5..3800ce4767 100644 --- a/TODO +++ b/TODO @@ -96,8 +96,6 @@ Features: * systemctl list-unit-files should list generated files (and probably with a new state "generated" for them, or so) -* do we really need both hasprefix() and startswith()? - * journald: when we drop syslog messages because the syslog socket is full, make sure to write how many messages are lost as first thing to syslog when it works again. diff --git a/src/journal/journal-send.c b/src/journal/journal-send.c index fef66fc29a..d00e26f1eb 100644 --- a/src/journal/journal-send.c +++ b/src/journal/journal-send.c @@ -245,7 +245,7 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int n) { have_syslog_identifier = have_syslog_identifier || (c == (char *) iov[i].iov_base + 17 && - hasprefix(iov[i].iov_base, "SYSLOG_IDENTIFIER")); + startswith(iov[i].iov_base, "SYSLOG_IDENTIFIER")); nl = memchr(iov[i].iov_base, '\n', iov[i].iov_len); if (nl) { diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c index 0f9af378cf..c50cf64f5c 100644 --- a/src/journal/journald-native.c +++ b/src/journal/journald-native.c @@ -154,23 +154,23 @@ void server_process_native_message( * of this entry for the rate limiting * logic */ if (l == 10 && - hasprefix(p, "PRIORITY=") && + startswith(p, "PRIORITY=") && p[9] >= '0' && p[9] <= '9') priority = (priority & LOG_FACMASK) | (p[9] - '0'); else if (l == 17 && - hasprefix(p, "SYSLOG_FACILITY=") && + startswith(p, "SYSLOG_FACILITY=") && p[16] >= '0' && p[16] <= '9') priority = (priority & LOG_PRIMASK) | ((p[16] - '0') << 3); else if (l == 18 && - hasprefix(p, "SYSLOG_FACILITY=") && + startswith(p, "SYSLOG_FACILITY=") && p[16] >= '0' && p[16] <= '9' && p[17] >= '0' && p[17] <= '9') priority = (priority & LOG_PRIMASK) | (((p[16] - '0')*10 + (p[17] - '0')) << 3); else if (l >= 19 && - hasprefix(p, "SYSLOG_IDENTIFIER=")) { + startswith(p, "SYSLOG_IDENTIFIER=")) { char *t; t = strndup(p + 18, l - 18); @@ -179,7 +179,7 @@ void server_process_native_message( identifier = t; } } else if (l >= 8 && - hasprefix(p, "MESSAGE=")) { + startswith(p, "MESSAGE=")) { char *t; t = strndup(p + 8, l - 8); @@ -189,7 +189,7 @@ void server_process_native_message( } } else if (l > strlen("OBJECT_PID=") && l < strlen("OBJECT_PID=") + DECIMAL_STR_MAX(pid_t) && - hasprefix(p, "OBJECT_PID=") && + startswith(p, "OBJECT_PID=") && allow_object_pid(ucred)) { char buf[DECIMAL_STR_MAX(pid_t)]; memcpy(buf, p + strlen("OBJECT_PID="), l - strlen("OBJECT_PID=")); diff --git a/src/libsystemd-bus/bus-match.c b/src/libsystemd-bus/bus-match.c index 750acfe6d5..1411167a7f 100644 --- a/src/libsystemd-bus/bus-match.c +++ b/src/libsystemd-bus/bus-match.c @@ -555,22 +555,22 @@ static int bus_match_find_leaf( enum bus_match_node_type bus_match_node_type_from_string(const char *k, size_t n) { assert(k); - if (n == 4 && hasprefix(k, "type")) + if (n == 4 && startswith(k, "type")) return BUS_MATCH_MESSAGE_TYPE; - if (n == 6 && hasprefix(k, "sender")) + if (n == 6 && startswith(k, "sender")) return BUS_MATCH_SENDER; - if (n == 11 && hasprefix(k, "destination")) + if (n == 11 && startswith(k, "destination")) return BUS_MATCH_DESTINATION; - if (n == 9 && hasprefix(k, "interface")) + if (n == 9 && startswith(k, "interface")) return BUS_MATCH_INTERFACE; - if (n == 6 && hasprefix(k, "member")) + if (n == 6 && startswith(k, "member")) return BUS_MATCH_MEMBER; - if (n == 4 && hasprefix(k, "path")) + if (n == 4 && startswith(k, "path")) return BUS_MATCH_PATH; - if (n == 14 && hasprefix(k, "path_namespace")) + if (n == 14 && startswith(k, "path_namespace")) return BUS_MATCH_PATH_NAMESPACE; - if (n == 4 && hasprefix(k, "arg")) { + if (n == 4 && startswith(k, "arg")) { int j; j = undecchar(k[3]); @@ -580,7 +580,7 @@ enum bus_match_node_type bus_match_node_type_from_string(const char *k, size_t n return BUS_MATCH_ARG + j; } - if (n == 5 && hasprefix(k, "arg")) { + if (n == 5 && startswith(k, "arg")) { int a, b; enum bus_match_node_type t; @@ -596,7 +596,7 @@ enum bus_match_node_type bus_match_node_type_from_string(const char *k, size_t n return t; } - if (n == 8 && hasprefix(k, "arg") && hasprefix(k + 4, "path")) { + if (n == 8 && startswith(k, "arg") && startswith(k + 4, "path")) { int j; j = undecchar(k[3]); @@ -606,7 +606,7 @@ enum bus_match_node_type bus_match_node_type_from_string(const char *k, size_t n return BUS_MATCH_ARG_PATH + j; } - if (n == 9 && hasprefix(k, "arg") && hasprefix(k + 5, "path")) { + if (n == 9 && startswith(k, "arg") && startswith(k + 5, "path")) { enum bus_match_node_type t; int a, b; @@ -622,7 +622,7 @@ enum bus_match_node_type bus_match_node_type_from_string(const char *k, size_t n return t; } - if (n == 13 && hasprefix(k, "arg") && hasprefix(k + 4, "namespace")) { + if (n == 13 && startswith(k, "arg") && startswith(k + 4, "namespace")) { int j; j = undecchar(k[3]); @@ -632,7 +632,7 @@ enum bus_match_node_type bus_match_node_type_from_string(const char *k, size_t n return BUS_MATCH_ARG_NAMESPACE + j; } - if (n == 14 && hasprefix(k, "arg") && hasprefix(k + 5, "namespace")) { + if (n == 14 && startswith(k, "arg") && startswith(k + 5, "namespace")) { enum bus_match_node_type t; int a, b; diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index f0236eeae5..87633e7816 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -536,7 +536,7 @@ static int output_export( /* We already printed the boot id, from the data in * the header, hence let's suppress it here */ if (length >= 9 && - hasprefix(data, "_BOOT_ID=")) + startswith(data, "_BOOT_ID=")) continue; if (!utf8_is_printable(data, length)) { diff --git a/src/shared/macro.h b/src/shared/macro.h index 0d3ff1cda5..d4f92b60ec 100644 --- a/src/shared/macro.h +++ b/src/shared/macro.h @@ -186,8 +186,6 @@ static inline size_t ALIGN_TO(size_t l, size_t ali) { #define char_array_0(x) x[sizeof(x)-1] = 0; -#define hasprefix(s, prefix) (memcmp(s, prefix, strlen(prefix)) == 0) - #define IOVEC_SET_STRING(i, s) \ do { \ struct iovec *_i = &(i); \ -- cgit v1.2.1 From df89481a35d4d7d58c7563f3082f67c218891375 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 21 Aug 2013 22:16:44 +0200 Subject: Optimize startswith() to macro I guess it's easier and cleaner anyway to use simple static inline functions instead of defines. --- src/shared/util.c | 34 ---------------------------------- src/shared/util.h | 14 ++++++++++++-- 2 files changed, 12 insertions(+), 36 deletions(-) diff --git a/src/shared/util.c b/src/shared/util.c index ca9c2eb9d1..1dde8afcad 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -128,40 +128,6 @@ char* endswith(const char *s, const char *postfix) { return (char*) s + sl - pl; } -char* startswith(const char *s, const char *prefix) { - const char *a, *b; - - assert(s); - assert(prefix); - - a = s, b = prefix; - for (;;) { - if (*b == 0) - return (char*) a; - if (*a != *b) - return NULL; - - a++, b++; - } -} - -char* startswith_no_case(const char *s, const char *prefix) { - const char *a, *b; - - assert(s); - assert(prefix); - - a = s, b = prefix; - for (;;) { - if (*b == 0) - return (char*) a; - if (tolower(*a) != tolower(*b)) - return NULL; - - a++, b++; - } -} - bool first_word(const char *s, const char *word) { size_t sl, wl; diff --git a/src/shared/util.h b/src/shared/util.h index 3be692ec33..63f4e3dff2 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -106,9 +106,19 @@ static inline bool isempty(const char *p) { return !p || !p[0]; } +static inline const char *startswith(const char *s, const char *prefix) { + if (strncmp(s, prefix, strlen(prefix)) == 0) + return s + strlen(prefix); + return NULL; +} + +static inline const char *startswith_no_case(const char *s, const char *prefix) { + if (strncasecmp(s, prefix, strlen(prefix)) == 0) + return s + strlen(prefix); + return NULL; +} + char *endswith(const char *s, const char *postfix) _pure_; -char *startswith(const char *s, const char *prefix) _pure_; -char *startswith_no_case(const char *s, const char *prefix) _pure_; bool first_word(const char *s, const char *word) _pure_; -- cgit v1.2.1 From 73814ca287cafcfa488f7ac85b25bc8584334db3 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 22 Aug 2013 17:03:29 -0400 Subject: Revert "udevd: simplify sigterm check" This reverts commit 47e737dc13bf4251ae5a2249ec29b34503ed92e1 - it introduced a use-after-free. The only way the code would get simpler is with a cleanup function, but eh, not worth it for just this one bit. Reviewed by kay on IRC. --- src/udev/udevd.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/udev/udevd.c b/src/udev/udevd.c index fd799cc910..7c6c5d6a87 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -314,10 +314,12 @@ static void worker_new(struct event *event) udev_device_unref(dev); dev = NULL; - udev_event_unref(udev_event); - - if (udev_event->sigterm) + if (udev_event->sigterm) { + udev_event_unref(udev_event); goto out; + } + + udev_event_unref(udev_event); /* wait for more device messages from main udevd, or term signal */ while (dev == NULL) { -- cgit v1.2.1 From 1f11a0cdfe397cc404d61ee679fc12f58c0a885b Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Fri, 23 Aug 2013 18:46:06 +0200 Subject: cgroup.c: check return value of unit_realize_cgroup_now() do not recurse further, if unit_realize_cgroup_now() failed --- src/core/cgroup.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 5a1c3adacd..50b17f3802 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -432,8 +432,13 @@ static int unit_realize_cgroup_now(Unit *u) { return 0; /* First, realize parents */ - if (UNIT_ISSET(u->slice)) - unit_realize_cgroup_now(UNIT_DEREF(u->slice)); + if (UNIT_ISSET(u->slice)) { + int r; + + r = unit_realize_cgroup_now(UNIT_DEREF(u->slice)); + if (r < 0) + return r; + } /* And then do the real work */ return unit_create_cgroups(u, mask); -- cgit v1.2.1 From d182614649b48c00615d744e2b7f4a14180a980d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 21 Aug 2013 19:35:32 -0400 Subject: nspawn: trivial simplification --- src/nspawn/nspawn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index fc005d9ce3..f8208607ce 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -1602,7 +1602,7 @@ int main(int argc, char *argv[]) { } if ((asprintf((char **)(envp + n_env++), "LISTEN_FDS=%u", n_fd_passed) < 0) || - (asprintf((char **)(envp + n_env++), "LISTEN_PID=%lu", (unsigned long) 1) < 0)) { + (asprintf((char **)(envp + n_env++), "LISTEN_PID=1") < 0)) { log_oom(); goto child_fail; } -- cgit v1.2.1 From f2369103655ccfd830b08cbc01fa776ba91a580d Mon Sep 17 00:00:00 2001 From: Gao feng Date: Fri, 23 Aug 2013 17:53:23 +0800 Subject: blkio: fix incorrect setting of cpu_shares We should set up blockio_weight not cpu_shares. --- src/core/dbus-cgroup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c index 8ad3d118c5..9e97b20d1e 100644 --- a/src/core/dbus-cgroup.c +++ b/src/core/dbus-cgroup.c @@ -216,7 +216,7 @@ int bus_cgroup_set_property( return -EINVAL; if (mode != UNIT_CHECK) { - c->cpu_shares = ul; + c->blockio_weight = ul; unit_write_drop_in_private_format(u, mode, name, "BlockIOWeight=%lu", ul); } -- cgit v1.2.1 From 7c902b146815a74796bb65d34b27b036d88cba81 Mon Sep 17 00:00:00 2001 From: Shawn Landden Date: Thu, 22 Aug 2013 21:17:16 -0700 Subject: udev: fix printf(3) type specifier src/udev/udev-rules.c: In function 'add_rule': src/udev/udev-rules.c:1078:33: warning: format '%lu' expects argument of type 'long unsigned int', but argument 8 has type 'int' [-Wformat=] log_error("invalid key/value pair in file %s on line %u," ^ --- src/udev/udev-rules.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index 16348126ee..f14158b500 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -1076,7 +1076,7 @@ static int add_rule(struct udev_rules *rules, char *line, tmp = cescape(buf); log_error("invalid key/value pair in file %s on line %u," - "starting at character %lu ('%s')\n", + "starting at character %tu ('%s')\n", filename, lineno, linepos - line + 1, tmp); if (linepos[1] == '#') log_info("hint: comments can only start at beginning of line"); -- cgit v1.2.1 From ac8e20c6e95975316279740778f381ad50a1a21a Mon Sep 17 00:00:00 2001 From: Shawn Landden Date: Wed, 21 Aug 2013 09:56:58 -0700 Subject: man: make reference to bind(2) explicit --- man/systemd.socket.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml index 852010bfaa..1fc28c54e4 100644 --- a/man/systemd.socket.xml +++ b/man/systemd.socket.xml @@ -510,7 +510,7 @@ ReusePort= Takes a boolean - value. If true, allows multiple bind()s + value. If true, allows multiple bind2s to this TCP or UDP port. This controls the SO_REUSEPORT socket option. See -- cgit v1.2.1 From ea92ae33e0fbbf8a98cd2e08ca5a850d83d57fae Mon Sep 17 00:00:00 2001 From: Maciej Wereski Date: Wed, 21 Aug 2013 16:43:55 +0200 Subject: "-" prefix for InaccessibleDirectories and ReadOnlyDirectories --- TODO | 6 +++--- man/systemd.exec.xml | 10 +++++++++- src/core/namespace.c | 12 +++++++++++- src/shared/conf-parser.c | 10 ++++++++-- 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/TODO b/TODO index 3800ce4767..fe305ecb66 100644 --- a/TODO +++ b/TODO @@ -23,6 +23,9 @@ Bugfixes: - make the resulting line the requested number of *characters*, not *bytes*, - avoid truncuating multi-byte sequences in the middle. +* When we detect invalid UTF-8, we cant't use it in an error message: + log...("Path is not UTF-8 clean, ignoring assignment: %s", rvalue); + * shorten the message to sane length: Cannot add dependency job for unit display-manager.service, ignoring: Unit display-manager.service failed to load: No such file or directory. See system logs and 'systemctl status display-manager.service' for details. @@ -285,9 +288,6 @@ Features: * timedate: have global on/off switches for auto-time (NTP), and auto-timezone that connman can subscribe to. -* Honour "-" prefix for InaccessibleDirectories= and ReadOnlyDirectories= to - suppress errors of the specified path doesn't exist - * dev-setup.c: when running in a container, create a tiny stub udev database with the systemd tag set for all network interfaces found, so that libudev reports them as present, and systemd's .device units diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index c0e1d862a6..b761832ed6 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -828,7 +828,15 @@ the empty string is assigned to this option the specific list is reset, and all prior assignments have no - effect. + effect. + Paths in + ReadOnlyDirectories= + and + InaccessibleDirectories= + may be prefixed with + -, in which case + they will be ignored when they don't + exist. diff --git a/src/core/namespace.c b/src/core/namespace.c index 7e33d84156..16b132ba56 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -51,6 +51,7 @@ typedef struct BindMount { const char *path; MountMode mode; bool done; + bool ignore; } BindMount; static int append_mounts(BindMount **p, char **strv, MountMode mode) { @@ -58,6 +59,13 @@ static int append_mounts(BindMount **p, char **strv, MountMode mode) { STRV_FOREACH(i, strv) { + (*p)->ignore = false; + + if ((mode == INACCESSIBLE || mode == READONLY) && (*i)[0] == '-') { + (*p)->ignore = true; + (*i)++; + } + if (!path_is_absolute(*i)) return -EINVAL; @@ -155,6 +163,8 @@ static int apply_mount( r = mount(what, m->path, NULL, MS_BIND|MS_REC, NULL); if (r >= 0) log_debug("Successfully mounted %s to %s", what, m->path); + else if (m->ignore && errno == ENOENT) + r = 0; return r; } @@ -168,7 +178,7 @@ static int make_read_only(BindMount *m) { return 0; r = mount(NULL, m->path, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_REC, NULL); - if (r < 0) + if (r < 0 && !(m->ignore && errno == ENOENT)) return -errno; return 0; diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c index 2303d9a50b..6085d33391 100644 --- a/src/shared/conf-parser.c +++ b/src/shared/conf-parser.c @@ -599,6 +599,7 @@ int config_parse_path(const char *unit, char **s = data; char *n; + int offset; assert(filename); assert(lvalue); @@ -611,7 +612,9 @@ int config_parse_path(const char *unit, return 0; } - if (!path_is_absolute(rvalue)) { + offset = rvalue[0] == '-' && (streq(lvalue, "InaccessibleDirectories") || + streq(lvalue, "ReadOnlyDirectories")); + if (!path_is_absolute(rvalue + offset)) { log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Not an absolute path, ignoring: %s", rvalue); return 0; @@ -713,6 +716,7 @@ int config_parse_path_strv(const char *unit, FOREACH_WORD_QUOTED(w, l, rvalue, state) { _cleanup_free_ char *n; + int offset; n = strndup(w, l); if (!n) @@ -724,7 +728,9 @@ int config_parse_path_strv(const char *unit, continue; } - if (!path_is_absolute(n)) { + offset = n[0] == '-' && (streq(lvalue, "InaccessibleDirectories") || + streq(lvalue, "ReadOnlyDirectories")); + if (!path_is_absolute(n + offset)) { log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Not an absolute path, ignoring: %s", rvalue); continue; -- cgit v1.2.1 From 862f4963c6f7778cea9e715eeb11ea959eba6db3 Mon Sep 17 00:00:00 2001 From: William Giokas <1007380@gmail.com> Date: Tue, 20 Aug 2013 22:06:54 -0500 Subject: zsh_completion: Fix single letter args Things like -n to specify the lines to show with systemctl and journalctl accepts syntax like: journalctl -n4 systemctl -n14 Previously, typing `-nXX ` where XX is a number, zsh would try to complete an integer. Now it will see the XX and use the _journalctl_none completion. This is also how any of the single letter options that take arguments work as well. --- shell-completion/zsh/_hostnamectl | 2 +- shell-completion/zsh/_journalctl | 14 +++++++------- shell-completion/zsh/_localectl | 2 +- shell-completion/zsh/_loginctl | 6 +++--- shell-completion/zsh/_machinectl | 6 +++--- shell-completion/zsh/_systemctl | 12 ++++++------ shell-completion/zsh/_systemd | 8 ++++---- shell-completion/zsh/_systemd-coredumpctl | 4 ++-- shell-completion/zsh/_systemd-delta | 2 +- shell-completion/zsh/_systemd-nspawn | 8 ++++---- shell-completion/zsh/_timedatectl | 2 +- 11 files changed, 33 insertions(+), 33 deletions(-) diff --git a/shell-completion/zsh/_hostnamectl b/shell-completion/zsh/_hostnamectl index 9d01495ea5..45b9597897 100644 --- a/shell-completion/zsh/_hostnamectl +++ b/shell-completion/zsh/_hostnamectl @@ -28,5 +28,5 @@ _arguments -s \ '--static[Only set static hostname]' \ '--pretty[Only set pretty hostname]' \ '--no-ask-password[Do not prompt for password]' \ - {-H,--host=}'[Operate on remote host]:userathost:_sd_hosts_or_user_at_host' \ + {-H+,--host=}'[Operate on remote host]:userathost:_sd_hosts_or_user_at_host' \ '*::hostnamectl commands:_hostnamectl_command' diff --git a/shell-completion/zsh/_journalctl b/shell-completion/zsh/_journalctl index 212bfdbc2a..7c5cc13bf0 100644 --- a/shell-completion/zsh/_journalctl +++ b/shell-completion/zsh/_journalctl @@ -62,26 +62,26 @@ _arguments -s \ {-a,--all}'[Show all fields, including long and unprintable]' \ {-f,--follow}'[Follow journal]' \ {-e,--pager-end}'[Jump to the end of the journal in the pager]' \ - {-n,--lines=}'[Number of journal entries to show]:integer' \ + {-n+,--lines=}'[Number of journal entries to show]:integer' \ '--no-tail[Show all lines, even in follow mode]' \ {-r,--reverse}'[Reverse output]' \ - {-o,--output=}'[Change journal output mode]:output modes:_outputmodes' \ + {-o+,--output=}'[Change journal output mode]:output modes:_outputmodes' \ {-x,--catalog}'[Show explanatory texts with each log line]' \ {-q,--quiet}"[Don't show privilege warning]" \ {-m,--merge}'[Show entries from all available journals]' \ - {-b,--boot=}'[Show data only from the specified boot or offset]:boot id or offset:_journal_boots' \ + {-b+,--boot=}'[Show data only from the specified boot or offset]:boot id or offset:_journal_boots' \ {-k,--dmesg}'[Show only kernel messages, Implies -b]' \ - {-u,--unit=}'[Show data only from the specified unit]:units:_journal_fields _SYSTEMD_UNIT' \ + {-u+,--unit=}'[Show data only from the specified unit]:units:_journal_fields _SYSTEMD_UNIT' \ '--user-unit[Show data only from the specified user session unit]:units:_journal_fields _SYSTEMD_USER_UNIT' \ - {-p,--priority=}'[Show only messages within the specified priority range]:priority:_journal_fields PRIORITY' \ - {-c,--cursor=}'[Start showing entries from specified cursor]:cursors:_journal_fields __CURSORS' \ + {-p+,--priority=}'[Show only messages within the specified priority range]:priority:_journal_fields PRIORITY' \ + {-c+,--cursor=}'[Start showing entries from specified cursor]:cursors:_journal_fields __CURSORS' \ '--after-cursor=[Start showing entries from the location in the journal after the cursor]:cursors:_journal_fields __CURSORS' \ '--since=[Start showing entries newer or of the specified date]:YYYY-MM-DD HH\:MM\:SS' \ '--until=[Stop showing entries older or of the specified date]:YYYY-MM-DD HH\:MM\:SS' \ {-F,--field=}'[List all values a certain field takes]:Fields:_list_fields' \ '--system[Show system and kernel messages]' \ '--user[Show messages from user services]' \ - {-D,--directory=}'[Show journal files from directory]:directories:_directories' \ + {-D+,--directory=}'[Show journal files from directory]:directories:_directories' \ '--file=[Operate on specified journal files]:file:_files' \ '--root=[Operate on catalog hierarchy under specified directory]:directories:_directories' \ '--new-id128[Generate a new 128 Bit ID]' \ diff --git a/shell-completion/zsh/_localectl b/shell-completion/zsh/_localectl index 321e418b50..3d76bb0c4d 100644 --- a/shell-completion/zsh/_localectl +++ b/shell-completion/zsh/_localectl @@ -79,5 +79,5 @@ _arguments \ "--no-convert[Don't convert keyboard mappings]" \ '--no-pager[Do not pipe output into a pager]' \ '--no-ask-password[Do not prompt for password]' \ - {-H,--host=}'[Operate on remote host]:userathost:_sd_hosts_or_user_at_host' \ + {-H+,--host=}'[Operate on remote host]:userathost:_sd_hosts_or_user_at_host' \ '*::localectl commands:_localectl_command' diff --git a/shell-completion/zsh/_loginctl b/shell-completion/zsh/_loginctl index 6d88685ed5..ebf6b3ae0a 100644 --- a/shell-completion/zsh/_loginctl +++ b/shell-completion/zsh/_loginctl @@ -95,12 +95,12 @@ done _arguments -s \ {-h,--help}'[Show help]' \ '--version[Show package version]' \ - \*{-p,--property=}'[Show only properties by this name]:unit property' \ + \*{-p+,--property=}'[Show only properties by this name]:unit property' \ {-a,--all}'[Show all properties, including empty ones]' \ '--kill-who=[Who to send signal to]:killwho:(main control all)' \ - {-s,--signal=}'[Which signal to send]:signal:_signals' \ + {-s+,--signal=}'[Which signal to send]:signal:_signals' \ '--no-ask-password[Do not ask for system passwords]' \ - {-H,--host=}'[Show information for remote host]:userathost:_sd_hosts_or_user_at_host' \ + {-H+,--host=}'[Show information for remote host]:userathost:_sd_hosts_or_user_at_host' \ {-P,--privileged}'[Acquire privileges before execution]' \ '--no-pager[Do not pipe output into a pager]' \ '*::loginctl command:_loginctl_command' diff --git a/shell-completion/zsh/_machinectl b/shell-completion/zsh/_machinectl index abdf46fa44..2e5e05cfcc 100644 --- a/shell-completion/zsh/_machinectl +++ b/shell-completion/zsh/_machinectl @@ -35,13 +35,13 @@ _arguments \ {-h,--help}'[Prints a short help text and exits.]' \ '--version[Prints a short version string and exits.]' \ - \*{-p,--property=}'[Limit output to specified property.]:property:(Name Id Timestamp TimestampMonotonic Service Scope Leader Class State RootDirectory)' \ + \*{-p+,--property=}'[Limit output to specified property.]:property:(Name Id Timestamp TimestampMonotonic Service Scope Leader Class State RootDirectory)' \ {-a,--all}'[Show all proerties]' \ (-l,--full)'[Do not ellipsize cgroup members]' \ '--no-pager[Do not pipe output into a pager]' \ '--no-ask-password[Do not ask for system passwords]' \ '--kill-who=[Who to send signal to]:killwho:(leader all)' \ - {-s,--signal=}'[Which signal to send]:signal:_signals' \ - {-H,--host=}'[Show information for remote host]:userathost:_sd_hosts_or_user_at_host' \ + {-s+,--signal=}'[Which signal to send]:signal:_signals' \ + {-H+,--host=}'[Show information for remote host]:userathost:_sd_hosts_or_user_at_host' \ {-P,--privileged}'[Acquire privileges before execution]' \ '*::machinectl command:_machinectl_command' diff --git a/shell-completion/zsh/_systemctl b/shell-completion/zsh/_systemctl index cc2df3c828..3d5f2ffeeb 100644 --- a/shell-completion/zsh/_systemctl +++ b/shell-completion/zsh/_systemctl @@ -309,9 +309,9 @@ _unit_types() { _arguments -s \ {-h,--help}'[Show help]' \ '--version[Show package version]' \ - {-t,--type=}'[List only units of a particular type]:unit type:_unit_types' \ + {-t+,--type=}'[List only units of a particular type]:unit type:_unit_types' \ '--state=[Display units in the specifyied state]:unit state:_unit_states' \ - \*{-p,--property=}'[Show only properties by specific name]:unit property' \ + \*{-p+,--property=}'[Show only properties by specific name]:unit property' \ {-a,--all}'[Show all units/properties, including dead/empty ones]' \ '--reverse[Show reverse dependencies]' \ '--after[Show units ordered after]' \ @@ -334,13 +334,13 @@ _arguments -s \ "--no-reload[When enabling/disabling unit files, don't reload daemon configuration]" \ '--no-ask-password[Do not ask for system passwords]' \ '--kill-who=[Who to send signal to]:killwho:(main control all)' \ - {-s,--signal=}'[Which signal to send]:signal:_signals' \ + {-s+,--signal=}'[Which signal to send]:signal:_signals' \ {-f,--force}'[When enabling unit files, override existing symlinks. When shutting down, execute action immediately]' \ '--root=[Enable unit files in the specified root directory]:directory:_directories' \ '--runtime[Enable unit files only temporarily until next reboot]' \ - {-H,--host=}'[Show information for remote host]:userathost:_sd_hosts_or_user_at_host' \ + {-H+,--host=}'[Show information for remote host]:userathost:_sd_hosts_or_user_at_host' \ {-P,--privileged}'[Acquire privileges before execution]' \ - {-n,--lines=}'[Journal entries to show]:number of entries' \ - {-o,--output=}'[Change journal output mode]:modes:_outputmodes' \ + {-n+,--lines=}'[Journal entries to show]:number of entries' \ + {-o+,--output=}'[Change journal output mode]:modes:_outputmodes' \ '--plain[When used with list-dependencies, print output as a list]' \ '*::systemctl command:_systemctl_command' diff --git a/shell-completion/zsh/_systemd b/shell-completion/zsh/_systemd index e954c3e653..06f03bd1e7 100644 --- a/shell-completion/zsh/_systemd +++ b/shell-completion/zsh/_systemd @@ -15,8 +15,8 @@ case "$service" in _arguments \ {-h,--help}'[Show this help]' \ '--version[Show package version.]' \ - {-t,--identifier=}'[Set syslog identifier.]' \ - {-p,--priority=}'[Set priority value.]:value:({0..7})' \ + {-t+,--identifier=}'[Set syslog identifier.]' \ + {-p+,--priority=}'[Set priority value.]:value:({0..7})' \ '--level-prefix=[Control whether level prefix shall be parsed.]:boolean:(1 0)' \ ':Message' ;; @@ -38,8 +38,8 @@ case "$service" in '(-m -p -i -t)-c[Order by CPU load]' \ '(-c -p -i -t)-m[Order by memory load]' \ '(-c -m -p -t)-i[Order by IO load]' \ - {-d,--delay=}'[Specify delay]' \ - {-n,--iterations=}'[Run for N iterations before exiting]' \ + {-d+,--delay=}'[Specify delay]' \ + {-n+,--iterations=}'[Run for N iterations before exiting]' \ {-b,--batch}'[Run in batch mode, accepting no input]' \ '--depth=[Maximum traversal depth]' ;; diff --git a/shell-completion/zsh/_systemd-coredumpctl b/shell-completion/zsh/_systemd-coredumpctl index 1c67500d96..159e8ee0e2 100644 --- a/shell-completion/zsh/_systemd-coredumpctl +++ b/shell-completion/zsh/_systemd-coredumpctl @@ -28,8 +28,8 @@ _systemd-coredumpctl_command(){ } _arguments \ - {-o,--output=}'[Write output to FILE]:output file:_files' \ - {-F,--field=}'[Show field in list output]:field' \ + {-o+,--output=}'[Write output to FILE]:output file:_files' \ + {-F+,--field=}'[Show field in list output]:field' \ '--no-pager[Do not pipe output into a pager]' \ {-h,--help}'[Show this help]' \ '--version[Show package version]' \ diff --git a/shell-completion/zsh/_systemd-delta b/shell-completion/zsh/_systemd-delta index 6abb6fc217..757f1b66fb 100644 --- a/shell-completion/zsh/_systemd-delta +++ b/shell-completion/zsh/_systemd-delta @@ -11,5 +11,5 @@ _arguments \ '--version[Show package version]' \ '--no-pager[Do not pipe output into a pager]' \ '--diff=[Show a diff when overridden files differ]:boolean:(1 0)' \ - {-t,--type=}'[Only display a selected set of override types]:types:_delta_type' \ + {-t+,--type=}'[Only display a selected set of override types]:types:_delta_type' \ ':SUFFIX:(tmpfiles.d sysctl.d systemd/system)' diff --git a/shell-completion/zsh/_systemd-nspawn b/shell-completion/zsh/_systemd-nspawn index a5f345ea2c..a8c2411f2f 100644 --- a/shell-completion/zsh/_systemd-nspawn +++ b/shell-completion/zsh/_systemd-nspawn @@ -12,11 +12,11 @@ _nspawn-caps(){ _arguments \ {-h,--help}'[Show this help]' \ - {--directory=,-D}'[Directory to use as file system root for the namespace container. If omitted the current directory will be used.]:directories:_directories' \ - {--boot,-b}'[Automatically search for an init binary and invoke it instead of a shell or a user supplied program.]' \ - {--user=,-u}'[Run the command under specified user, create home directory and cd into it.]' \ + {--directory=,-D+}'[Directory to use as file system root for the namespace container. If omitted the current directory will be used.]:directories:_directories' \ + {--boot,-b+}'[Automatically search for an init binary and invoke it instead of a shell or a user supplied program.]' \ + {--user=,-u+}'[Run the command under specified user, create home directory and cd into it.]' \ '--uuid=[Set the specified uuid for the container.]' \ - {--controllers=,-C}'[Makes the container appear in other hierarchies than the name=systemd:/ one. Takes a comma-separated list of controllers.]' \ + {--controllers=,-C+}'[Makes the container appear in other hierarchies than the name=systemd:/ one. Takes a comma-separated list of controllers.]' \ '--private-network[Turn off networking in the container. This makes all network interfaces unavailable in the container, with the exception of the loopback device.]' \ '--read-only[Mount the root file system read only for the container.]' \ '--capability=[List one or more additional capabilities to grant the container.]:capabilities:_nspawn-caps' \ diff --git a/shell-completion/zsh/_timedatectl b/shell-completion/zsh/_timedatectl index 9e24b86080..987c2de88d 100644 --- a/shell-completion/zsh/_timedatectl +++ b/shell-completion/zsh/_timedatectl @@ -61,5 +61,5 @@ _arguments -s \ '--adjust-system-clock[Adjust system clock when changing local RTC mode]' \ '--no-pager[Do not pipe output into a pager]' \ '--no-ask-password[Do not prompt for password]' \ - {-H,--host=}'[Operate on remote host]:userathost:_sd_hosts_or_user_at_host' \ + {-H+,--host=}'[Operate on remote host]:userathost:_sd_hosts_or_user_at_host' \ '*::timedatectl commands:_timedatectl_command' -- cgit v1.2.1 From f1a5d37e08f89bf64ac73cec2daf7caec4fc6f1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 23 Aug 2013 13:00:43 -0400 Subject: keyboard: add eMachines E725 Information supplied by Ludvig . --- hwdb/60-keyboard.hwdb | 1 + 1 file changed, 1 insertion(+) diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index 4e7c1a2968..5a361b6240 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -94,6 +94,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*C3[01]0*:pvr* # keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pn* keyboard:dmi:bvn*:bvr*:bd*:svnGateway*:pnA0A1*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svneMachines:pneMachines E725:pvr* KEYBOARD_KEY_a5=help # Fn+F1 KEYBOARD_KEY_a6=setup # Fn+F2 Acer eSettings KEYBOARD_KEY_a7=battery # Fn+F3 Power Management -- cgit v1.2.1 From 0f85cbe105b7c4bde19fc7f12bf79429349182dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 23 Aug 2013 13:13:12 -0400 Subject: man: Small grammar fix Use Oxford comma. --- man/systemctl.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/man/systemctl.xml b/man/systemctl.xml index fc1c7f2cf9..49f22ca0b5 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -111,9 +111,9 @@ along with systemd; If not, see . - The argument should be a comma-separated list of unit LOAD - or SUB or ACTIVE states. When listing units, show only those - with specified LOAD or SUB or ACTIVE state. + The argument should be a comma-separated list of unit LOAD, + SUB, or ACTIVE states. When listing units, show only those + in specified states. -- cgit v1.2.1 From 93a279e34a8d2c38b1c6bcf750548e730f5309d8 Mon Sep 17 00:00:00 2001 From: Herczeg Zsolt Date: Fri, 23 Aug 2013 16:18:36 +0200 Subject: Keyboard map for Samsung NP700Z3C I'm using Ubuntu 13.04 on a Samsung Series 5 computer and found that that Fn hotkeys does not work. --- hwdb/60-keyboard.hwdb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index 5a361b6240..4431edc94d 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -868,6 +868,23 @@ keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*200E[45]*:pvr* KEYBOARD_KEY_ce=! # Fn+F1 launch control setting KEYBOARD_KEY_d5=! # Fn+F12 Wi-Fi toggle +# Series 5 +keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700Z*:pvr* + KEYBOARD_KEY_ce=!prog1 # Fn+F1 launch settings +#KEYBOARD_KEY_89=!brightnessdown # Fn+F2 +#KEYBOARD_KEY_88=!brightnessup # Fn+F3 +#KEYBOARD_KEY_82=!switchvideomode # Fn+F4 video output +#KEYBOARD_KEY_f9=!f23 # Fn+F5 touchpad turn OFF +#KEYBOARD_KEY_f7=!f22 # Fn+F5 touchpad turn ON + KEYBOARD_KEY_a0=!mute # Fn+F6 mute + KEYBOARD_KEY_ae=!volumedown # Fn+F7 + KEYBOARD_KEY_b0=!volumeup # Fn+F8 + KEYBOARD_KEY_97=!kbdillumdown # Fn+F9 keyboard backlight down + KEYBOARD_KEY_96=!kbdillumup # Fn+F10 keyboard backlight up + KEYBOARD_KEY_b3=!prog3 # Fn+F11 fan/cooling mode changer + KEYBOARD_KEY_d5=!wlan # Fn+F12 wlan/airplane switch +# KEYBOARD_KEY_ba=!ejectcd # Fn+DEL eject cd + # Series 9 keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*90X3A*:pvr* keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*900X[34]*:pvr* -- cgit v1.2.1 From 9e15a18acd19bf80faef774ee92877024ef599a5 Mon Sep 17 00:00:00 2001 From: William Giokas <1007380@gmail.com> Date: Sat, 24 Aug 2013 07:23:27 -0500 Subject: zsh_completion: Fix --user-unit completion _SYSTEMD_USER_UNIT in the --user-unit flag argument should instead be USER_UNIT. It should also have an optional `=` between the flag and the argument. --- shell-completion/zsh/_journalctl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell-completion/zsh/_journalctl b/shell-completion/zsh/_journalctl index 7c5cc13bf0..73646b57f5 100644 --- a/shell-completion/zsh/_journalctl +++ b/shell-completion/zsh/_journalctl @@ -13,7 +13,7 @@ _list_fields() { _{P,U,G}ID _COMM _EXE _CMDLINE _AUDIT_{SESSION,LOGINUID} _SYSTEMD_{CGROUP,SESSION,UNIT,OWNER_UID} - _SYSTEMD_USER_UNIT + _SYSTEMD_USER_UNIT USER_UNIT _SELINUX_CONTEXT _SOURCE_REALTIME_TIMESTAMP _{BOOT,MACHINE}_ID _HOSTNAME _TRANSPORT _KERNEL_{DEVICE,SUBSYSTEM} @@ -72,7 +72,7 @@ _arguments -s \ {-b+,--boot=}'[Show data only from the specified boot or offset]:boot id or offset:_journal_boots' \ {-k,--dmesg}'[Show only kernel messages, Implies -b]' \ {-u+,--unit=}'[Show data only from the specified unit]:units:_journal_fields _SYSTEMD_UNIT' \ - '--user-unit[Show data only from the specified user session unit]:units:_journal_fields _SYSTEMD_USER_UNIT' \ + '--user-unit=[Show data only from the specified user session unit]:units:_journal_fields USER_UNIT' \ {-p+,--priority=}'[Show only messages within the specified priority range]:priority:_journal_fields PRIORITY' \ {-c+,--cursor=}'[Start showing entries from specified cursor]:cursors:_journal_fields __CURSORS' \ '--after-cursor=[Start showing entries from the location in the journal after the cursor]:cursors:_journal_fields __CURSORS' \ -- cgit v1.2.1 From 64b2a4da973aa87a92564bcbdfbb34072da54285 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Mon, 26 Aug 2013 16:49:10 +0200 Subject: keymap: Add Samsung NP53U3C https://launchpad.net/bugs/1203853 --- hwdb/60-keyboard.hwdb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index 4431edc94d..09bdadc05c 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -919,6 +919,9 @@ keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700Z*:pvr* keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700T*:pvr* KEYBOARD_KEY_ad=leftmeta +keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn535U*:pvr* + KEYBOARD_KEY_d5=!wlan + ########################################################### # SONY ########################################################### -- cgit v1.2.1 From 792d616391159f4fa992341bf264c9407e480c6d Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Tue, 27 Aug 2013 12:57:01 +0200 Subject: keymap: Add Logitech Internet Navigator variant [PID C309] By Albrecht Kolthoff via linux-hotplug@. --- hwdb/60-keyboard.hwdb | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index 09bdadc05c..13ba5c288e 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -656,6 +656,26 @@ keyboard:usb:v046DpC52Dd*dc*dsc*dp*ic*isc*ip*in00* KEYBOARD_KEY_07003e=presentation KEYBOARD_KEY_070037=displaytoggle +# Internet Navigator +keyboard:usb:v046DpC309* + KEYBOARD_KEY_90001=chat # Messenger/SMS + KEYBOARD_KEY_90002=camera # webcam + KEYBOARD_KEY_90003=prog1 # iTouch + KEYBOARD_KEY_90004=shop # Shopping + KEYBOARD_KEY_C0201=new # New (F1) + KEYBOARD_KEY_C0289=reply # Reply mail (F2) + KEYBOARD_KEY_C028B=forwardmail # Forward mail (F3) + KEYBOARD_KEY_C028C=send # Send (F4) + KEYBOARD_KEY_C021A=undo # Undo (F5). + KEYBOARD_KEY_C0279=redo # Redo (F6). + KEYBOARD_KEY_C0208=print # Print (F7) + KEYBOARD_KEY_C0207=save # Save (F8) + KEYBOARD_KEY_C0194=file # My Computer (F9) + KEYBOARD_KEY_C01A7=documents # My Documents (F10) + KEYBOARD_KEY_C01B6=images # My Pictures (F11) ?? + KEYBOARD_KEY_C01B7=sound # My Music (F12) ?? + + ########################################################### # Maxdata ########################################################### -- cgit v1.2.1 From bd6d2963396061ed068c4c6c54d8104b59ba91dc Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 27 Aug 2013 18:25:06 +0200 Subject: log to kmsg when "debug" is used on the kernel command line --- src/core/main.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index 8a73ad3cc7..0178f10720 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -401,9 +401,14 @@ static int parse_proc_cmdline_word(const char *word) { } else if (streq(word, "quiet")) arg_show_status = false; - else if (streq(word, "debug")) + else if (streq(word, "debug")) { + /* Log to kmsg, the journal socket will fill up before the + * journal is started and tools running during that time + * will block with every log message for for 60 seconds, + * before they give up. */ log_set_max_level(LOG_DEBUG); - else if (!in_initrd()) { + log_set_target(LOG_TARGET_KMSG); + } else if (!in_initrd()) { unsigned i; /* SysV compatibility */ -- cgit v1.2.1 From fe05567c31cb88593a09ce5d8961d8b20627feb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 22 Aug 2013 23:25:28 -0400 Subject: shell-completions: systemd-analyze set-log-level --- shell-completion/bash/systemd-analyze | 9 +++++++++ shell-completion/zsh/_systemd-analyze | 19 ++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/shell-completion/bash/systemd-analyze b/shell-completion/bash/systemd-analyze index 33833aac10..5bd676866b 100644 --- a/shell-completion/bash/systemd-analyze +++ b/shell-completion/bash/systemd-analyze @@ -34,6 +34,7 @@ _systemd_analyze() { [NO_OPTION]='time blame plot' [CRITICAL_CHAIN]='critical-chain' [DOT]='dot' + [LOG_LEVEL]='set-log-level' ) _init_completion || return @@ -68,6 +69,14 @@ _systemd_analyze() { if [[ $cur = -* ]]; then comps='--help --version --system --user --from-pattern --to-pattern --order --require' fi + + elif __contains_word "$verb" ${VERBS[LOG_LEVEL]}; then + if [[ $cur = -* ]]; then + comps='--help --version --system --user' + else + comps='debug info notice warning err crit alert emerg' + fi + fi COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) diff --git a/shell-completion/zsh/_systemd-analyze b/shell-completion/zsh/_systemd-analyze index 13e96c0586..37c60f5b40 100644 --- a/shell-completion/zsh/_systemd-analyze +++ b/shell-completion/zsh/_systemd-analyze @@ -1,5 +1,11 @@ #compdef systemd-analyze +_systemd_analyze_set-log-level() { + local -a _levels + _levels=(debug info notice warning err crit alert emerg) + _describe -t level 'logging level' _levels || compadd "$@" +} + _systemd_analyze_command(){ local -a _systemd_analyze_cmds # Descriptions taken from systemd-analyze --help. @@ -9,12 +15,23 @@ _systemd_analyze_command(){ 'critical-chain:Print a tree of the time critical chain of units' 'plot:Output SVG graphic showing service initialization' 'dot:Dump dependency graph (in dot(1) format)' + 'set-log-level:Set systemd log threshold' ) if (( CURRENT == 1 )); then _describe "options" _systemd_analyze_cmds else - _message "no more options" + local curcontext="$curcontext" + cmd="${${_systemd_analyze_cmds[(r)$words[1]:*]%%:*}}" + if (( $#cmd )); then + if (( $+functions[_systemd_analyze_$cmd] )) && (( CURRENT == 2 )); then + _systemd_analyze_$cmd + else + _message "no more options" + fi + else + _message "unknown systemd-analyze command: $words[1]" + fi fi } -- cgit v1.2.1 From 335c46b59888d431e5a57cddcf7ceecd09ec8e4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 24 Aug 2013 10:51:55 -0400 Subject: Disallow invalid UTF-8 configuration It is best to catch such errors early. If invalid UTF-8 ends up being given to dbus methods, the program will crash: process 20801: arguments to dbus_message_iter_append_basic() were incorrect, assertion "_dbus_check_is_valid_utf8 (*string_p)" failed in file dbus-message.c line 2598. --- src/shared/fileio.c | 88 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 57 insertions(+), 31 deletions(-) diff --git a/src/shared/fileio.c b/src/shared/fileio.c index 2b1dab8053..77fd05955a 100644 --- a/src/shared/fileio.c +++ b/src/shared/fileio.c @@ -23,6 +23,7 @@ #include "fileio.h" #include "util.h" #include "strv.h" +#include "utf8.h" int write_string_to_file(FILE *f, const char *line) { errno = 0; @@ -177,13 +178,15 @@ int read_full_file(const char *fn, char **contents, size_t *size) { static int parse_env_file_internal( const char *fname, const char *newline, - int (*push) (const char *key, char *value, void *userdata), + int (*push) (const char *filename, unsigned line, + const char *key, char *value, void *userdata), void *userdata) { _cleanup_free_ char *contents = NULL, *key = NULL; size_t key_alloc = 0, n_key = 0, value_alloc = 0, n_value = 0, last_value_whitespace = (size_t) -1, last_key_whitespace = (size_t) -1; char *p, *value = NULL; int r; + unsigned line = 1; enum { PRE_KEY, @@ -230,6 +233,7 @@ static int parse_env_file_internal( case KEY: if (strchr(newline, c)) { state = PRE_KEY; + line ++; n_key = 0; } else if (c == '=') { state = PRE_VALUE; @@ -253,6 +257,7 @@ static int parse_env_file_internal( case PRE_VALUE: if (strchr(newline, c)) { state = PRE_KEY; + line ++; key[n_key] = 0; if (value) @@ -262,7 +267,7 @@ static int parse_env_file_internal( if (last_key_whitespace != (size_t) -1) key[last_key_whitespace] = 0; - r = push(key, value, userdata); + r = push(fname, line, key, value, userdata); if (r < 0) goto fail; @@ -292,6 +297,7 @@ static int parse_env_file_internal( case VALUE: if (strchr(newline, c)) { state = PRE_KEY; + line ++; key[n_key] = 0; @@ -306,7 +312,7 @@ static int parse_env_file_internal( if (last_key_whitespace != (size_t) -1) key[last_key_whitespace] = 0; - r = push(key, value, userdata); + r = push(fname, line, key, value, userdata); if (r < 0) goto fail; @@ -408,8 +414,10 @@ static int parse_env_file_internal( case COMMENT: if (c == '\\') state = COMMENT_ESCAPE; - else if (strchr(newline, c)) + else if (strchr(newline, c)) { state = PRE_KEY; + line ++; + } break; case COMMENT_ESCAPE: @@ -439,7 +447,7 @@ static int parse_env_file_internal( if (last_key_whitespace != (size_t) -1) key[last_key_whitespace] = 0; - r = push(key, value, userdata); + r = push(fname, line, key, value, userdata); if (r < 0) goto fail; } @@ -451,27 +459,36 @@ fail: return r; } -static int parse_env_file_push(const char *key, char *value, void *userdata) { - const char *k; - va_list* ap = (va_list*) userdata; - va_list aq; +static int parse_env_file_push(const char *filename, unsigned line, + const char *key, char *value, void *userdata) { + assert(utf8_is_valid(key)); + + if (value && !utf8_is_valid(value)) + /* FIXME: filter UTF-8 */ + log_error("%s:%u: invalid UTF-8 for key %s: '%s', ignoring.", + filename, line, key, value); + else { + const char *k; + va_list* ap = (va_list*) userdata; + va_list aq; - va_copy(aq, *ap); + va_copy(aq, *ap); - while ((k = va_arg(aq, const char *))) { - char **v; + while ((k = va_arg(aq, const char *))) { + char **v; - v = va_arg(aq, char **); + v = va_arg(aq, char **); - if (streq(key, k)) { - va_end(aq); - free(*v); - *v = value; - return 1; + if (streq(key, k)) { + va_end(aq); + free(*v); + *v = value; + return 1; + } } - } - va_end(aq); + va_end(aq); + } free(value); return 0; @@ -494,19 +511,28 @@ int parse_env_file( return r; } -static int load_env_file_push(const char *key, char *value, void *userdata) { - char ***m = userdata; - char *p; - int r; +static int load_env_file_push(const char *filename, unsigned line, + const char *key, char *value, void *userdata) { + assert(utf8_is_valid(key)); - p = strjoin(key, "=", strempty(value), NULL); - if (!p) - return -ENOMEM; + if (value && !utf8_is_valid(value)) + /* FIXME: filter UTF-8 */ + log_error("%s:%u: invalid UTF-8 for key %s: '%s', ignoring.", + filename, line, key, value); + else { + char ***m = userdata; + char *p; + int r; - r = strv_push(m, p); - if (r < 0) { - free(p); - return r; + p = strjoin(key, "=", strempty(value), NULL); + if (!p) + return -ENOMEM; + + r = strv_push(m, p); + if (r < 0) { + free(p); + return r; + } } free(value); -- cgit v1.2.1 From 042f598892e2587d735e4de1f4aabcb3d89d05f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 24 Aug 2013 10:52:23 -0400 Subject: logind: be more verbose on errors --- src/login/logind-session.c | 3 ++- src/login/logind.c | 29 +++++++++++++++++++++++------ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 1fea4745b6..dac50e8334 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -480,7 +480,8 @@ static int session_start_scope(Session *s) { r = manager_start_scope(s->manager, scope, s->leader, s->user->slice, description, "systemd-user-sessions.service", kill_mode, &error, &job); if (r < 0) { - log_error("Failed to start session scope: %s %s", bus_error(&error, r), error.name); + log_error("Failed to start session scope %s: %s %s", + scope, bus_error(&error, r), error.name); dbus_error_free(&error); free(scope); diff --git a/src/login/logind.c b/src/login/logind.c index 0002d262c1..9094567b8d 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -1423,12 +1423,29 @@ int manager_startup(Manager *m) { return r; /* Deserialize state */ - manager_enumerate_devices(m); - manager_enumerate_seats(m); - manager_enumerate_users(m); - manager_enumerate_sessions(m); - manager_enumerate_inhibitors(m); - manager_enumerate_buttons(m); + r = manager_enumerate_devices(m); + if (r < 0) + log_warning("Device enumeration failed: %s", strerror(-r)); + + r = manager_enumerate_seats(m); + if (r < 0) + log_warning("Seat enumeration failed: %s", strerror(-r)); + + r = manager_enumerate_users(m); + if (r < 0) + log_warning("User enumeration failed: %s", strerror(-r)); + + r = manager_enumerate_sessions(m); + if (r < 0) + log_warning("Session enumeration failed: %s", strerror(-r)); + + r = manager_enumerate_inhibitors(m); + if (r < 0) + log_warning("Inhibitor enumeration failed: %s", strerror(-r)); + + r = manager_enumerate_buttons(m); + if (r < 0) + log_warning("Button enumeration failed: %s", strerror(-r)); /* Remove stale objects before we start them */ manager_gc(m, false); -- cgit v1.2.1 From 5af726cced7f87d6f7b7d6bd1dd5ee44ded5aa7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 24 Aug 2013 23:48:34 -0400 Subject: logind-session.c: use _cleanup_ --- src/login/logind-session.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/login/logind-session.c b/src/login/logind-session.c index dac50e8334..a726fb1bed 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -381,7 +381,8 @@ int session_activate(Session *s) { } static int session_link_x11_socket(Session *s) { - char *t, *f, *c; + _cleanup_free_ char *t = NULL, *f = NULL; + char *c; size_t k; assert(s); @@ -405,7 +406,6 @@ static int session_link_x11_socket(Session *s) { if (access(f, F_OK) < 0) { log_warning("Session %s has display %s with non-existing socket %s.", s->id, s->display, f); - free(f); return -ENOENT; } @@ -414,10 +414,8 @@ static int session_link_x11_socket(Session *s) { * path is owned by the user */ t = strappend(s->user->runtime_path, "/X11-display"); - if (!t) { - free(f); + if (!t) return log_oom(); - } if (link(f, t) < 0) { if (errno == EEXIST) { @@ -437,17 +435,12 @@ static int session_link_x11_socket(Session *s) { } log_error("Failed to link %s to %s: %m", f, t); - free(f); - free(t); return -errno; } } done: log_info("Linked %s to %s.", f, t); - free(f); - free(t); - s->user->display = s; return 0; @@ -585,7 +578,7 @@ static int session_stop_scope(Session *s) { } static int session_unlink_x11_socket(Session *s) { - char *t; + _cleanup_free_ char *t = NULL; int r; assert(s); @@ -601,8 +594,6 @@ static int session_unlink_x11_socket(Session *s) { return log_oom(); r = unlink(t); - free(t); - return r < 0 ? -errno : 0; } -- cgit v1.2.1 From e862b60f1c77bc12bf49475930f79ce68489828a Mon Sep 17 00:00:00 2001 From: Gao feng Date: Wed, 28 Aug 2013 12:10:16 +0800 Subject: blcokio bandwidth: add missing set of CGroupBlockIODeviceBandwidth's read BlockIOReadBandwidth and BlockIOWriteBandwidth both use config_parse_blockio_bandwidth to set up CGroupBlockIODeviceBandwidth, We should set the read value based on the left values in config files. --- src/core/load-fragment.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index e5fc4a3bd9..4714687955 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -2253,6 +2253,7 @@ int config_parse_blockio_bandwidth( b->path = path; path = NULL; b->bandwidth = (uint64_t) bytes; + b->read = streq("BlockIOReadBandwidth", lvalue); LIST_PREPEND(CGroupBlockIODeviceBandwidth, device_bandwidths, c->blockio_device_bandwidths, b); -- cgit v1.2.1 From ad7bfffde594bf141e13f17e8d8214bfa29ea635 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Wed, 28 Aug 2013 09:49:11 +0800 Subject: device cgroup: don't create a new CGroupDeviceAllow when it already in the list If a device node is already in the device_allow list of CGroupContext, we should replace it instead of create a new one and append this new one to the end of device_allow list. change from v1: use streq to replace !strcmp --- src/core/dbus-cgroup.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c index 9e97b20d1e..4ce7dc5e7f 100644 --- a/src/core/dbus-cgroup.c +++ b/src/core/dbus-cgroup.c @@ -314,21 +314,35 @@ int bus_cgroup_set_property( } if (mode != UNIT_CHECK) { - a = new0(CGroupDeviceAllow, 1); - if (!a) - return -ENOMEM; - - a->path = strdup(path); - if (!a->path) { - free(a); - return -ENOMEM; + CGroupDeviceAllow *b; + bool exist = false; + + LIST_FOREACH(device_allow, b, c->device_allow) { + if (streq(b->path, path)) { + a = b; + exist = true; + break; + } + } + + if (!exist) { + a = new0(CGroupDeviceAllow, 1); + if (!a) + return -ENOMEM; + + a->path = strdup(path); + if (!a->path) { + free(a); + return -ENOMEM; + } } a->r = !!strchr(rwm, 'r'); a->w = !!strchr(rwm, 'w'); a->m = !!strchr(rwm, 'm'); - LIST_PREPEND(CGroupDeviceAllow, device_allow, c->device_allow, a); + if (!exist) + LIST_PREPEND(CGroupDeviceAllow, device_allow, c->device_allow, a); } n++; -- cgit v1.2.1 From a255a7f1442590b95a54227636ed0e66398fb4ff Mon Sep 17 00:00:00 2001 From: Gao feng Date: Mon, 26 Aug 2013 10:36:45 +0800 Subject: cgroup: only check once when mode is UNIT_CHECK If the mode is UNIT_CHECK,it means we only want to check if the paramaters are valid. the first round of cycle already did this check, no need to check again. --- src/core/dbus-unit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index 4cd3a13fd2..2ea59b2913 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -981,7 +981,7 @@ int bus_unit_set_properties( if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_INVALID) { - if (for_real) + if (for_real || mode == UNIT_CHECK) break; /* Reached EOF. Let's try again, and this time for realz... */ -- cgit v1.2.1 From 3d040cf24473f2ed13121d57ed753bad5f8ad09d Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Wed, 28 Aug 2013 16:02:39 +0200 Subject: Revert "cgroup.c: check return value of unit_realize_cgroup_now()" This reverts commit 1f11a0cdfe397cc404d61ee679fc12f58c0a885b. --- src/core/cgroup.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 50b17f3802..5a1c3adacd 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -432,13 +432,8 @@ static int unit_realize_cgroup_now(Unit *u) { return 0; /* First, realize parents */ - if (UNIT_ISSET(u->slice)) { - int r; - - r = unit_realize_cgroup_now(UNIT_DEREF(u->slice)); - if (r < 0) - return r; - } + if (UNIT_ISSET(u->slice)) + unit_realize_cgroup_now(UNIT_DEREF(u->slice)); /* And then do the real work */ return unit_create_cgroups(u, mask); -- cgit v1.2.1 From b58b8e11c5f769e3c80d5169fdcc4bd04b882b7d Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Wed, 28 Aug 2013 15:33:35 +0200 Subject: Do not realloc strings, which are already in the hashmap as keys This prevents corruption of the hashmap, because we would free() the keys in the hashmap, if the unit is already in there, with the same cgroup path. --- src/core/cgroup.c | 18 ++++++++++++++---- src/core/unit.c | 2 +- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 5a1c3adacd..3eeb475754 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -382,6 +382,7 @@ static CGroupControllerMask unit_get_siblings_mask(Unit *u) { static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) { char *path = NULL; int r; + bool is_in_hash = false; assert(u); @@ -390,8 +391,14 @@ static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) { return -ENOMEM; r = hashmap_put(u->manager->cgroup_unit, path, u); - if (r < 0) + if (r == 0) + is_in_hash = true; + + if (r < 0) { + free(path); + log_error("cgroup %s exists already: %s", path, strerror(-r)); return r; + } /* First, create our own group */ r = cg_create_with_mask(mask, path); @@ -405,9 +412,12 @@ static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) { log_error("Failed to migrate cgroup %s: %s", path, strerror(-r)); } - /* And remember the new data */ - free(u->cgroup_path); - u->cgroup_path = path; + if (!is_in_hash) { + /* And remember the new data */ + free(u->cgroup_path); + u->cgroup_path = path; + } + u->cgroup_realized = true; u->cgroup_mask = mask; diff --git a/src/core/unit.c b/src/core/unit.c index 27119b0cd7..ab313b9b91 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -2329,7 +2329,7 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) { free(u->cgroup_path); u->cgroup_path = s; - hashmap_put(u->manager->cgroup_unit, s, u); + assert(hashmap_put(u->manager->cgroup_unit, s, u) == 1); continue; } -- cgit v1.2.1 From 3f42b51f21171a3166200af3d9966812f1ddd0f0 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Thu, 29 Aug 2013 17:48:42 +0200 Subject: keymap: Don't erase previous assignments Don't use "KEYBOARD_KEY_xx=!" assignments (i. e. only enabling force-release) if more general matches already explicitly set a key code before, to not override the previously set value. https://launchpad.net/bugs/1218433 --- hwdb/60-keyboard.hwdb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index 13ba5c288e..33dc5d6a35 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -245,11 +245,11 @@ keyboard:dmi:bvn*:bvr*:bd*:svnDell Inc.:pnStudio 155[78]:pvr* # Dell Touchpad keyboard:dmi:bvn*:bvr*:bd*:svnDell Inc.:pn:*Latitude*:pvr* keyboard:dmi:bvn*:bvr*:bd*:svnDell Inc.:pn:*Precision*:pvr* - KEYBOARD_KEY_9e=! + KEYBOARD_KEY_9e=!f21 # Dell XPS keyboard:dmi:bvn*:bvr*:bd*:svnDell Inc.:pnXPS*:pvr* - KEYBOARD_KEY_8c=! + KEYBOARD_KEY_8c=!f23 ########################################################### # Everex -- cgit v1.2.1 From db7c6e6fc85d13ab18eb0d918957210c7476cba6 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Fri, 30 Aug 2013 06:31:12 +0200 Subject: keymap: Fix Dell vendor names Spaces are dropped from vendor and product names in DMI modaliases, so a match like "svnDell Inc.:" will never happen. Also, some machines use "Dell", some "Dell Inc", some "Dell Inc.", so just match on "Dell*" to avoid all these traps. https://launchpad.net/bugs/1218433 --- hwdb/60-keyboard.hwdb | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index 33dc5d6a35..958185f4f2 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -192,7 +192,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnCompaq*:pn*Evo N*:pvr* # Dell ########################################################### -keyboard:dmi:bvn*:bvr*:bd*:svnDell:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pvr* KEYBOARD_KEY_81=playpause # Play/Pause KEYBOARD_KEY_82=stopcd # Stop KEYBOARD_KEY_83=previoussong # Previous song @@ -224,31 +224,31 @@ keyboard:dmi:bvn*:bvr*:bd*:svnDell:pvr* KEYBOARD_KEY_d9=f21 # Touchpad toggle # -keyboard:dmi:bvn*:bvr*:bd*:svnDell:pnInspiron 910:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnDell:pnInspiron 101[012]:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnDell:pnInspiron 1110:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnDell:pnInspiron 1210:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnInspiron 910:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnInspiron 101[012]:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnInspiron 1110:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnInspiron 1210:pvr* KEYBOARD_KEY_84=wlan # Latitude XT2 -keyboard:dmi:bvn*:bvr*:bd*:svnDell:pnLatitude XT2:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude XT2:pvr* KEYBOARD_KEY_9b=up # tablet rocker up KEYBOARD_KEY_9e=enter # tablet rocker press KEYBOARD_KEY_9f=back # tablet back KEYBOARD_KEY_a3=down # tablet rocker down -keyboard:dmi:bvn*:bvr*:bd*:svnDell Inc.:pnStudio 155[78]:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnStudio 155[78]:pvr* KEYBOARD_KEY_a0=! # mute KEYBOARD_KEY_ae=! # volume down KEYBOARD_KEY_b0=! # volume up # Dell Touchpad -keyboard:dmi:bvn*:bvr*:bd*:svnDell Inc.:pn:*Latitude*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnDell Inc.:pn:*Precision*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pn:*Latitude*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pn:*Precision*:pvr* KEYBOARD_KEY_9e=!f21 # Dell XPS -keyboard:dmi:bvn*:bvr*:bd*:svnDell Inc.:pnXPS*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnXPS*:pvr* KEYBOARD_KEY_8c=!f23 ########################################################### -- cgit v1.2.1 From b534166eaec8fef9902a68f75cab8eeae458b23c Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Fri, 30 Aug 2013 06:43:26 +0200 Subject: keymap: Don't use spaces in DMI modalias matches Spaces get dropped from DMI modaliases. Replace them with '*' to make them robust against future changes in space escaping. --- hwdb/60-keyboard.hwdb | 100 +++++++++++++++++++++++++------------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index 958185f4f2..288d0c8abd 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -51,7 +51,7 @@ keyboard:name:Acer WMI hotkeys:dmi:bvn*:bvr*:bd*:svn*:pnAcer*:pvr* KEYBOARD_KEY_82=f21 # Aspire 5720 -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire 5720*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire*5720*:pvr* keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnZG8*:pvr* KEYBOARD_KEY_84=bluetooth # sent when bluetooth module missing, and key pressed KEYBOARD_KEY_92=media # Acer arcade @@ -60,7 +60,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnZG8*:pvr* KEYBOARD_KEY_f4=prog3 # e-key # Aspire 5920g -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire 5920G:* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire*5920G:* KEYBOARD_KEY_8a=media KEYBOARD_KEY_92=media KEYBOARD_KEY_a6=setup @@ -68,7 +68,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire 5920G:* KEYBOARD_KEY_d9=bluetooth # (toggle) on-to-off # Aspire 6920 -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire 6920:* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire*6920:* KEYBOARD_KEY_d9=bluetooth # (toggle) on-to-off KEYBOARD_KEY_92=media KEYBOARD_KEY_9e=back @@ -76,7 +76,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire 6920:* KEYBOARD_KEY_89=fastforward # Aspire 8930 -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire 8930:* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire*8930:* KEYBOARD_KEY_ca=prog3 # key 'HOLD' on CineDash Media Console KEYBOARD_KEY_83=rewind KEYBOARD_KEY_89=fastforward @@ -94,7 +94,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*C3[01]0*:pvr* # keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pn* keyboard:dmi:bvn*:bvr*:bd*:svnGateway*:pnA0A1*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svneMachines:pneMachines E725:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svneMachines:pneMachines*E725:pvr* KEYBOARD_KEY_a5=help # Fn+F1 KEYBOARD_KEY_a6=setup # Fn+F2 Acer eSettings KEYBOARD_KEY_a7=battery # Fn+F3 Power Management @@ -131,7 +131,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*6292*:pvr* keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*8471*:pvr* keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*4720*:pvr* keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*7720*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire 1810T*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire*1810T*:pvr* keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAO751h:* keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAO531h:* KEYBOARD_KEY_d9=bluetooth @@ -142,8 +142,8 @@ keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*4720*:pvr* KEYBOARD_KEY_ee=screenlock # -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate 6593:* -keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire 1640:* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*6593:* +keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire*1640:* KEYBOARD_KEY_b2=www KEYBOARD_KEY_ee=screenlock @@ -167,7 +167,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnASUS:* # BenQ ########################################################### -keyboard:dmi:bvn*:bvr*:bd*:svn*BenQ*:pn*Joybook R22*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svn*BenQ*:pn*Joybook*R22*:pvr* KEYBOARD_KEY_6e=wlan ########################################################### @@ -182,7 +182,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnCOMPAL:pnHEL80I:* ########################################################### keyboard:dmi:bvn*:bvr*:bd*:svnCompaq*:pn*E500*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnCompaq*:pn*Evo N*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnCompaq*:pn*Evo*N*:pvr* KEYBOARD_KEY_a3=www # I key KEYBOARD_KEY_9a=search KEYBOARD_KEY_9e=email @@ -224,20 +224,20 @@ keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pvr* KEYBOARD_KEY_d9=f21 # Touchpad toggle # -keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnInspiron 910:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnInspiron 101[012]:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnInspiron 1110:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnInspiron 1210:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnInspiron*910:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnInspiron*101[012]:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnInspiron*1110:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnInspiron*1210:pvr* KEYBOARD_KEY_84=wlan # Latitude XT2 -keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude XT2:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude*XT2:pvr* KEYBOARD_KEY_9b=up # tablet rocker up KEYBOARD_KEY_9e=enter # tablet rocker press KEYBOARD_KEY_9f=back # tablet back KEYBOARD_KEY_a3=down # tablet rocker down -keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnStudio 155[78]:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnStudio*155[78]:pvr* KEYBOARD_KEY_a0=! # mute KEYBOARD_KEY_ae=! # volume down KEYBOARD_KEY_b0=! # volume up @@ -272,35 +272,35 @@ keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pnAMILO*M*:pvr* KEYBOARD_KEY_97=prog2 KEYBOARD_KEY_9f=prog1 -keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pnAmilo Li 1718:* +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pnAmilo*Li*1718:* KEYBOARD_KEY_d6=wlan # Amilo Li 2732 -keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pnAMILO Li 2732:* +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pnAMILO*Li*2732:* KEYBOARD_KEY_d9=brightnessdown # Fn+F8 brightness down KEYBOARD_KEY_ef=brightnessup # Fn+F9 brightness up KEYBOARD_KEY_a9=switchvideomode # Fn+F10 Cycle between available video outputs # Amilo Pa 2548 -keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*AMILO Pa 2548*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*AMILO*Pa*2548*:pvr* KEYBOARD_KEY_e0=volumedown KEYBOARD_KEY_e1=volumeup KEYBOARD_KEY_e5=prog1 # Amilo Pro Edition V3505 -keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*AMILO Pro Edition V3505*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*AMILO*Pro*Edition*V3505*:pvr* KEYBOARD_KEY_a5=help # Fn+F1 KEYBOARD_KEY_a9=switchvideomode # Fn+F3 KEYBOARD_KEY_d9=brightnessdown # Fn+F8 KEYBOARD_KEY_e0=brightnessup # Fn+F9 # Amilo Pro v3205 -keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*AMILO Pro V3205*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*AMILO*Pro*V3205*:pvr* KEYBOARD_KEY_f4=f21 # FIXME: silent-mode decrease CPU/GPU clock KEYBOARD_KEY_f7=switchvideomode # Fn+F3 # Amilo Si 1520 -keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*Amilo Si 1520*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*Amilo*Si*1520*:pvr* KEYBOARD_KEY_e1=wlan KEYBOARD_KEY_f3=wlan KEYBOARD_KEY_ee=brightnessdown @@ -309,14 +309,14 @@ keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*Amilo Si 1520*:pvr* KEYBOARD_KEY_f7=video # Esprimo Mobile V5 -keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*ESPRIMO Mobile V5*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*ESPRIMO*Mobile*V5*:pvr* KEYBOARD_KEY_a9=switchvideomode KEYBOARD_KEY_d9=brightnessdown KEYBOARD_KEY_df=sleep KEYBOARD_KEY_ef=brightnessup # Esprimo Mobile V6 -keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*ESPRIMO Mobile V6*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*ESPRIMO*Mobile*V6*:pvr* KEYBOARD_KEY_ce=brightnessup KEYBOARD_KEY_ef=brightnessdown @@ -382,7 +382,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[pP][aA][vV][iI][lL][iI][oO][n KEYBOARD_KEY_d8=!f23 # touchpad off KEYBOARD_KEY_d9=!f22 # touchpad on -keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP Pavilion dv7 Notebook PC:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*Pavilion*dv7*Notebook*PC:pvr* KEYBOARD_KEY_b7=print KEYBOARD_KEY_c2=media # FIXME: quick play KEYBOARD_KEY_c6=break @@ -403,7 +403,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*Presario*CQ*:pvr* # 2510p 2530p keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*2510p*:pvr* keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*2530p*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP G60 Notebook PC:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*G60*Notebook*PC:pvr* KEYBOARD_KEY_d8=!f23 # touchpad off KEYBOARD_KEY_d9=!f22 # touchpad on @@ -418,13 +418,13 @@ keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[tT][xX]2*:pvr* KEYBOARD_KEY_d9=!f22 # Toggle touchpad button on tx2 (ON) # Presario 2100 -keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnPresario 2100*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnPresario*2100*:pvr* KEYBOARD_KEY_f0=help KEYBOARD_KEY_f1=screenlock KEYBOARD_KEY_f3=search # Elitebook 8440p -keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP EliteBook 8440p:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*EliteBook*8440p:pvr* KEYBOARD_KEY_88=www KEYBOARD_KEY_a0=mute KEYBOARD_KEY_ae=volumedown @@ -432,7 +432,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP EliteBook 8440p:pvr* KEYBOARD_KEY_ec=mail # Elitebook 8460p -keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP EliteBook 8460p:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*EliteBook*8460p:pvr* KEYBOARD_KEY_f8=wlan # Wireless HW switch button KEYBOARD_KEY_b3=prog1 # Fn+F11 - Ambient Light Sensor button KEYBOARD_KEY_b1=prog2 # Fn+ESC - System information button @@ -481,7 +481,7 @@ keyboard:usb:v04B3p301[89]* ########################################################### # Symphony -keyboard:dmi:bvn*:bvr*:bd*:svnINVENTEC:pnSYMPHONY 6.0/7.0:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnINVENTEC:pnSYMPHONY*6.0/7.0:pvr* KEYBOARD_KEY_f3=prog2 KEYBOARD_KEY_f4=prog1 @@ -549,7 +549,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pnS10-*:pvr* KEYBOARD_KEY_f3=f21 # Thinkpad X200_Tablet -keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pnThinkPad X2* Tablet*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pnThinkPad*X2*Tablet*:pvr* KEYBOARD_KEY_5d=menu KEYBOARD_KEY_63=fn KEYBOARD_KEY_66=screenlock @@ -558,7 +558,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pnThinkPad X2* Tablet*:pvr* KEYBOARD_KEY_6c=direction # rotate screen # ThinkPad X6 Tablet -keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pnThinkPad X6*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pnThinkPad*X6*:pvr* KEYBOARD_KEY_6c=f21 # rotate KEYBOARD_KEY_68=screenlock # screenlock KEYBOARD_KEY_6b=esc # escape @@ -569,16 +569,16 @@ keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pnThinkPad X6*:pvr* KEYBOARD_KEY_69=enter # enter on d-pad # IdeaPad -keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad Y550*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad*Y550*:pvr* KEYBOARD_KEY_95=media KEYBOARD_KEY_a3=play # V480 -keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*Lenovo V480*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*Lenovo*V480*:pvr* KEYBOARD_KEY_f1=f21 # IdeaPad -keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad U300s*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad*U300s*:pvr* KEYBOARD_KEY_f1=f21 KEYBOARD_KEY_ce=f20 @@ -681,7 +681,7 @@ keyboard:usb:v046DpC309* ########################################################### # Pro 7000 -keyboard:dmi:bvn*:bvr*:bd*:svnMAXDATA:pnPro 7000*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnMAXDATA:pnPro*7000*:pvr* KEYBOARD_KEY_97=prog2 KEYBOARD_KEY_9f=prog1 KEYBOARD_KEY_a0=mute # Fn+F5 @@ -827,7 +827,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnOLPC:pnXO:* # Onkyo ########################################################### -keyboard:dmi:bvn*:bvr*:bd*:svnONKYO CORPORATION:pnONKYOPC:* +keyboard:dmi:bvn*:bvr*:bd*:svnONKYO*CORPORATION:pnONKYOPC:* KEYBOARD_KEY_a0=mute # Fn+D KEYBOARD_KEY_ae=volumedown # Fn+F KEYBOARD_KEY_b0=volumeup # Fn+G @@ -848,7 +848,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnONKYO CORPORATION:pnONKYOPC:* ########################################################### # Model 2 -keyboard:dmi:bvn*:bvr*:bd*:svnOQO Inc.*:pnOQO Model 2*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnOQO*Inc.*:pnOQO*Model*2*:pvr* KEYBOARD_KEY_8e=wlan KEYBOARD_KEY_f0=switchvideomode KEYBOARD_KEY_f1=mute @@ -992,12 +992,12 @@ keyboard:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVPC*:pvr* ########################################################### # Satellite A100 -keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSATELLITE A100:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSATELLITE*A100:pvr* KEYBOARD_KEY_a4=stopcd KEYBOARD_KEY_b2=www # Satellite A110 -keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite A110:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite*A110:pvr* KEYBOARD_KEY_92=stop KEYBOARD_KEY_93=www KEYBOARD_KEY_94=media @@ -1010,7 +1010,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite A110:pvr* KEYBOARD_KEY_f7=playpause # Satellite M30X -keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite M30X:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite*M30X:pvr* KEYBOARD_KEY_ef=brightnessdown KEYBOARD_KEY_d9=brightnessup KEYBOARD_KEY_ee=screenlock @@ -1047,7 +1047,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnZepto:pnZnote:* KEYBOARD_KEY_b0=! # volume up # Znote 6615WD -keyboard:dmi:bvn*:bvr*:bd*:svnZepto:pnZnote 6615WD:* +keyboard:dmi:bvn*:bvr*:bd*:svnZepto:pnZnote*6615WD:* KEYBOARD_KEY_a0=! # mute KEYBOARD_KEY_ae=! # volume down KEYBOARD_KEY_b0=! # volume up @@ -1057,19 +1057,19 @@ keyboard:dmi:bvn*:bvr*:bd*:svnZepto:pnZnote 6615WD:* ########################################################### # Common Volume Keys -keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU SIEMENS:pnAMILO*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnFUJITSU*SIEMENS:pnAMILO*:pvr* keyboard:dmi:bvn*:bvr*:bd*:svnFOXCONN:pnQBOOK:* keyboard:dmi:bvn*:bvr*:bd*:svnMTC:pn*:pvrA0:* -keyboard:dmi:bvn*:bvr*:bd*:svnMio Technology:pnN890:* -keyboard:dmi:bvn*:bvr*:bd*:svnPEGATRON CORP.:pnSpring Peak:* -keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA:pnSatellite [uU]30[05]*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA:pnSatellite Pro [uU]300*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA:pnSATELLITE [uU]500*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnViooo Corporation:pnPT17:* +keyboard:dmi:bvn*:bvr*:bd*:svnMio*Technology:pnN890:* +keyboard:dmi:bvn*:bvr*:bd*:svnPEGATRON*CORP.:pnSpring*Peak:* +keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA:pnSatellite*[uU]30[05]*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA:pnSatellite*Pro*[uU]300*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA:pnSATELLITE*[uU]500*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnViooo*Corporation:pnPT17:* keyboard:dmi:bvn*:bvr*:bd*:svnHANNspree:pnSN10E100:* keyboard:dmi:bvn*:bvr*:bd*:svnGIGABYTE:pni1520M:* keyboard:dmi:bvn*:bvr*:bd*:svnBenQ:pn*nScreen*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnBenQ:pnJoybook Lite*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnBenQ:pnJoybook*Lite*:pvr* keyboard:dmi:bvn*:bvr*:bd*:svnDIXONSP:pnDIXON*:pvr* KEYBOARD_KEY_a0=! # mute KEYBOARD_KEY_ae=! # volume down -- cgit v1.2.1 From 31c885e9ae53f4b88a36452c4ca10643fdd0fd06 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Fri, 30 Aug 2013 10:23:50 +0200 Subject: main: drop capabilities of userhelpers before ours First drop the capabilities of the userhelpers before dropping our own, otherwise we might not be allowed to drop the capabilities of the userhelpers. Especially, if we want to drop CAP_SYS_MODULE. Credits: Matteo Sasso --- src/core/main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index 0178f10720..72bd542af0 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1509,14 +1509,14 @@ int main(int argc, char *argv[]) { log_error("Failed to adjust timer slack: %m"); if (arg_capability_bounding_set_drop) { - r = capability_bounding_set_drop(arg_capability_bounding_set_drop, true); + r = capability_bounding_set_drop_usermode(arg_capability_bounding_set_drop); if (r < 0) { - log_error("Failed to drop capability bounding set: %s", strerror(-r)); + log_error("Failed to drop capability bounding set of usermode helpers: %s", strerror(-r)); goto finish; } - r = capability_bounding_set_drop_usermode(arg_capability_bounding_set_drop); + r = capability_bounding_set_drop(arg_capability_bounding_set_drop, true); if (r < 0) { - log_error("Failed to drop capability bounding set of usermode helpers: %s", strerror(-r)); + log_error("Failed to drop capability bounding set: %s", strerror(-r)); goto finish; } } -- cgit v1.2.1 From 78f66c2151813166549e5482a3dccffe4f890b44 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Mon, 2 Sep 2013 07:36:34 +0200 Subject: keymap: Fix typo in Latitude/Precision rules We actually want to match the product name, "pn:" makes no sense. --- hwdb/60-keyboard.hwdb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index 288d0c8abd..abeb03df8d 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -243,8 +243,8 @@ keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnStudio*155[78]:pvr* KEYBOARD_KEY_b0=! # volume up # Dell Touchpad -keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pn:*Latitude*:pvr* -keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pn:*Precision*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnPrecision*:pvr* KEYBOARD_KEY_9e=!f21 # Dell XPS -- cgit v1.2.1 From ee2babf4c36f9ab65e9ebbe966ed7839c532df45 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Mon, 2 Sep 2013 08:11:07 +0200 Subject: keymap: Explicitly match "any product name" for "all models from vendor" rules Without this, the hwdb trie gets mis-sorted to match the more specific rules first, as ":pvr" is lexicographically after ":pn". So ensure that all our matches have some ":pn" match to avoid this trap. --- hwdb/60-keyboard.hwdb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index abeb03df8d..1fd8a8846e 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -158,7 +158,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnAlienware*:pn* # Asus ########################################################### -keyboard:dmi:bvn*:bvr*:bd*:svnASUS:* +keyboard:dmi:bvn*:bvr*:bd*:svnASUS:pn* KEYBOARD_KEY_ed=volumeup KEYBOARD_KEY_ee=volumedown KEYBOARD_KEY_ef=mute @@ -192,7 +192,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnCompaq*:pn*Evo*N*:pvr* # Dell ########################################################### -keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pn* KEYBOARD_KEY_81=playpause # Play/Pause KEYBOARD_KEY_82=stopcd # Stop KEYBOARD_KEY_83=previoussong # Previous song @@ -866,7 +866,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svn*:pn*:pvr*:rvnQuanta:rn30B7:rvr65.2B:* # Samsung ########################################################### -keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn* KEYBOARD_KEY_74=prog1 # User key KEYBOARD_KEY_75=www KEYBOARD_KEY_78=mail -- cgit v1.2.1 From 51cc07576e119dea6e65478eeba9472979fd0936 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Wed, 4 Sep 2013 12:36:19 +0200 Subject: libudev: fix memleak when enumerating childs We need to free udev-devices again if they don't match. Funny that no-one noticed it yet since valgrind is quite verbose about it. Fix it and free non-matching devices. --- src/libudev/libudev-enumerate.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/libudev/libudev-enumerate.c b/src/libudev/libudev-enumerate.c index 3e791074f3..b96e5b278f 100644 --- a/src/libudev/libudev-enumerate.c +++ b/src/libudev/libudev-enumerate.c @@ -829,23 +829,27 @@ nomatch: static int parent_add_child(struct udev_enumerate *enumerate, const char *path) { struct udev_device *dev; + int r = 0; dev = udev_device_new_from_syspath(enumerate->udev, path); if (dev == NULL) return -ENODEV; if (!match_subsystem(enumerate, udev_device_get_subsystem(dev))) - return 0; + goto nomatch; if (!match_sysname(enumerate, udev_device_get_sysname(dev))) - return 0; + goto nomatch; if (!match_property(enumerate, dev)) - return 0; + goto nomatch; if (!match_sysattr(enumerate, dev)) - return 0; + goto nomatch; syspath_add(enumerate, udev_device_get_syspath(dev)); + r = 1; + +nomatch: udev_device_unref(dev); - return 1; + return r; } static int parent_crawl_children(struct udev_enumerate *enumerate, const char *path, int maxdepth) -- cgit v1.2.1 From c851f34ba1cb379d3b3fc06a8421051fd9d0394d Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Tue, 3 Sep 2013 21:34:02 -0700 Subject: cgtop: fixup the online help The online help shows the keys as uppercase but the code and manpage say lower case. Make the online help follow reality. --- src/cgtop/cgtop.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c index fb523a3e6c..cacf705a0a 100644 --- a/src/cgtop/cgtop.c +++ b/src/cgtop/cgtop.c @@ -824,9 +824,9 @@ int main(int argc, char *argv[]) { case '?': case 'h': fprintf(stdout, - "\t<" ON "P" OFF "> By path; <" ON "T" OFF "> By tasks; <" ON "C" OFF "> By CPU; <" ON "M" OFF "> By memory; <" ON "I" OFF "> By I/O\n" + "\t<" ON "p" OFF "> By path; <" ON "t" OFF "> By tasks; <" ON "c" OFF "> By CPU; <" ON "m" OFF "> By memory; <" ON "i" OFF "> By I/O\n" "\t<" ON "+" OFF "> Increase delay; <" ON "-" OFF "> Decrease delay; <" ON "%%" OFF "> Toggle time\n" - "\t<" ON "Q" OFF "> Quit; <" ON "SPACE" OFF "> Refresh"); + "\t<" ON "q" OFF "> Quit; <" ON "SPACE" OFF "> Refresh"); fflush(stdout); sleep(3); break; -- cgit v1.2.1 From f9e84da678cc28998fb04bf5ba326d91fc2850fa Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Fri, 30 Aug 2013 15:50:41 +0200 Subject: libudev: enumerate: fix NULL-deref for subsystem-matches udev_device_get_subsystem() may return NULL if no subsystem could be figured out by libudev. This might be due to OOM or if the device disconnected between the udev_device_new() call and udev_device_get_subsystem(). Therefore, we need to handle subsystem==NULL safely. Instead of testing for it in each helper, we treat subsystem==NULL as empty subsystem in match_subsystem(). Backtrace of udev_enumerate with an input-device disconnecting in exactly this time-frame: (gdb) bt #0 0x00007ffff569dc24 in strnlen () from /usr/lib/libc.so.6 #1 0x00007ffff56d9e04 in fnmatch@@GLIBC_2.2.5 () from /usr/lib/libc.so.6 #2 0x00007ffff5beb83d in match_subsystem (udev_enumerate=0x7a05f0, subsystem=0x0) at src/libudev/libudev-enumerate.c:727 #3 0x00007ffff5bebb30 in parent_add_child (enumerate=enumerate@entry=0x7a05f0, path=) at src/libudev/libudev-enumerate.c:834 #4 0x00007ffff5bebc3f in parent_crawl_children (enumerate=enumerate@entry=0x7a05f0, path=0x7a56b0 "/sys/devices//input/input97", maxdepth=maxdepth@entry=254) at src/libudev/libudev-enumerate.c:866 #5 0x00007ffff5bebc54 in parent_crawl_children (enumerate=enumerate@entry=0x7a05f0, path=0x79e8c0 "/sys/devices//input", maxdepth=maxdepth@entry=255) at src/libudev/libudev-enumerate.c:868 #6 0x00007ffff5bebc54 in parent_crawl_children (enumerate=enumerate@entry=0x7a05f0, path=path@entry=0x753190 "/sys/devices/", maxdepth=maxdepth@entry=256) at src/libudev/libudev-enumerate.c:868 #7 0x00007ffff5bec7df in scan_devices_children (enumerate=0x7a05f0) at src/libudev/libudev-enumerate.c:882 #8 udev_enumerate_scan_devices (udev_enumerate=udev_enumerate@entry=0x7a05f0) at src/libudev/libudev-enumerate.c:919 #9 0x00007ffff5df8777 in () at some/file.c:181 --- src/libudev/libudev-enumerate.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libudev/libudev-enumerate.c b/src/libudev/libudev-enumerate.c index b96e5b278f..385829d464 100644 --- a/src/libudev/libudev-enumerate.c +++ b/src/libudev/libudev-enumerate.c @@ -721,6 +721,8 @@ static bool match_subsystem(struct udev_enumerate *udev_enumerate, const char *s { struct udev_list_entry *list_entry; + subsystem = subsystem ? : ""; + udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->subsystem_nomatch_list)) { if (fnmatch(udev_list_entry_get_name(list_entry), subsystem, 0) == 0) return false; -- cgit v1.2.1 From 756c9a2499ca377b9e96ea6fc6911ff64040174e Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 4 Sep 2013 17:59:14 +0200 Subject: libudev: enumerate - do not try to match against an empty subsystem --- src/libudev/libudev-enumerate.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libudev/libudev-enumerate.c b/src/libudev/libudev-enumerate.c index 385829d464..bc1e37d341 100644 --- a/src/libudev/libudev-enumerate.c +++ b/src/libudev/libudev-enumerate.c @@ -721,12 +721,14 @@ static bool match_subsystem(struct udev_enumerate *udev_enumerate, const char *s { struct udev_list_entry *list_entry; - subsystem = subsystem ? : ""; + if (!subsystem) + return false; udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->subsystem_nomatch_list)) { if (fnmatch(udev_list_entry_get_name(list_entry), subsystem, 0) == 0) return false; } + if (udev_list_get_entry(&udev_enumerate->subsystem_match_list) != NULL) { udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->subsystem_match_list)) { if (fnmatch(udev_list_entry_get_name(list_entry), subsystem, 0) == 0) @@ -734,6 +736,7 @@ static bool match_subsystem(struct udev_enumerate *udev_enumerate, const char *s } return false; } + return true; } -- cgit v1.2.1 From 629bfc5a7fbbe4861b5cde857140f623d5de5ec5 Mon Sep 17 00:00:00 2001 From: George McCollister Date: Wed, 4 Sep 2013 07:12:43 -0500 Subject: journald: fix vacuuming of archived journals d_name is modified on line 227 so if the entire journal name is needed again p must be used. Before this change when journal_file_empty was called on archived journals it would always return with -2. Signed-off-by: George McCollister --- src/journal/journal-vacuum.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/journal/journal-vacuum.c b/src/journal/journal-vacuum.c index 79572f1fb6..ace772273b 100644 --- a/src/journal/journal-vacuum.c +++ b/src/journal/journal-vacuum.c @@ -265,18 +265,18 @@ int journal_directory_vacuum( /* We do not vacuum active files or unknown files! */ continue; - if (journal_file_empty(dirfd(d), de->d_name)) { + if (journal_file_empty(dirfd(d), p)) { /* Always vacuum empty non-online files. */ - if (unlinkat(dirfd(d), de->d_name, 0) >= 0) - log_debug("Deleted empty journal %s/%s.", directory, de->d_name); + if (unlinkat(dirfd(d), p, 0) >= 0) + log_debug("Deleted empty journal %s/%s.", directory, p); else if (errno != ENOENT) - log_warning("Failed to delete %s/%s: %m", directory, de->d_name); + log_warning("Failed to delete %s/%s: %m", directory, p); continue; } - patch_realtime(directory, de->d_name, &st, &realtime); + patch_realtime(directory, p, &st, &realtime); GREEDY_REALLOC(list, n_allocated, n_list + 1); -- cgit v1.2.1 From 489798614cefed16db5f086c3fa9a301f0276fd8 Mon Sep 17 00:00:00 2001 From: George McCollister Date: Wed, 4 Sep 2013 07:12:44 -0500 Subject: journald: fix fd leak in journal_file_empty Before my previous patch, journal_file_empty wasn't be called with the correct filename. Now that it's being called with the correct filename it leaks file descriptors. This patch closes the file descriptors before returning. Signed-off-by: George McCollister [Edit harald@redhat.com: make use of _cleanup_close_ instead] --- src/journal/journal-vacuum.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/journal/journal-vacuum.c b/src/journal/journal-vacuum.c index ace772273b..178c8030db 100644 --- a/src/journal/journal-vacuum.c +++ b/src/journal/journal-vacuum.c @@ -129,8 +129,9 @@ static void patch_realtime( } static int journal_file_empty(int dir_fd, const char *name) { - int fd, r; + int r; le64_t n_entries; + _cleanup_close_ int fd; fd = openat(dir_fd, name, O_RDONLY|O_CLOEXEC|O_NOFOLLOW|O_NONBLOCK); if (fd < 0) -- cgit v1.2.1 From ca0ceb6f3e7e8ffda57b18c2dfe72dfb9de08f35 Mon Sep 17 00:00:00 2001 From: Andrew Cook Date: Wed, 4 Sep 2013 23:27:40 +1000 Subject: systemd-coredump: Ignore coredumps larger than COREDUMP_MAX Currently this check happens when the coredump has been collected in it's entirety and being received by journald. this is not ideal behaviour when the crashing process is consuming significant percentage of physical memory such as a large instance of firefox or a java application. --- src/journal/coredump.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/journal/coredump.c b/src/journal/coredump.c index fd03e389bb..a7d3c34fe4 100644 --- a/src/journal/coredump.c +++ b/src/journal/coredump.c @@ -41,7 +41,7 @@ #define COREDUMP_MIN_START (3*1024*1024) /* Make sure to not make this larger than the maximum journal entry * size. See ENTRY_SIZE_MAX in journald-native.c. */ -#define COREDUMP_MAX (768*1024*1024) +#define COREDUMP_MAX (767*1024*1024) enum { ARG_PID = 1, @@ -258,6 +258,12 @@ int main(int argc, char* argv[]) { break; coredump_size += n; + + if(coredump_size > COREDUMP_MAX) { + log_error("Coredump too large, ignoring"); + goto finish; + } + if (!GREEDY_REALLOC(coredump_data, coredump_bufsize, coredump_size + 1)) { r = log_oom(); goto finish; -- cgit v1.2.1 From 92f2ff4415b43e3265da0a1f09b24635f0874d55 Mon Sep 17 00:00:00 2001 From: Andrew Cook Date: Wed, 4 Sep 2013 23:27:52 +1000 Subject: systemd-coredump: Log crashes without coredumps on failure Make a best-effort attempt to store information about crashes during failure, currently if these are encountered the crash is completely silenced. ideally coredumpctl would show if a coredump is available. --- src/journal/coredump.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/journal/coredump.c b/src/journal/coredump.c index a7d3c34fe4..68c353fe83 100644 --- a/src/journal/coredump.c +++ b/src/journal/coredump.c @@ -241,7 +241,7 @@ int main(int argc, char* argv[]) { coredump_data = malloc(coredump_bufsize); if (!coredump_data) { r = log_oom(); - goto finish; + goto finalize; } memcpy(coredump_data, "COREDUMP=", 9); @@ -261,12 +261,12 @@ int main(int argc, char* argv[]) { if(coredump_size > COREDUMP_MAX) { log_error("Coredump too large, ignoring"); - goto finish; + goto finalize; } if (!GREEDY_REALLOC(coredump_data, coredump_bufsize, coredump_size + 1)) { r = log_oom(); - goto finish; + goto finalize; } } @@ -274,6 +274,7 @@ int main(int argc, char* argv[]) { iovec[j].iov_len = coredump_size; j++; +finalize: r = sd_journal_sendv(iovec, j); if (r < 0) log_error("Failed to send coredump: %s", strerror(-r)); -- cgit v1.2.1 From 32ce5ae22bf47969cac69abd37290539f9c189de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 6 Sep 2013 13:14:26 +0200 Subject: man: fix typo https://bugs.freedesktop.org/show_bug.cgi?id=68723 --- man/systemd.special.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/systemd.special.xml b/man/systemd.special.xml index e1299abcb0..2900808ef4 100644 --- a/man/systemd.special.xml +++ b/man/systemd.special.xml @@ -385,7 +385,7 @@ this unit during installation. This is best configured via - WantedBy=multi-uer.target + WantedBy=multi-user.target in the unit's [Install] section. -- cgit v1.2.1 From a012ab5293a28af93454b3105ca85ca148b1c11f Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Fri, 6 Sep 2013 16:26:55 -0400 Subject: TODO: update todo --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index fe305ecb66..ff29cba8f9 100644 --- a/TODO +++ b/TODO @@ -636,6 +636,8 @@ Features: when we start a service in order to avoid confusion when a user assumes starting a service is enough to make it accessible +* support User= and Group= attributes for AF_UNIX sockets. + * Make it possible to set the keymap independently from the font on the kernel cmdline. Right now setting one resets also the other. -- cgit v1.2.1 From a6fde35332f5e7f78bff437d7b7bfded83debbaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 31 Aug 2013 20:28:09 +0200 Subject: systemd-run: properly escape arguments Spaces, quotes, and such, were not properly escaped. We should write them like we read them. https://bugs.freedesktop.org/show_bug.cgi?id=67971 --- src/core/dbus-service.c | 21 ++++----- src/shared/strv.c | 37 ++++++++++++++++ src/shared/strv.h | 1 + src/test/test-strv.c | 114 +++++++++++++++++++++++++++++++++--------------- 4 files changed, 125 insertions(+), 48 deletions(-) diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c index 85b13f01ef..696c4462fe 100644 --- a/src/core/dbus-service.c +++ b/src/core/dbus-service.c @@ -273,21 +273,16 @@ static int bus_service_set_transient_property( fputs("ExecStart=\n", f); LIST_FOREACH(command, c, s->exec_command[SERVICE_EXEC_START]) { - char **a; - fputs("ExecStart=", f); + _cleanup_free_ char *a; - if (c->ignore) - fputc('-', f); - - fputc('@', f); - fputs(c->path, f); - - STRV_FOREACH(a, c->argv) { - fputc(' ', f); - fputs(*a, f); - } + a = strv_join_quoted(c->argv); + if (!a) + return -ENOMEM; - fputc('\n', f); + fprintf(f, "ExecStart=%s@%s %s\n", + c->ignore ? "-" : "", + c->path, + a); } fflush(f); diff --git a/src/shared/strv.c b/src/shared/strv.c index 3e7778d61c..2df478f30b 100644 --- a/src/shared/strv.c +++ b/src/shared/strv.c @@ -356,6 +356,43 @@ char *strv_join(char **l, const char *separator) { return r; } +char *strv_join_quoted(char **l) { + char *buf = NULL; + char **s; + size_t allocated = 0, len = 0; + + STRV_FOREACH(s, l) { + /* assuming here that escaped string cannot be more + * than twice as long, and reserving space for the + * separator and quotes. + */ + _cleanup_free_ char *esc = NULL; + size_t needed; + + if (!GREEDY_REALLOC(buf, allocated, + len + strlen(*s) * 2 + 3)) + goto oom; + + esc = cescape(*s); + if (!esc) + goto oom; + + needed = snprintf(buf + len, allocated - len, "%s\"%s\"", + len > 0 ? " " : "", esc); + assert(needed < allocated - len); + len += needed; + } + + if (!buf) + buf = malloc0(1); + + return buf; + + oom: + free(buf); + return NULL; +} + char **strv_append(char **l, const char *s) { char **r, **k; diff --git a/src/shared/strv.h b/src/shared/strv.h index 4ade827a42..4e80ea6d89 100644 --- a/src/shared/strv.h +++ b/src/shared/strv.h @@ -68,6 +68,7 @@ char **strv_split_quoted(const char *s); char **strv_split_newlines(const char *s); char *strv_join(char **l, const char *separator); +char *strv_join_quoted(char **l); char **strv_parse_nulstr(const char *s, size_t l); char **strv_split_nulstr(const char *s); diff --git a/src/test/test-strv.c b/src/test/test-strv.c index 074e1bb3d4..25bee22dfe 100644 --- a/src/test/test-strv.c +++ b/src/test/test-strv.c @@ -42,50 +42,68 @@ static void test_specifier_printf(void) { assert_se(streq(w, "xxx a=AAAA b=BBBB yyy")); } -static void test_strv_find(void) { - const char * const input_table[] = { - "one", - "two", - "three", - NULL - }; +static const char* const input_table_multiple[] = { + "one", + "two", + "three", + NULL, +}; + +static const char* const input_table_one[] = { + "one", + NULL, +}; + +static const char* const input_table_none[] = { + NULL, +}; + +static const char* const input_table_quotes[] = { + "\"", + "'", + "\"\"", + "\\", + "\\\\", + NULL, +}; +#define QUOTES_STRING \ + "\"\\\"\" " \ + "\"\\\'\" " \ + "\"\\\"\\\"\" " \ + "\"\\\\\" " \ + "\"\\\\\\\\\"" + +static const char * const input_table_spaces[] = { + " ", + "' '", + "\" ", + " \"", + " \\\\ ", + NULL, +}; +#define SPACES_STRING \ + "\" \" " \ + "\"\\' \\'\" " \ + "\"\\\" \" " \ + "\" \\\"\" " \ + "\" \\\\\\\\ \"" - assert_se(strv_find((char **)input_table, "three")); - assert_se(!strv_find((char **)input_table, "four")); +static void test_strv_find(void) { + assert_se(strv_find((char **)input_table_multiple, "three")); + assert_se(!strv_find((char **)input_table_multiple, "four")); } static void test_strv_find_prefix(void) { - const char * const input_table[] = { - "one", - "two", - "three", - NULL - }; - - assert_se(strv_find_prefix((char **)input_table, "o")); - assert_se(strv_find_prefix((char **)input_table, "one")); - assert_se(strv_find_prefix((char **)input_table, "")); - assert_se(!strv_find_prefix((char **)input_table, "xxx")); - assert_se(!strv_find_prefix((char **)input_table, "onee")); + assert_se(strv_find_prefix((char **)input_table_multiple, "o")); + assert_se(strv_find_prefix((char **)input_table_multiple, "one")); + assert_se(strv_find_prefix((char **)input_table_multiple, "")); + assert_se(!strv_find_prefix((char **)input_table_multiple, "xxx")); + assert_se(!strv_find_prefix((char **)input_table_multiple, "onee")); } static void test_strv_join(void) { _cleanup_free_ char *p = NULL, *q = NULL, *r = NULL, *s = NULL, *t = NULL; - const char * const input_table_multiple[] = { - "one", - "two", - "three", - NULL - }; - const char * const input_table_one[] = { - "one", - NULL - }; - const char * const input_table_none[] = { - NULL - }; - p = strv_join((char **)input_table_multiple, ", "); assert_se(p); assert_se(streq(p, "one, two, three")); @@ -107,6 +125,25 @@ static void test_strv_join(void) { assert_se(streq(t, "")); } +static void test_strv_quote_unquote(const char* const *split, const char *quoted) { + _cleanup_free_ char *p; + _cleanup_strv_free_ char **s; + char **t; + + p = strv_join_quoted((char **)split); + printf("-%s- --- -%s-\n", p, quoted); /* fprintf deals with NULL, puts does not */ + assert_se(p); + assert_se(streq(p, quoted)); + + s = strv_split_quoted(quoted); + assert_se(s); + STRV_FOREACH(t, s) { + assert_se(*t); + assert_se(streq(*t, *split)); + split++; + } +} + static void test_strv_split_nulstr(void) { _cleanup_strv_free_ char **l = NULL; const char nulstr[] = "str0\0str1\0str2\0str3\0"; @@ -253,6 +290,13 @@ int main(int argc, char *argv[]) { test_strv_find(); test_strv_find_prefix(); test_strv_join(); + + test_strv_quote_unquote(input_table_multiple, "\"one\" \"two\" \"three\""); + test_strv_quote_unquote(input_table_one, "\"one\""); + test_strv_quote_unquote(input_table_none, ""); + test_strv_quote_unquote(input_table_quotes, QUOTES_STRING); + test_strv_quote_unquote(input_table_spaces, SPACES_STRING); + test_strv_split_nulstr(); test_strv_parse_nulstr(); test_strv_overlap(); -- cgit v1.2.1 From 116cc028742836e61abce7582ec9ecf9f0aaeb53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 8 Sep 2013 07:31:25 -0400 Subject: path-util.c: small modernization --- src/shared/path-util.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/shared/path-util.c b/src/shared/path-util.c index 0c1b6a0ab0..6888135778 100644 --- a/src/shared/path-util.c +++ b/src/shared/path-util.c @@ -102,7 +102,8 @@ char **path_split_and_make_absolute(const char *p) { char **l; assert(p); - if (!(l = strv_split(p, ":"))) + l = strv_split(p, ":"); + if (!l) return NULL; if (!path_strv_make_absolute_cwd(l)) { @@ -126,7 +127,7 @@ char *path_make_absolute(const char *p, const char *prefix) { } char *path_make_absolute_cwd(const char *p) { - char *cwd, *r; + _cleanup_free_ char *cwd = NULL; assert(p); @@ -140,10 +141,7 @@ char *path_make_absolute_cwd(const char *p) { if (!cwd) return NULL; - r = path_make_absolute(p, cwd); - free(cwd); - - return r; + return path_make_absolute(p, cwd); } char **path_strv_make_absolute_cwd(char **l) { @@ -156,7 +154,8 @@ char **path_strv_make_absolute_cwd(char **l) { STRV_FOREACH(s, l) { char *t; - if (!(t = path_make_absolute_cwd(*s))) + t = path_make_absolute_cwd(*s); + if (!t) return NULL; free(*s); -- cgit v1.2.1 From c9d954b27ee125c3c90a6d2951c62eec4abb160b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 8 Sep 2013 07:51:39 -0400 Subject: run: allow non-absolute paths as command --- TODO | 2 ++ man/systemd-run.xml | 17 +++++++++++++++++ src/core/manager.c | 6 +----- src/run/run.c | 11 +++++++++-- src/shared/path-util.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++ src/shared/path-util.h | 8 ++++++++ src/test/test-path-util.c | 24 ++++++++++++++++++++++++ 7 files changed, 109 insertions(+), 7 deletions(-) diff --git a/TODO b/TODO index ff29cba8f9..b83fd67b86 100644 --- a/TODO +++ b/TODO @@ -715,6 +715,8 @@ Features: - document initcall_debug - kernel cmdline "bootchart" option for simplicity? +* systemd-run is missing completion scripts + External: * dbus: diff --git a/man/systemd-run.xml b/man/systemd-run.xml index 6b0189c25d..e76a402003 100644 --- a/man/systemd-run.xml +++ b/man/systemd-run.xml @@ -187,6 +187,23 @@ along with systemd; If not, see . code otherwise. + + Example + + The following command will log the environment variables + provided by systemd to services: + + # systemd-run env +Running as unit run-19945.service. +# journalctl -u run-19945.service +Sep 08 07:37:21 bupkis systemd[1]: Starting /usr/bin/env... +Sep 08 07:37:21 bupkis systemd[1]: Started /usr/bin/env. +Sep 08 07:37:21 bupkis env[19948]: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin +Sep 08 07:37:21 bupkis env[19948]: LANG=en_US.UTF-8 +Sep 08 07:37:21 bupkis env[19948]: BOOT_IMAGE=/vmlinuz-3.11.0-0.rc5.git6.2.fc20.x86_64 + + + See Also diff --git a/src/core/manager.c b/src/core/manager.c index 10ccffb404..669af1524f 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -456,11 +456,7 @@ static int manager_setup_signals(Manager *m) { } static int manager_default_environment(Manager *m) { -#ifdef HAVE_SPLIT_USR - const char *path = "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"; -#else - const char *path = "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin"; -#endif + const char *path = "PATH=" DEFAULT_PATH; assert(m); diff --git a/src/run/run.c b/src/run/run.c index c5d314bdf1..da8c788eea 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -39,7 +39,7 @@ static bool arg_send_sighup = false; static int help(void) { - printf("%s [OPTIONS...] [COMMAND LINE...]\n\n" + printf("%s [OPTIONS...] COMMAND [ARGS...]\n\n" "Run the specified command in a transient scope or service unit.\n\n" " -h --help Show this help\n" " --version Show package version\n" @@ -324,7 +324,7 @@ static int start_transient_scope( int main(int argc, char* argv[]) { sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_bus_unref_ sd_bus *bus = NULL; - _cleanup_free_ char *description = NULL; + _cleanup_free_ char *description = NULL, *command = NULL; int r; log_parse_environment(); @@ -334,6 +334,13 @@ int main(int argc, char* argv[]) { if (r <= 0) goto fail; + r = find_binary(argv[optind], &command); + if (r < 0) { + log_error("Failed to find executable %s: %s", argv[optind], strerror(-r)); + goto fail; + } + argv[optind] = command; + if (!arg_description) { description = strv_join(argv + optind, " "); if (!description) { diff --git a/src/shared/path-util.c b/src/shared/path-util.c index 6888135778..8e108db531 100644 --- a/src/shared/path-util.c +++ b/src/shared/path-util.c @@ -425,3 +425,51 @@ int path_is_os_tree(const char *path) { return r < 0 ? 0 : 1; } + +int find_binary(const char *name, char **filename) { + assert(name); + if (strchr(name, '/')) { + char *p; + + if (path_is_absolute(name)) + p = strdup(name); + else + p = path_make_absolute_cwd(name); + if (!p) + return -ENOMEM; + + *filename = p; + return 0; + } else { + const char *path; + char *state, *w; + size_t l; + + /** + * Plain getenv, not secure_getenv, because we want + * to actually allow the user to pick the binary. + */ + path = getenv("PATH"); + if (!path) + path = DEFAULT_PATH; + + FOREACH_WORD_SEPARATOR(w, l, path, ":", state) { + char *p; + + if (asprintf(&p, "%.*s/%s", l, w, name) < 0) + return -ENOMEM; + + if (access(p, X_OK) < 0) { + free(p); + continue; + } + + path_kill_slashes(p); + *filename = p; + + return 0; + } + + return -ENOENT; + } +} diff --git a/src/shared/path-util.h b/src/shared/path-util.h index d187743769..9452931586 100644 --- a/src/shared/path-util.h +++ b/src/shared/path-util.h @@ -25,6 +25,12 @@ #include "macro.h" +#ifdef HAVE_SPLIT_USR +# define DEFAULT_PATH "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" +#else +# define DEFAULT_PATH "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin" +#endif + bool is_path(const char *p) _pure_; char** path_split_and_make_absolute(const char *p); char* path_get_file_name(const char *p) _pure_; @@ -43,3 +49,5 @@ char** path_strv_canonicalize_uniq(char **l); int path_is_mount_point(const char *path, bool allow_symlink); int path_is_read_only_fs(const char *path); int path_is_os_tree(const char *path); + +int find_binary(const char *name, char **filename); diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c index f396b32ffe..b0aeb11a63 100644 --- a/src/test/test-path-util.c +++ b/src/test/test-path-util.c @@ -83,7 +83,31 @@ static void test_path(void) { } } +static void test_find_binary(void) { + char *p; + + assert(find_binary("/bin/sh", &p) == 0); + puts(p); + assert(streq(p, "/bin/sh")); + free(p); + + assert(find_binary("./test-path-util", &p) == 0); + puts(p); + assert(endswith(p, "/test-path-util")); + assert(path_is_absolute(p)); + free(p); + + assert(find_binary("sh", &p) == 0); + puts(p); + assert(endswith(p, "/sh")); + assert(path_is_absolute(p)); + free(p); + + assert(find_binary("xxxx-xxxx", &p) == -ENOENT); +} + int main(void) { test_path(); + test_find_binary(); return 0; } -- cgit v1.2.1 From 4bcc8c3cb57733de6eeb2528a194501fade11e6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 9 Sep 2013 17:31:10 -0400 Subject: Fix two compiler warnings --- src/run/run.c | 1 + src/shared/path-util.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/run/run.c b/src/run/run.c index da8c788eea..18a4920f03 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -28,6 +28,7 @@ #include "strv.h" #include "build.h" #include "unit-name.h" +#include "path-util.h" static bool arg_scope = false; static bool arg_user = false; diff --git a/src/shared/path-util.c b/src/shared/path-util.c index 8e108db531..45099eeda8 100644 --- a/src/shared/path-util.c +++ b/src/shared/path-util.c @@ -456,7 +456,7 @@ int find_binary(const char *name, char **filename) { FOREACH_WORD_SEPARATOR(w, l, path, ":", state) { char *p; - if (asprintf(&p, "%.*s/%s", l, w, name) < 0) + if (asprintf(&p, "%.*s/%s", (int) l, w, name) < 0) return -ENOMEM; if (access(p, X_OK) < 0) { -- cgit v1.2.1 From 046d2bd446815c40abc1ae4309e72a238bc787b4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 7 Sep 2013 09:25:07 -0700 Subject: build-sys: gpt-auto-generator depends on HAVE_BLKID --- Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile.am b/Makefile.am index fd38e8201f..c8283d59e0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1709,6 +1709,7 @@ bin_PROGRAMS += \ endif # ------------------------------------------------------------------------------ +if HAVE_BLKID systemgenerator_PROGRAMS += \ systemd-gpt-auto-generator @@ -1725,6 +1726,7 @@ systemd_gpt_auto_generator_LDADD = \ systemd_gpt_auto_generator_CFLAGS = \ $(AM_CFLAGS) \ $(BLKID_CFLAGS) +endif # ------------------------------------------------------------------------------ systemd_rc_local_generator_SOURCES = \ -- cgit v1.2.1 From 33e74db2667103e33f7e47277378612dcdbdfaa5 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Mon, 9 Sep 2013 17:41:03 -0400 Subject: keymap: Add Asus WMI module We need to override the TOUCHPAD_TOGGLE to F21 to make it useful under X, as for other models. --- hwdb/60-keyboard.hwdb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index 1fd8a8846e..640ff54443 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -163,6 +163,9 @@ keyboard:dmi:bvn*:bvr*:bd*:svnASUS:pn* KEYBOARD_KEY_ee=volumedown KEYBOARD_KEY_ef=mute +keyboard:name:Asus WMI hotkeys:dmi:bvn*:bvr*:bd*:svnASUS*:pn*:pvr* + KEYBOARD_KEY_6b=f21 # Touchpad Toggle + ########################################################### # BenQ ########################################################### -- cgit v1.2.1 From 289f910e16d0a962e128979b67fed5f2ef668e00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 10 Sep 2013 08:20:24 -0400 Subject: journald: be a bit more verbose when vacuuming Vacuuming behaviour is a bit confusing, and/or we have some bugs, so those additional messages should help to find out what's going on. Also, rotation of journal files shouldn't be happening too often, so the level of the messages is bumped to info, so that they'll be logged under normal operation. --- src/initctl/initctl.c | 10 ++++++---- src/journal/journal-vacuum.c | 20 ++++++++++++++------ src/journal/journalctl.c | 2 +- src/journal/journald-server.c | 4 ++++ 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/initctl/initctl.c b/src/initctl/initctl.c index 5fbce4a9a7..ec33040509 100644 --- a/src/initctl/initctl.c +++ b/src/initctl/initctl.c @@ -223,8 +223,10 @@ static int fifo_process(Fifo *f) { assert(f); errno = EIO; - if ((l = read(f->fd, ((uint8_t*) &f->buffer) + f->bytes_read, sizeof(f->buffer) - f->bytes_read)) <= 0) { - + l = read(f->fd, + ((uint8_t*) &f->buffer) + f->bytes_read, + sizeof(f->buffer) - f->bytes_read); + if (l <= 0) { if (errno == EAGAIN) return 0; @@ -372,8 +374,8 @@ static int process_event(Server *s, struct epoll_event *ev) { } f = (Fifo*) ev->data.ptr; - - if ((r = fifo_process(f)) < 0) { + r = fifo_process(f); + if (r < 0) { log_info("Got error on fifo: %s", strerror(-r)); fifo_free(f); return r; diff --git a/src/journal/journal-vacuum.c b/src/journal/journal-vacuum.c index 178c8030db..c73ad8f393 100644 --- a/src/journal/journal-vacuum.c +++ b/src/journal/journal-vacuum.c @@ -159,7 +159,7 @@ int journal_directory_vacuum( struct vacuum_info *list = NULL; unsigned n_list = 0, i; size_t n_allocated = 0; - uint64_t sum = 0; + uint64_t sum = 0, freed = 0; usec_t retention_limit = 0; assert(directory); @@ -267,13 +267,17 @@ int journal_directory_vacuum( continue; if (journal_file_empty(dirfd(d), p)) { - /* Always vacuum empty non-online files. */ - if (unlinkat(dirfd(d), p, 0) >= 0) - log_debug("Deleted empty journal %s/%s.", directory, p); - else if (errno != ENOENT) + uint64_t size = 512UL * (uint64_t) st.st_blocks; + + if (unlinkat(dirfd(d), p, 0) >= 0) { + log_info("Deleted empty journal %s/%s (%"PRIu64" bytes).", + directory, p, size); + freed += size; + } else if (errno != ENOENT) log_warning("Failed to delete %s/%s: %m", directory, p); + continue; } @@ -310,7 +314,9 @@ int journal_directory_vacuum( break; if (unlinkat(dirfd(d), list[i].filename, 0) >= 0) { - log_debug("Deleted archived journal %s/%s.", directory, list[i].filename); + log_debug("Deleted archived journal %s/%s (%"PRIu64" bytes).", + directory, list[i].filename, list[i].usage); + freed += list[i].usage; if (list[i].usage < sum) sum -= list[i].usage; @@ -329,5 +335,7 @@ finish: free(list[i].filename); free(list); + log_info("Vacuuming done, freed %"PRIu64" bytes", freed); + return r; } diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 27c148e689..9a2d255361 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -1301,7 +1301,7 @@ static int access_check(sd_journal *j) { int main(int argc, char *argv[]) { int r; - _cleanup_journal_close_ sd_journal*j = NULL; + _cleanup_journal_close_ sd_journal *j = NULL; bool need_seek = false; sd_id128_t previous_boot_id; bool previous_boot_id_valid = false, first_line = true; diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 14afcfb794..9daeb6e9e7 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -1092,6 +1092,8 @@ int process_event(Server *s, struct epoll_event *ev) { } if (sfsi.ssi_signo == SIGUSR1) { + log_info("Received request to flush runtime journal from PID %"PRIu32, + sfsi.ssi_pid); touch("/run/systemd/journal/flushed"); server_flush_to_var(s); server_sync(s); @@ -1099,6 +1101,8 @@ int process_event(Server *s, struct epoll_event *ev) { } if (sfsi.ssi_signo == SIGUSR2) { + log_info("Received request to rotate journal from PID %"PRIu32, + sfsi.ssi_pid); server_rotate(s); server_vacuum(s); return 1; -- cgit v1.2.1 From 5ca8c5d9775e1d81f087fba71fc3d4690e103bbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 10 Sep 2013 08:27:15 -0400 Subject: man: add not to not use -x in bug reports --- man/journalctl.xml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/man/journalctl.xml b/man/journalctl.xml index 8680e53285..b52caa47bf 100644 --- a/man/journalctl.xml +++ b/man/journalctl.xml @@ -392,7 +392,7 @@ context of an error or log event, possible solutions, as well as pointers to support forums, developer - documentation and any other relevant + documentation, and any other relevant manuals. Note that help texts are not available for all messages, but only for selected ones. For more @@ -400,7 +400,14 @@ please refer to the Message Catalog Developer - Documentation. + Documentation. + + Note: when attaching + journalctl output + to bug reports, please do + not use + . + -- cgit v1.2.1 From 9285c9ff263d90439810735ddca074b4b4193f05 Mon Sep 17 00:00:00 2001 From: Lukas Nykryn Date: Wed, 28 Aug 2013 19:27:44 +0200 Subject: service: remove pidfile after exit of a service --- TODO | 2 -- src/core/service.c | 6 ++++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index b83fd67b86..59e0f979e1 100644 --- a/TODO +++ b/TODO @@ -60,8 +60,6 @@ Features: * better error message if you run systemctl without systemd running -* unlink PID files of units after exit - * tiny tool that saves/restores backlight * systemctl status output should should include list of triggering units and their status diff --git a/src/core/service.c b/src/core/service.c index 4070fd741b..34dde7963e 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -1957,6 +1957,12 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) /* we want fresh tmpdirs in case service is started again immediately */ exec_context_tmp_dirs_done(&s->exec_context); + /* Try to delete the pid file. At this point it will be + * out-of-date, and some software might be confused by it, so + * let's remove it. */ + if (s->pid_file) + unlink_noerrno(s->pid_file); + return; fail: -- cgit v1.2.1 From 27722f964361a7da2532cf0a2d57a2f0dd0a09f2 Mon Sep 17 00:00:00 2001 From: Lukas Nykryn Date: Wed, 28 Aug 2013 15:46:59 +0200 Subject: man: split systemctl commands to sections --- man/systemctl.xml | 1428 +++++++++++++++++++++++++++-------------------------- 1 file changed, 736 insertions(+), 692 deletions(-) diff --git a/man/systemctl.xml b/man/systemctl.xml index 49f22ca0b5..1642a47273 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -503,25 +503,28 @@ along with systemd; If not, see . The following commands are understood: - - - list-units + + Unit Commands - - List known units (subject to limitations specified - with ). + + + list-units - This is the default command. - - + + List known units (subject to limitations specified + with ). - - list-sockets + This is the default command. + + - - List socket units ordered by the listening address. Produces output - similar to - + + list-sockets + + + List socket units ordered by the listening address. Produces output + similar to + LISTEN UNIT ACTIVATES /dev/initctl systemd-initctl.socket systemd-initctl.service ... @@ -529,683 +532,724 @@ LISTEN UNIT ACTIVATES kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service 5 sockets listed. - - Note: because the addresses might contains spaces, this output - is not suitable for programmatic consumption. - - - See also the options , - , and . - - - - - start NAME... - - - Start (activate) one or more units specified on the - command line. - - - - stop NAME... - - - Stop (deactivate) one or more units specified on the - command line. - - - - reload NAME... - - - Asks all units listed on the command line to reload - their configuration. Note that this will reload the - service-specific configuration, not the unit configuration - file of systemd. If you want systemd to reload the - configuration file of a unit use the - daemon-reload command. In other words: - for the example case of Apache, this will reload Apache's - httpd.conf in the web server, not the - apache.service systemd unit - file. - - This command should not be confused with the - daemon-reload or load - commands. - - - - - restart NAME... - - - Restart one or more units specified on the command - line. If the units are not running yet, they will be - started. - - - - try-restart NAME... - - - Restart one or more units specified on the command - line if the units are running. This does nothing if units are not - running. Note that, for compatibility with Red Hat init - scripts, condrestart is equivalent to this - command. - - - - reload-or-restart NAME... - - - Reload one or more units if they support it. If not, - restart them instead. If the units are not running yet, they - will be started. - - - - reload-or-try-restart NAME... - - - Reload one or more units if they support it. If not, - restart them instead. This does nothing if the units are not - running. Note that, for compatibility with SysV init scripts, - force-reload is equivalent to this - command. - - - - isolate NAME - - - Start the unit specified on the command line and its - dependencies and stop all others. - - This is similar to changing the runlevel in a - traditional init system. The isolate - command will immediately stop processes that are not enabled - in the new unit, possibly including the graphical - environment or terminal you are currently using. - - Note that this is allowed only on units where - is enabled. See - systemd.unit5 - for details. - - - - kill NAME... - - - Send a signal to one or more processes of the - unit. Use to select which - process to kill. Use to select - the kill mode and to select the - signal to send. - - - - is-active NAME... - - - Check whether any of the specified units are active - (i.e. running). Returns an exit code 0 if at least one is - active, non-zero otherwise. Unless - is specified, this will also print the current unit state to - STDOUT. - - - - is-failed NAME... - - - Check whether any of the specified units are in a "failed" state. - Returns an exit code 0 if at least one has failed, non-zero - otherwise. Unless is specified, this - will also print the current unit state to - STDOUT. - - - - status [NAME...|PID...] - - - Show terse runtime status information about one or - more units, followed by most recent log data from the - journal. If no units are specified, show all units (subject - to limitations specified with ). If a PID - is passed, show information about the unit the process - belongs to. - - This function is intended to generate human-readable - output. If you are looking for computer-parsable output, use - show instead. - - - - show [NAME...|JOB...] - - - Show properties of one or more units, jobs, or the - manager itself. If no argument is specified properties of - the manager will be shown. If a unit name is specified - properties of the unit is shown, and if a job id is - specified properties of the job is shown. By default, empty - properties are suppressed. Use to - show those too. To select specific properties to show use - . This command is intended to be - used whenever computer-parsable output is required. Use - status if you are looking for formatted - human-readable output. - - - - - set-property NAME ASSIGNMENT... - - - Set the specified unit properties at runtime where - this is supported. This allows changing configuration - parameter properties such as resource management controls at - runtime. Not all properties may be changed at runtime, but - many resource management settings (primarily those in - systemd.cgroup5) - may. The changes are applied instantly, and stored on disk - for future boots, unless is - passed, in which case the settings only apply until the next - reboot. The syntax of the property assignment follows - closely the syntax of assignments in unit files. - - Example: systemctl set-property foobar.service CPUShares=777 - - Note that this command allows changing multiple - properties at the same time, which is preferable over - setting them individually. Like unit file configuration - settings, assigning the empty list to list parameters will - reset the list. - - - - - help NAME...|PID... - - - Show manual pages for one or more units, if - available. If a PID is given, the manual pages for the unit - the process belongs to are shown. - - - - - reset-failed [NAME...] - - - Reset the failed state of the - specified units, or if no unit name is passed, reset the state of all - units. When a unit fails in some way (i.e. process exiting - with non-zero error code, terminating abnormally or timing - out), it will automatically enter the - failed state and its exit code and status - is recorded for introspection by the administrator until the - service is restarted or reset with this command. - - - - - list-unit-files - - - List installed unit files. - - - - - enable NAME... - - - Enable one or more unit files or unit file instances, - as specified on the command line. This will create a number - of symlinks as encoded in the [Install] - sections of the unit files. After the symlinks have been - created, the systemd configuration is reloaded (in a way that - is equivalent to daemon-reload) to ensure - the changes are taken into account immediately. Note that - this does not have the effect of also - starting any of the units being enabled. If this - is desired, a separate start command must - be invoked for the unit. Also note that in case of instance - enablement, symlinks named the same as instances are created in - the install location, however they all point to the same - template unit file. - - This command will print the actions executed. This - output may be suppressed by passing . - - - Note that this operation creates only the suggested - symlinks for the units. While this command is the - recommended way to manipulate the unit configuration - directory, the administrator is free to make additional - changes manually by placing or removing symlinks in the - directory. This is particularly useful to create - configurations that deviate from the suggested default - installation. In this case, the administrator must make sure - to invoke daemon-reload manually as - necessary to ensure the changes are taken into account. - - - Enabling units should not be confused with starting - (activating) units, as done by the start - command. Enabling and starting units is orthogonal: units - may be enabled without being started and started without - being enabled. Enabling simply hooks the unit into various - suggested places (for example, so that the unit is - automatically started on boot or when a particular kind of - hardware is plugged in). Starting actually spawns the daemon - process (in case of service units), or binds the socket (in - case of socket units), and so on. - - Depending on whether , - or is - specified, this enables the unit for the system, for the - calling user only or for all future logins of all - users. Note that in the last case, no systemd daemon - configuration is reloaded. - - - - - disable NAME... - - - Disables one or more units. This removes all symlinks - to the specified unit files from the unit configuration - directory, and hence undoes the changes made by - enable. Note however that this removes - all symlinks to the unit files (i.e. including manual - additions), not just those actually created by - enable. This call implicitly reloads the - systemd daemon configuration after completing the disabling - of the units. Note that this command does not implicitly - stop the units that are being disabled. If this is desired, - an additional stop command should be - executed afterwards. - - This command will print the actions executed. This - output may be suppressed by passing . - - - This command honors , - , in a - similar way as enable. - - - - - is-enabled NAME... - - - Checks whether any of the specified unit files are - enabled (as with enable). Returns an exit - code of 0 if at least one is enabled, non-zero - otherwise. Prints the current enable status. To suppress - this output, use . - - - - - reenable NAME... - - - Reenable one or more unit files, as specified on the - command line. This is a combination of - disable and enable and - is useful to reset the symlinks a unit is enabled with to - the defaults configured in the [Install] - section of the unit file. - - - - - preset NAME... - - - Reset one or more unit files, as specified on the - command line, to the defaults configured in the preset - policy files. This has the same effect as - disable or enable, - depending how the unit is listed in the preset files. For - more information on the preset policy format, see - systemd.preset5. - For more information on the concept of presets, please - consult the - Preset - document. - - - - - mask NAME... - - - Mask one or more unit files, as specified on the - command line. This will link these units to - /dev/null, making it impossible to - start them. This is a stronger version of - disable, since it prohibits all kinds of - activation of the unit, including manual activation. Use - this option with care. - - - - - unmask NAME... - - - Unmask one or more unit files, as specified on the - command line. This will undo the effect of - mask. - - - - - link FILENAME... - - - Link a unit file that is not in the unit file search - paths into the unit file search path. This requires an - absolute path to a unit file. The effect of this can be - undone with disable. The effect of this - command is that a unit file is available for - start and other commands although it - is not installed directly in the unit search path. - - - - - get-default - - - Get the default target specified - via default.target link. - - - - - set-default NAME - - - Set the default target to boot into. Command links - default.target to the given unit. - - - - - list-jobs - - - List jobs that are in progress. - - - - cancel JOB... - - - Cancel one or more jobs specified on the command line - by their numeric job IDs. If no job ID is specified, cancel - all pending jobs. - - - - - list-dependencies NAME - - - Shows required and wanted units of the specified - unit. If no unit is specified, - default.target is implied. Target units - are recursively expanded. When is - passed, all other units are recursively expanded as - well. - - - - snapshot [NAME] - - - Create a snapshot. If a snapshot name is specified, - the new snapshot will be named after it. If none is - specified, an automatic snapshot name is generated. In either - case, the snapshot name used is printed to STDOUT, unless - is specified. - - A snapshot refers to a saved state of the systemd - manager. It is implemented itself as a unit that is - generated dynamically with this command and has dependencies - on all units active at the time. At a later time, the user - may return to this state by using the - isolate command on the snapshot unit. - - - Snapshots are only useful for saving and restoring - which units are running or are stopped, they do not - save/restore any other state. Snapshots are dynamic and lost - on reboot. - - - - delete NAME... - - - Remove a snapshot previously created with - snapshot. - - - - daemon-reload - - - Reload systemd manager configuration. This will reload - all unit files and recreate the entire dependency - tree. While the daemon is reloaded, all sockets systemd - listens on on behalf of user configuration will stay - accessible. This command should not be confused - with the load or - reload commands. - - - - daemon-reexec - - - Reexecute the systemd manager. This will serialize the - manager state, reexecute the process and deserialize the - state again. This command is of little use except for - debugging and package upgrades. Sometimes it might be - helpful as a heavy-weight daemon-reload. - While the daemon is reexecuted, all sockets systemd listening - on behalf of user configuration will stay accessible. - - - - - show-environment - - - Dump the systemd manager environment block. The - environment block will be dumped in straight-forward form - suitable for sourcing into a shell script. This environment - block will be passed to all processes the manager - spawns. - - - - set-environment VARIABLE=VALUE... - - - Set one or more systemd manager environment variables, - as specified on the command line. - - - - unset-environment VARIABLE... - - - Unset one or more systemd manager environment - variables. If only a variable name is specified, it will be - removed regardless of its value. If a variable and a value - are specified, the variable is only removed if it has the - specified value. - - - - default - - - Enter default mode. This is mostly equivalent to - isolate default.target. - - - - rescue - - - Enter rescue mode. This is mostly equivalent to - isolate rescue.target, but also prints a - wall message to all users. - - - - emergency - - - Enter emergency mode. This is mostly equivalent to - isolate emergency.target, but also prints - a wall message to all users. - - - - halt - - - Shut down and halt the system. This is mostly equivalent to - start halt.target --irreversible, but also - prints a wall message to all users. If combined with - , shutdown of all running services is - skipped, however all processes are killed and all file - systems are unmounted or mounted read-only, immediately - followed by the system halt. If is - specified twice, the operation is immediately executed - without terminating any processes or unmounting any file - systems. This may result in data loss. - - - - poweroff - - - Shut down and power-off the system. This is mostly - equivalent to start poweroff.target --irreversible, - but also prints a wall message to all users. If combined with - , shutdown of all running services is - skipped, however all processes are killed and all file - systems are unmounted or mounted read-only, immediately - followed by the powering off. If is - specified twice, the operation is immediately executed - without terminating any processes or unmounting any file - systems. This may result in data loss. - - - - reboot - - - Shut down and reboot the system. This is mostly - equivalent to start reboot.target --irreversible, - but also prints a wall message to all users. If combined with - , shutdown of all running services is - skipped, however all processes are killed and all file - systems are unmounted or mounted read-only, immediately - followed by the reboot. If is - specified twice, the operation is immediately executed - without terminating any processes or unmounting any file - systems. This may result in data loss. - - - - kexec - - - Shut down and reboot the system via kexec. This is - mostly equivalent to start kexec.target --irreversible, - but also prints a wall message to all users. If combined - with , shutdown of all running - services is skipped, however all processes are killed and - all file systems are unmounted or mounted read-only, - immediately followed by the reboot. - - - - exit - - - Ask the systemd manager to quit. This is only - supported for user service managers (i.e. in conjunction - with the option) and will fail - otherwise. - - - - - suspend - - - Suspend the system. This will trigger activation of - the special suspend.target target. - - - - - hibernate - - - Hibernate the system. This will trigger activation of - the special hibernate.target target. - - - - - hybrid-sleep - - - Hibernate and suspend the system. This will trigger - activation of the special - hybrid-sleep.target target. - - - - switch-root ROOT [INIT] - - - Switches to a different root directory and executes a - new system manager process below it. This is intended for - usage in initial RAM disks ("initrd"), and will transition - from the initrd's system manager process (a.k.a "init" - process) to the main system manager process. This call takes two - arguments: the directory that is to become the new root directory, and - the path to the new system manager binary below it to - execute as PID 1. If the latter is omitted or the empty - string, a systemd binary will automatically be searched for - and used as init. If the system manager path is omitted or - equal to the empty string, the state of the initrd's system - manager process is passed to the main system manager, which - allows later introspection of the state of the services - involved in the initrd boot. - - - + + Note: because the addresses might contains spaces, this output + is not suitable for programmatic consumption. + + + See also the options , + , and . + + + + + start NAME... + + + Start (activate) one or more units specified on the + command line. + + + + stop NAME... + + + Stop (deactivate) one or more units specified on the + command line. + + + + reload NAME... + + + Asks all units listed on the command line to reload + their configuration. Note that this will reload the + service-specific configuration, not the unit configuration + file of systemd. If you want systemd to reload the + configuration file of a unit use the + daemon-reload command. In other words: + for the example case of Apache, this will reload Apache's + httpd.conf in the web server, not the + apache.service systemd unit + file. + + This command should not be confused with the + daemon-reload or load + commands. + + + + + restart NAME... + + + Restart one or more units specified on the command + line. If the units are not running yet, they will be + started. + + + + try-restart NAME... + + + Restart one or more units specified on the command + line if the units are running. This does nothing if units are not + running. Note that, for compatibility with Red Hat init + scripts, condrestart is equivalent to this + command. + + + + reload-or-restart NAME... + + + Reload one or more units if they support it. If not, + restart them instead. If the units are not running yet, they + will be started. + + + + reload-or-try-restart NAME... + + + Reload one or more units if they support it. If not, + restart them instead. This does nothing if the units are not + running. Note that, for compatibility with SysV init scripts, + force-reload is equivalent to this + command. + + + + isolate NAME + + + Start the unit specified on the command line and its + dependencies and stop all others. + + This is similar to changing the runlevel in a + traditional init system. The isolate + command will immediately stop processes that are not enabled + in the new unit, possibly including the graphical + environment or terminal you are currently using. + + Note that this is allowed only on units where + is enabled. See + systemd.unit5 + for details. + + + + kill NAME... + + + Send a signal to one or more processes of the + unit. Use to select which + process to kill. Use to select + the kill mode and to select the + signal to send. + + + + is-active NAME... + + + Check whether any of the specified units are active + (i.e. running). Returns an exit code 0 if at least one is + active, non-zero otherwise. Unless + is specified, this will also print the current unit state to + STDOUT. + + + + is-failed NAME... + + + Check whether any of the specified units are in a "failed" state. + Returns an exit code 0 if at least one has failed, non-zero + otherwise. Unless is specified, this + will also print the current unit state to + STDOUT. + + + + status [NAME...|PID...] + + + Show terse runtime status information about one or + more units, followed by most recent log data from the + journal. If no units are specified, show all units (subject + to limitations specified with ). If a PID + is passed, show information about the unit the process + belongs to. + + This function is intended to generate human-readable + output. If you are looking for computer-parsable output, use + show instead. + + + + show [NAME...|JOB...] + + + Show properties of one or more units, jobs, or the + manager itself. If no argument is specified properties of + the manager will be shown. If a unit name is specified + properties of the unit is shown, and if a job id is + specified properties of the job is shown. By default, empty + properties are suppressed. Use to + show those too. To select specific properties to show use + . This command is intended to be + used whenever computer-parsable output is required. Use + status if you are looking for formatted + human-readable output. + + + + + set-property NAME ASSIGNMENT... + + + Set the specified unit properties at runtime where + this is supported. This allows changing configuration + parameter properties such as resource management controls at + runtime. Not all properties may be changed at runtime, but + many resource management settings (primarily those in + systemd.cgroup5) + may. The changes are applied instantly, and stored on disk + for future boots, unless is + passed, in which case the settings only apply until the next + reboot. The syntax of the property assignment follows + closely the syntax of assignments in unit files. + + Example: systemctl set-property foobar.service CPUShares=777 + + Note that this command allows changing multiple + properties at the same time, which is preferable over + setting them individually. Like unit file configuration + settings, assigning the empty list to list parameters will + reset the list. + + + + + help NAME...|PID... + + + Show manual pages for one or more units, if + available. If a PID is given, the manual pages for the unit + the process belongs to are shown. + + + + + reset-failed [NAME...] + + + Reset the failed state of the + specified units, or if no unit name is passed, reset the state of all + units. When a unit fails in some way (i.e. process exiting + with non-zero error code, terminating abnormally or timing + out), it will automatically enter the + failed state and its exit code and status + is recorded for introspection by the administrator until the + service is restarted or reset with this command. + + + + + list-dependencies NAME + + + Shows required and wanted units of the specified + unit. If no unit is specified, + default.target is implied. Target units + are recursively expanded. When is + passed, all other units are recursively expanded as + well. + + + + + + + Unit File Commands + + + + list-unit-files + + + List installed unit files. + + + + + enable NAME... + + + Enable one or more unit files or unit file instances, + as specified on the command line. This will create a number + of symlinks as encoded in the [Install] + sections of the unit files. After the symlinks have been + created, the systemd configuration is reloaded (in a way that + is equivalent to daemon-reload) to ensure + the changes are taken into account immediately. Note that + this does not have the effect of also + starting any of the units being enabled. If this + is desired, a separate start command must + be invoked for the unit. Also note that in case of instance + enablement, symlinks named the same as instances are created in + the install location, however they all point to the same + template unit file. + + This command will print the actions executed. This + output may be suppressed by passing . + + + Note that this operation creates only the suggested + symlinks for the units. While this command is the + recommended way to manipulate the unit configuration + directory, the administrator is free to make additional + changes manually by placing or removing symlinks in the + directory. This is particularly useful to create + configurations that deviate from the suggested default + installation. In this case, the administrator must make sure + to invoke daemon-reload manually as + necessary to ensure the changes are taken into account. + + + Enabling units should not be confused with starting + (activating) units, as done by the start + command. Enabling and starting units is orthogonal: units + may be enabled without being started and started without + being enabled. Enabling simply hooks the unit into various + suggested places (for example, so that the unit is + automatically started on boot or when a particular kind of + hardware is plugged in). Starting actually spawns the daemon + process (in case of service units), or binds the socket (in + case of socket units), and so on. + + Depending on whether , + or is + specified, this enables the unit for the system, for the + calling user only or for all future logins of all + users. Note that in the last case, no systemd daemon + configuration is reloaded. + + + + + disable NAME... + + + Disables one or more units. This removes all symlinks + to the specified unit files from the unit configuration + directory, and hence undoes the changes made by + enable. Note however that this removes + all symlinks to the unit files (i.e. including manual + additions), not just those actually created by + enable. This call implicitly reloads the + systemd daemon configuration after completing the disabling + of the units. Note that this command does not implicitly + stop the units that are being disabled. If this is desired, + an additional stop command should be + executed afterwards. + + This command will print the actions executed. This + output may be suppressed by passing . + + + This command honors , + , in a + similar way as enable. + + + + + is-enabled NAME... + + + Checks whether any of the specified unit files are + enabled (as with enable). Returns an exit + code of 0 if at least one is enabled, non-zero + otherwise. Prints the current enable status. To suppress + this output, use . + + + + + reenable NAME... + + + Reenable one or more unit files, as specified on the + command line. This is a combination of + disable and enable and + is useful to reset the symlinks a unit is enabled with to + the defaults configured in the [Install] + section of the unit file. + + + + + preset NAME... + + + Reset one or more unit files, as specified on the + command line, to the defaults configured in the preset + policy files. This has the same effect as + disable or enable, + depending how the unit is listed in the preset files. For + more information on the preset policy format, see + systemd.preset5. + For more information on the concept of presets, please + consult the + Preset + document. + + + + + mask NAME... + + + Mask one or more unit files, as specified on the + command line. This will link these units to + /dev/null, making it impossible to + start them. This is a stronger version of + disable, since it prohibits all kinds of + activation of the unit, including manual activation. Use + this option with care. + + + + + unmask NAME... + + + Unmask one or more unit files, as specified on the + command line. This will undo the effect of + mask. + + + + + link FILENAME... + + + Link a unit file that is not in the unit file search + paths into the unit file search path. This requires an + absolute path to a unit file. The effect of this can be + undone with disable. The effect of this + command is that a unit file is available for + start and other commands although it + is not installed directly in the unit search path. + + + + + get-default + + + Get the default target specified + via default.target link. + + + + + set-default NAME + + + Set the default target to boot into. Command links + default.target to the given unit. + + + + + + + Job Commands + + + + list-jobs + + + List jobs that are in progress. + + + + cancel JOB... + + + Cancel one or more jobs specified on the command line + by their numeric job IDs. If no job ID is specified, cancel + all pending jobs. + + + + + + + Snapshot Commands + + + + snapshot [NAME] + + + Create a snapshot. If a snapshot name is specified, + the new snapshot will be named after it. If none is + specified, an automatic snapshot name is generated. In either + case, the snapshot name used is printed to STDOUT, unless + is specified. + + A snapshot refers to a saved state of the systemd + manager. It is implemented itself as a unit that is + generated dynamically with this command and has dependencies + on all units active at the time. At a later time, the user + may return to this state by using the + isolate command on the snapshot unit. + + + Snapshots are only useful for saving and restoring + which units are running or are stopped, they do not + save/restore any other state. Snapshots are dynamic and lost + on reboot. + + + + delete NAME... + + + Remove a snapshot previously created with + snapshot. + + + + + + + Environment Commands + + + + show-environment + + + Dump the systemd manager environment block. The + environment block will be dumped in straight-forward form + suitable for sourcing into a shell script. This environment + block will be passed to all processes the manager + spawns. + + + + set-environment VARIABLE=VALUE... + + + Set one or more systemd manager environment variables, + as specified on the command line. + + + + unset-environment VARIABLE... + + + Unset one or more systemd manager environment + variables. If only a variable name is specified, it will be + removed regardless of its value. If a variable and a value + are specified, the variable is only removed if it has the + specified value. + + + + + + + Manager Lifecycle Commands + + + + daemon-reload + + + Reload systemd manager configuration. This will reload + all unit files and recreate the entire dependency + tree. While the daemon is reloaded, all sockets systemd + listens on on behalf of user configuration will stay + accessible. This command should not be confused + with the load or + reload commands. + + + + daemon-reexec + + + Reexecute the systemd manager. This will serialize the + manager state, reexecute the process and deserialize the + state again. This command is of little use except for + debugging and package upgrades. Sometimes it might be + helpful as a heavy-weight daemon-reload. + While the daemon is reexecuted, all sockets systemd listening + on behalf of user configuration will stay accessible. + + + + + + + + System Commands + + + + default + + + Enter default mode. This is mostly equivalent to + isolate default.target. + + + + rescue + + + Enter rescue mode. This is mostly equivalent to + isolate rescue.target, but also prints a + wall message to all users. + + + + emergency + + + Enter emergency mode. This is mostly equivalent to + isolate emergency.target, but also prints + a wall message to all users. + + + + halt + + + Shut down and halt the system. This is mostly equivalent to + start halt.target --irreversible, but also + prints a wall message to all users. If combined with + , shutdown of all running services is + skipped, however all processes are killed and all file + systems are unmounted or mounted read-only, immediately + followed by the system halt. If is + specified twice, the operation is immediately executed + without terminating any processes or unmounting any file + systems. This may result in data loss. + + + + poweroff + + + Shut down and power-off the system. This is mostly + equivalent to start poweroff.target --irreversible, + but also prints a wall message to all users. If combined with + , shutdown of all running services is + skipped, however all processes are killed and all file + systems are unmounted or mounted read-only, immediately + followed by the powering off. If is + specified twice, the operation is immediately executed + without terminating any processes or unmounting any file + systems. This may result in data loss. + + + + reboot + + + Shut down and reboot the system. This is mostly + equivalent to start reboot.target --irreversible, + but also prints a wall message to all users. If combined with + , shutdown of all running services is + skipped, however all processes are killed and all file + systems are unmounted or mounted read-only, immediately + followed by the reboot. If is + specified twice, the operation is immediately executed + without terminating any processes or unmounting any file + systems. This may result in data loss. + + + + kexec + + + Shut down and reboot the system via kexec. This is + mostly equivalent to start kexec.target --irreversible, + but also prints a wall message to all users. If combined + with , shutdown of all running + services is skipped, however all processes are killed and + all file systems are unmounted or mounted read-only, + immediately followed by the reboot. + + + + exit + + + Ask the systemd manager to quit. This is only + supported for user service managers (i.e. in conjunction + with the option) and will fail + otherwise. + + + + + suspend + + + Suspend the system. This will trigger activation of + the special suspend.target target. + + + + + hibernate + + + Hibernate the system. This will trigger activation of + the special hibernate.target target. + + + + + hybrid-sleep + + + Hibernate and suspend the system. This will trigger + activation of the special + hybrid-sleep.target target. + + + + switch-root ROOT [INIT] + + + Switches to a different root directory and executes a + new system manager process below it. This is intended for + usage in initial RAM disks ("initrd"), and will transition + from the initrd's system manager process (a.k.a "init" + process) to the main system manager process. This call takes two + arguments: the directory that is to become the new root directory, and + the path to the new system manager binary below it to + execute as PID 1. If the latter is omitted or the empty + string, a systemd binary will automatically be searched for + and used as init. If the system manager path is omitted or + equal to the empty string, the state of the initrd's system + manager process is passed to the main system manager, which + allows later introspection of the state of the services + involved in the initrd boot. + + + + -- cgit v1.2.1 From 47c0980d37a6255e411747572a00638bca35be5a Mon Sep 17 00:00:00 2001 From: Gao feng Date: Fri, 30 Aug 2013 10:56:00 +0800 Subject: blkio bandwidth: don't clean up all of entries in blockio_device_bandwidths list if we get BlockIOReadBandwidth="", we should only remove the read-bandwidth-entries in blockio_device_bandwidths list. --- src/core/load-fragment.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 4714687955..f4a268c1ef 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -2205,6 +2205,7 @@ int config_parse_blockio_bandwidth( CGroupContext *c = data; const char *bandwidth; off_t bytes; + bool read; size_t n; int r; @@ -2212,9 +2213,14 @@ int config_parse_blockio_bandwidth( assert(lvalue); assert(rvalue); + read = streq("BlockIOReadBandwidth", lvalue); + if (isempty(rvalue)) { - while (c->blockio_device_bandwidths) - cgroup_context_free_blockio_device_bandwidth(c, c->blockio_device_bandwidths); + CGroupBlockIODeviceBandwidth *next; + + LIST_FOREACH_SAFE (device_bandwidths, b, next, c->blockio_device_bandwidths) + if (b->read == read) + cgroup_context_free_blockio_device_bandwidth(c, b); return 0; } @@ -2253,7 +2259,7 @@ int config_parse_blockio_bandwidth( b->path = path; path = NULL; b->bandwidth = (uint64_t) bytes; - b->read = streq("BlockIOReadBandwidth", lvalue); + b->read = read; LIST_PREPEND(CGroupBlockIODeviceBandwidth, device_bandwidths, c->blockio_device_bandwidths, b); -- cgit v1.2.1 From f004c2ca11b1700fb8539a667194e8cd86cef7be Mon Sep 17 00:00:00 2001 From: Gao feng Date: Tue, 10 Sep 2013 17:23:07 +0200 Subject: cgroup: setup BlockIORead/WriteBandwidth in bus_cgroup_set_property This patch adds the support for setting up BlockIORead/WriteBandwidth in bus_cgroup_set_property. --- src/core/dbus-cgroup.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c index 4ce7dc5e7f..0c12c50fd2 100644 --- a/src/core/dbus-cgroup.c +++ b/src/core/dbus-cgroup.c @@ -222,6 +222,101 @@ int bus_cgroup_set_property( return 1; + } else if (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth")) { + DBusMessageIter sub; + unsigned n = 0; + bool read = true; + + if (streq(name, "BlockIOWriteBandwidth")) + read = false; + + if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(i) != DBUS_TYPE_STRUCT) + return -EINVAL; + + dbus_message_iter_recurse(i, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { + DBusMessageIter sub2; + const char *path; + uint64_t u64; + CGroupBlockIODeviceBandwidth *a; + + dbus_message_iter_recurse(&sub, &sub2); + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &u64, false) < 0) + return -EINVAL; + + if (mode != UNIT_CHECK) { + CGroupBlockIODeviceBandwidth *b; + bool exist = false; + + LIST_FOREACH(device_bandwidths, b, c->blockio_device_bandwidths) { + if (path_equal(path, b->path) && read == b->read) { + a = b; + exist = true; + break; + } + } + + if (!exist) { + a = new0(CGroupBlockIODeviceBandwidth, 1); + if (!a) + return -ENOMEM; + + a->read = read; + a->path = strdup(path); + if (!a->path) { + free(a); + return -ENOMEM; + } + } + + a->bandwidth = u64; + + if (!exist) + LIST_PREPEND(CGroupBlockIODeviceBandwidth, device_bandwidths, + c->blockio_device_bandwidths, a); + } + + n++; + dbus_message_iter_next(&sub); + } + + if (mode != UNIT_CHECK) { + _cleanup_free_ char *buf = NULL; + _cleanup_fclose_ FILE *f = NULL; + CGroupBlockIODeviceBandwidth *a; + CGroupBlockIODeviceBandwidth *next; + size_t size = 0; + + if (n == 0) { + LIST_FOREACH_SAFE(device_bandwidths, a, next, c->blockio_device_bandwidths) + if (a->read == read) + cgroup_context_free_blockio_device_bandwidth(c, a); + } + + f = open_memstream(&buf, &size); + if (!f) + return -ENOMEM; + + if (read) { + fputs("BlockIOReadBandwidth=\n", f); + LIST_FOREACH(device_bandwidths, a, c->blockio_device_bandwidths) + if (a->read) + fprintf(f, "BlockIOReadBandwidth=%s %" PRIu64 "\n", a->path, a->bandwidth); + } else { + fputs("BlockIOWriteBandwidth=\n", f); + LIST_FOREACH(device_bandwidths, a, c->blockio_device_bandwidths) + if (!a->read) + fprintf(f, "BlockIOWriteBandwidth=%s %" PRIu64 "\n", a->path, a->bandwidth); + } + + fflush(f); + unit_write_drop_in_private(u, mode, name, buf); + } + + return 1; + } else if (streq(name, "MemoryAccounting")) { if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_BOOLEAN) -- cgit v1.2.1 From 670612567ba54808fea06c445c6f2a7ee2d58197 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Fri, 30 Aug 2013 10:56:02 +0800 Subject: systemcl: add support for setting BlockIORead/WriteBandwidth for unit This patch allows user to set up BlockIOReadBandwidth and BlockIOWriteBandwidth for unit through systemctl. Such as systemctl set-property sshd.service BlockIOReadBandwidth="/dev/sda 100000" systemctl set-property sshd.service BlockIOWriteBandwidth="/dev/sda 200000" --- src/systemctl/systemctl.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index a635891bc0..889d120588 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -3685,6 +3685,11 @@ static int append_assignment(DBusMessageIter *iter, const char *assignment) { rwm = ""; } + if (!path_startswith(path, "/dev")) { + log_error("%s is not a device file in /dev.", path); + return -EINVAL; + } + if (!dbus_message_iter_open_container(&sub2, DBUS_TYPE_STRUCT, NULL, &sub3) || !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, &path) || !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, &rwm) || @@ -3695,6 +3700,52 @@ static int append_assignment(DBusMessageIter *iter, const char *assignment) { if (!dbus_message_iter_close_container(&sub, &sub2)) return log_oom(); + } else if (streq(field, "BlockIOReadBandwidth") || streq(field, "BlockIOWriteBandwidth")) { + DBusMessageIter sub2; + + if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "a(st)", &sub) || + !dbus_message_iter_open_container(&sub, DBUS_TYPE_ARRAY, "(st)", &sub2)) + return log_oom(); + + if (!isempty(eq)) { + const char *path, *bandwidth; + DBusMessageIter sub3; + uint64_t u; + off_t bytes; + char *e; + + e = strchr(eq, ' '); + if (e) { + path = strndupa(eq, e - eq); + bandwidth = e+1; + } else { + log_error("Failed to parse %s value %s.", field, eq); + return -EINVAL; + } + + if (!path_startswith(path, "/dev")) { + log_error("%s is not a device file in /dev.", path); + return -EINVAL; + } + + r = parse_bytes(bandwidth, &bytes); + if (r < 0) { + log_error("Failed to parse byte value %s.", bandwidth); + return -EINVAL; + } + + u = (uint64_t) bytes; + + if (!dbus_message_iter_open_container(&sub2, DBUS_TYPE_STRUCT, NULL, &sub3) || + !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, &path) || + !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_UINT64, &u) || + !dbus_message_iter_close_container(&sub2, &sub3)) + return log_oom(); + } + + if (!dbus_message_iter_close_container(&sub, &sub2)) + return log_oom(); + } else { log_error("Unknown assignment %s.", assignment); return -EINVAL; -- cgit v1.2.1 From 06eb4e3bf87584ea526a90643d49037cf6ffd7ff Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 10 Sep 2013 18:21:10 +0200 Subject: cgroup: compare fs paths with path_equal() rather than streq() --- src/core/dbus-cgroup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c index 0c12c50fd2..3409e4a11b 100644 --- a/src/core/dbus-cgroup.c +++ b/src/core/dbus-cgroup.c @@ -413,7 +413,7 @@ int bus_cgroup_set_property( bool exist = false; LIST_FOREACH(device_allow, b, c->device_allow) { - if (streq(b->path, path)) { + if (path_equal(b->path, path)) { a = b; exist = true; break; -- cgit v1.2.1 From 6f68ecb450970cafea6d1893f63c0b6385518822 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Tue, 27 Aug 2013 13:36:53 +0800 Subject: cgroup: setup BlockIODeviceWeight in bus_cgroup_set_property This patch adds the support for setting up BlockIODeviceWeight in bus_cgroup_set_property. most of the codes are copied from the case that sets up DeviceAllow. --- src/core/dbus-cgroup.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c index 3409e4a11b..1f2a396a6d 100644 --- a/src/core/dbus-cgroup.c +++ b/src/core/dbus-cgroup.c @@ -317,6 +317,92 @@ int bus_cgroup_set_property( return 1; + } else if (streq(name, "BlockIODeviceWeight")) { + DBusMessageIter sub; + unsigned n = 0; + + if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(i) != DBUS_TYPE_STRUCT) + return -EINVAL; + + dbus_message_iter_recurse(i, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { + DBusMessageIter sub2; + const char *path; + uint64_t u64; + unsigned long ul; + CGroupBlockIODeviceWeight *a; + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &u64, false) < 0) + return -EINVAL; + + ul = (unsigned long) u64; + if (ul < 10 || ul > 1000) + return -EINVAL; + + if (mode != UNIT_CHECK) { + CGroupBlockIODeviceWeight *b; + bool exist = false; + + LIST_FOREACH(device_weights, b, c->blockio_device_weights) { + if (path_equal(b->path, path)) { + a = b; + exist = true; + break; + } + } + + if (!exist) { + a = new0(CGroupBlockIODeviceWeight, 1); + if (!a) + return -ENOMEM; + + a->path = strdup(path); + if (!a->path) { + free(a); + return -ENOMEM; + } + } + + a->weight = ul; + + if (!exist) + LIST_PREPEND(CGroupBlockIODeviceWeight, device_weights, + c->blockio_device_weights, a); + } + + n++; + dbus_message_iter_next(&sub); + } + + if (mode != UNIT_CHECK) { + _cleanup_free_ char *buf = NULL; + _cleanup_fclose_ FILE *f = NULL; + CGroupBlockIODeviceWeight *a; + size_t size = 0; + + if (n == 0) { + while (c->blockio_device_weights) + cgroup_context_free_blockio_device_weight(c, c->blockio_device_weights); + } + + f = open_memstream(&buf, &size); + if (!f) + return -ENOMEM; + + fputs("BlockIODeviceWeight=\n", f); + LIST_FOREACH(device_weights, a, c->blockio_device_weights) + fprintf(f, "BlockIODeviceWeight=%s %lu\n", a->path, a->weight); + + fflush(f); + unit_write_drop_in_private(u, mode, name, buf); + } + + return 1; + } else if (streq(name, "MemoryAccounting")) { if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_BOOLEAN) -- cgit v1.2.1 From 7239c1707a69aff63425e8b6570cfabbd7386f61 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Tue, 27 Aug 2013 13:36:54 +0800 Subject: systemcl: add support for setting BlockIODeviceWeight for unit This patch allows user to set up BlockIODeviceWeight for unit through systemctl. Such as systemctl set-property sshd.service BlockIODeviceWeight="/dev/sda 100" --- src/systemctl/systemctl.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 889d120588..0aeae91b35 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -3746,6 +3746,48 @@ static int append_assignment(DBusMessageIter *iter, const char *assignment) { if (!dbus_message_iter_close_container(&sub, &sub2)) return log_oom(); + } else if (streq(field, "BlockIODeviceWeight")) { + DBusMessageIter sub2; + + if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "a(st)", &sub) || + !dbus_message_iter_open_container(&sub, DBUS_TYPE_ARRAY, "(st)", &sub2)) + return log_oom(); + + if (!isempty(eq)) { + const char *path, *weight; + DBusMessageIter sub3; + uint64_t u; + char *e; + + e = strchr(eq, ' '); + if (e) { + path = strndupa(eq, e - eq); + weight = e+1; + } else { + log_error("Failed to parse %s value %s.", field, eq); + return -EINVAL; + } + + if (!path_startswith(path, "/dev")) { + log_error("%s is not a device file in /dev.", path); + return -EINVAL; + } + + r = safe_atou64(weight, &u); + if (r < 0) { + log_error("Failed to parse %s value %s.", field, weight); + return -EINVAL; + } + if (!dbus_message_iter_open_container(&sub2, DBUS_TYPE_STRUCT, NULL, &sub3) || + !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, &path) || + !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_UINT64, &u) || + !dbus_message_iter_close_container(&sub2, &sub3)) + return log_oom(); + } + + if (!dbus_message_iter_close_container(&sub, &sub2)) + return log_oom(); + } else { log_error("Unknown assignment %s.", assignment); return -EINVAL; -- cgit v1.2.1 From b8ab2dc6c9eb8d6c738524f2ab48931855e3a08a Mon Sep 17 00:00:00 2001 From: Gao feng Date: Tue, 27 Aug 2013 13:36:55 +0800 Subject: systemctl: show BlockIODeviceWeight for unit We can use systemctl show unitname to show the BlockIODeviceWeight of unit. --- src/systemctl/systemctl.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 0aeae91b35..a305c3d87d 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -3315,6 +3315,24 @@ static int print_property(const char *name, DBusMessageIter *iter) { } return 0; + } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "BlockIODeviceWeight")) { + DBusMessageIter sub, sub2; + + dbus_message_iter_recurse(iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { + const char *path; + uint64_t weight; + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &weight, false) >= 0) + printf("%s=%s %" PRIu64 "\n", name, strna(path), weight); + + dbus_message_iter_next(&sub); + } + return 0; + } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) { DBusMessageIter sub, sub2; -- cgit v1.2.1 From 6b4991cfde6c0a0b62e836ca75ae362779c474d4 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sun, 25 Aug 2013 09:01:45 +0200 Subject: man: wording and grammar updates This includes regularly-submitted corrections to comma setting and orthographical mishaps that appeared in man/ in recent commits. In this particular commit: - the usual comma fixes - expand contractions (this is prose) --- man/journalctl.xml | 2 +- man/sd_journal_get_cursor.xml | 2 +- man/sd_journal_get_fd.xml | 14 +++++++------- man/sd_notify.xml | 2 +- man/shutdown.xml | 4 ++-- man/systemd-backlight@.service.xml | 4 ++-- man/systemd-cgls.xml | 2 +- man/systemd-efi-boot-generator.xml | 4 ++-- man/systemd-nspawn.xml | 2 +- man/systemd.exec.xml | 9 ++++----- man/systemd.journal-fields.xml | 2 +- man/systemd.mount.xml | 2 +- man/systemd.service.xml | 4 ++-- man/systemd.special.xml | 2 +- man/systemd.time.xml | 2 +- man/systemd.xml | 2 +- man/telinit.xml | 2 +- man/timedatectl.xml | 2 +- man/tmpfiles.d.xml | 12 ++++++------ 19 files changed, 37 insertions(+), 38 deletions(-) diff --git a/man/journalctl.xml b/man/journalctl.xml index b52caa47bf..a5778bf369 100644 --- a/man/journalctl.xml +++ b/man/journalctl.xml @@ -281,7 +281,7 @@ - is very similar + is very similar, but shows monotonic timestamps instead of wallclock timestamps. diff --git a/man/sd_journal_get_cursor.xml b/man/sd_journal_get_cursor.xml index 861927e2e1..4cee7d5b63 100644 --- a/man/sd_journal_get_cursor.xml +++ b/man/sd_journal_get_cursor.xml @@ -120,7 +120,7 @@ returns 0 on success or a negative errno-style error code. sd_journal_test_cursor() returns positive if the current entry matches the - specified cursor, 0 if it doesn't match the specified + specified cursor, 0 if it does not match the specified cursor or a negative errno-style error code on failure. diff --git a/man/sd_journal_get_fd.xml b/man/sd_journal_get_fd.xml index 1c6f25005e..c4387b0856 100644 --- a/man/sd_journal_get_fd.xml +++ b/man/sd_journal_get_fd.xml @@ -232,15 +232,15 @@ else { SD_JOURNAL_APPEND or SD_JOURNAL_INVALIDATE on success or a negative errno-style error code. If - SD_JOURNAL_NOP is returned the - journal didn't change since the last invocation. If - SD_JOURNAL_APPEND is returned new + SD_JOURNAL_NOP is returned, the + journal did not change since the last invocation. If + SD_JOURNAL_APPEND is returned, new entries have been appended to the end of the - journal. If SD_JOURNAL_INVALIDATE + journal. If SD_JOURNAL_INVALIDATE, journal files were added or removed (possibly due to - rotation). In the latter event live-view UIs should - probably refresh their entire display while in the - case of SD_JOURNAL_APPEND it is + rotation). In the latter event, live-view UIs should + probably refresh their entire display, while in the + case of SD_JOURNAL_APPEND, it is sufficient to simply continue reading at the previous end of the journal. diff --git a/man/sd_notify.xml b/man/sd_notify.xml index 7d96890397..fc0f2f6927 100644 --- a/man/sd_notify.xml +++ b/man/sd_notify.xml @@ -200,7 +200,7 @@ the status was sent these functions return with a positive return value. In order to support both, init systems that implement this scheme and those which - don't, it is generally recommended to ignore the return + do not, it is generally recommended to ignore the return value of this call. diff --git a/man/shutdown.xml b/man/shutdown.xml index af799c6649..795fb66328 100644 --- a/man/shutdown.xml +++ b/man/shutdown.xml @@ -133,7 +133,7 @@ - Don't halt, power-off, + Do not halt, power-off, reboot, just write wall message. @@ -141,7 +141,7 @@ - Don't send wall + Do not send wall message before halt, power-off, reboot. diff --git a/man/systemd-backlight@.service.xml b/man/systemd-backlight@.service.xml index f2f54728a3..2b73625e91 100644 --- a/man/systemd-backlight@.service.xml +++ b/man/systemd-backlight@.service.xml @@ -57,9 +57,9 @@ systemd-backlight@.service is a service that restores the display backlight brightness at early-boot and saves it at shutdown. On - disk the backlight brightness is stored in + disk, the backlight brightness is stored in /var/lib/backlight/. Note that by - default only firmware backlight devices are + default, only firmware backlight devices are saved/restored. diff --git a/man/systemd-cgls.xml b/man/systemd-cgls.xml index 53e7f7ddd8..2877f22126 100644 --- a/man/systemd-cgls.xml +++ b/man/systemd-cgls.xml @@ -107,7 +107,7 @@ - Don't hide empty + Do not hide empty control groups in the output. diff --git a/man/systemd-efi-boot-generator.xml b/man/systemd-efi-boot-generator.xml index 03a4fdd0b8..3a79dfb8df 100644 --- a/man/systemd-efi-boot-generator.xml +++ b/man/systemd-efi-boot-generator.xml @@ -56,7 +56,7 @@ systemd-efi-boot-generator is a generator that automatically creates mount and - automount units for the EFI System Partition (ESP) + automount units for the EFI System Partition (ESP), mounting it to /boot. Note that this generator will execute no operation on non-EFI systems, on systems where the boot loader does not @@ -64,7 +64,7 @@ /boot is an explicitly configured mount (for example, listed in fstab5) or where the /boot mount point is non-empty. Since this generator creates an - automount unit the mount will only be activated + automount unit, the mount will only be activated on-demand, when accessed. systemd-efi-boot-generator diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml index e55933d069..6264e48dbc 100644 --- a/man/systemd-nspawn.xml +++ b/man/systemd-nspawn.xml @@ -334,7 +334,7 @@ /var/log/journal exists, it will be bind mounted into the container. If the - subdirectory doesn't exist, no + subdirectory does not exist, no linking is performed. Effectively, booting a container once with guest or diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index b761832ed6..2c673a2a96 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -1,4 +1,3 @@ - @@ -327,8 +326,8 @@ absolute filename or wildcard expression, optionally prefixed with -, which indicates - that if the file does not exist it - won't be read and no error or warning + that if the file does not exist, it + will not be read and no error or warning message is logged. This option may be specified more than once in which case all specified files are read. If the @@ -835,7 +834,7 @@ InaccessibleDirectories= may be prefixed with -, in which case - they will be ignored when they don't + they will be ignored when they do not exist. @@ -972,7 +971,7 @@ sigreturn, exit_group, exit system calls - are implicitly whitelisted and don't + are implicitly whitelisted and do not need to be listed explicitly. This option may be specified more than once in which case the filter masks are diff --git a/man/systemd.journal-fields.xml b/man/systemd.journal-fields.xml index 452406c676..cffcccb53e 100644 --- a/man/systemd.journal-fields.xml +++ b/man/systemd.journal-fields.xml @@ -525,7 +525,7 @@ url="http://www.freedesktop.org/wiki/Software/systemd/json">Journal JSON Format, the addresses of journal entries are serialized into fields prefixed with double - underscores. Note that these aren't proper fields when + underscores. Note that these are not proper fields when stored in the journal but for addressing meta data of entries. They cannot be written as part of structured log entries via calls such as diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml index 214f40c742..9aac94e1a1 100644 --- a/man/systemd.mount.xml +++ b/man/systemd.mount.xml @@ -84,7 +84,7 @@ using configuration not specified in /etc/fstab; mount8 - will refuse options that aren't listed in + will refuse options that are not listed in /etc/fstab if it is not run as UID 0. diff --git a/man/systemd.service.xml b/man/systemd.service.xml index 238a49a251..5df554ca12 100644 --- a/man/systemd.service.xml +++ b/man/systemd.service.xml @@ -483,7 +483,7 @@ was stopped. This includes cases where the commands configured in ExecStop= were used, - where the service doesn't have any + where the service does not have any ExecStop= defined, or where the service exited unexpectedly. This argument takes multiple command lines, @@ -823,7 +823,7 @@ in other words: the Service= setting of .socket units - doesn't have to match the inverse of + does not have to match the inverse of the Sockets= setting of the .service it diff --git a/man/systemd.special.xml b/man/systemd.special.xml index 2900808ef4..4d06607145 100644 --- a/man/systemd.special.xml +++ b/man/systemd.special.xml @@ -448,7 +448,7 @@ after it. Note that networking daemons that simply provide functionality to other hosts - generally don't need to pull + generally do not need to pull this in. diff --git a/man/systemd.time.xml b/man/systemd.time.xml index 4f6dd0f086..3d13b573fa 100644 --- a/man/systemd.time.xml +++ b/man/systemd.time.xml @@ -127,7 +127,7 @@ but when the weekday is specified it must either be in the abbreviated (Wed) or non-abbreviated (Wednesday) English - language form (case doesn't matter), and is not + language form (case does not matter), and is not subject to the locale choice of the user. Either the date, or the time part may be omitted, in which case the current date or 00:00:00, resp., is assumed. The diff --git a/man/systemd.xml b/man/systemd.xml index 9f58bc2f82..47d6438939 100644 --- a/man/systemd.xml +++ b/man/systemd.xml @@ -1022,7 +1022,7 @@ option prefixed with rd. is honored only in the initial RAM disk (initrd), - while the one that isn't prefixed only + while the one that is not prefixed only in the main system. diff --git a/man/telinit.xml b/man/telinit.xml index 4c6064f54a..bb8093914a 100644 --- a/man/telinit.xml +++ b/man/telinit.xml @@ -80,7 +80,7 @@ - Don't send wall + Do not send wall message before reboot/halt/power-off. diff --git a/man/timedatectl.xml b/man/timedatectl.xml index 16ee3df4be..9aade29a78 100644 --- a/man/timedatectl.xml +++ b/man/timedatectl.xml @@ -92,7 +92,7 @@ - Don't query the user + Do not query the user for authentication for privileged operations. diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml index 6a2193d67d..025c8018d9 100644 --- a/man/tmpfiles.d.xml +++ b/man/tmpfiles.d.xml @@ -104,7 +104,7 @@ L /tmp/foobar - - - - /dev/null f - Create a file if it doesn't exist yet (optionally writing a short string into it, if the argument parameter is passed) + Create a file if it does not exist yet (optionally writing a short string into it, if the argument parameter is passed) @@ -122,7 +122,7 @@ L /tmp/foobar - - - - /dev/null d - Create a directory if it doesn't exist yet + Create a directory if it does not exist yet @@ -132,22 +132,22 @@ L /tmp/foobar - - - - /dev/null p - Create a named pipe (FIFO) if it doesn't exist yet + Create a named pipe (FIFO) if it does not exist yet L - Create a symlink if it doesn't exist yet + Create a symlink if it does not exist yet c - Create a character device node if it doesn't exist yet + Create a character device node if it does not exist yet b - Create a block device node if it doesn't exist yet + Create a block device node if it does not exist yet -- cgit v1.2.1 From 1e44448168ff26ff391af83bf67d5bcc3ca368bc Mon Sep 17 00:00:00 2001 From: Lukas Nykryn Date: Thu, 22 Aug 2013 14:47:49 +0200 Subject: man: one more example in tmpfiles.d --- man/tmpfiles.d.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml index 025c8018d9..58ac995a18 100644 --- a/man/tmpfiles.d.xml +++ b/man/tmpfiles.d.xml @@ -322,6 +322,13 @@ L /tmp/foobar - - - - /dev/null d /var/run/screens 1777 root root 10d d /var/run/uscreens 0755 root root 10d12h + + /etc/tmpfiles.d/abrt.conf example + abrt needs a directory created at boot with specific mode and ownership and its content should be preserved. + + d /var/tmp/abrt 0755 abrt abrt +x /var/tmp/abrt/* + -- cgit v1.2.1 From 1361a3e33a1a43a3ea0563df6e4fbb26fe4bb1ab Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 11 Sep 2013 13:57:34 +0200 Subject: man: document that Type=notify is currently incompatible with PrivateNetwork=yes --- man/systemd.service.xml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/man/systemd.service.xml b/man/systemd.service.xml index 5df554ca12..a15dfb2cb6 100644 --- a/man/systemd.service.xml +++ b/man/systemd.service.xml @@ -217,7 +217,11 @@ systemd. If NotifyAccess= is not set, it will be implicitly set to - . + . Note that + currently + Type= + won't work if used in combination with + PrivateNetwork=. Behavior of is very similar -- cgit v1.2.1 From 40f862e3aee1a7712a4867b807e6ab96173bd9cb Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Thu, 22 Aug 2013 10:09:39 +0800 Subject: filesystem targets: disable default dependencies This means we can use default dependencies on mount units without having to get them automatically ordered before the filesystem targets. Reported-by: Thomas Baechler --- units/initrd-fs.target | 2 ++ units/initrd-root-fs.target | 2 ++ units/local-fs.target | 2 ++ units/remote-fs.target | 2 ++ 4 files changed, 8 insertions(+) diff --git a/units/initrd-fs.target b/units/initrd-fs.target index 7578b8824b..866f0d0257 100644 --- a/units/initrd-fs.target +++ b/units/initrd-fs.target @@ -12,3 +12,5 @@ OnFailure=emergency.target OnFailureIsolate=yes ConditionPathExists=/etc/initrd-release After=initrd-parse-etc.service +DefaultDependencies=no +Conflicts=shutdown.target diff --git a/units/initrd-root-fs.target b/units/initrd-root-fs.target index cd189f0296..d0b9863000 100644 --- a/units/initrd-root-fs.target +++ b/units/initrd-root-fs.target @@ -11,3 +11,5 @@ Documentation=man:systemd.special(7) ConditionPathExists=/etc/initrd-release OnFailure=emergency.target OnFailureIsolate=yes +DefaultDependencies=no +Conflicts=shutdown.target diff --git a/units/local-fs.target b/units/local-fs.target index 18c3d74f18..8f06ed6cab 100644 --- a/units/local-fs.target +++ b/units/local-fs.target @@ -9,5 +9,7 @@ Description=Local File Systems Documentation=man:systemd.special(7) After=local-fs-pre.target +DefaultDependencies=no +Conflicts=shutdown.target OnFailure=emergency.target OnFailureIsolate=no diff --git a/units/remote-fs.target b/units/remote-fs.target index 09213e8fca..43ffa5c107 100644 --- a/units/remote-fs.target +++ b/units/remote-fs.target @@ -9,6 +9,8 @@ Description=Remote File Systems Documentation=man:systemd.special(7) After=remote-fs-pre.target +DefaultDependencies=no +Conflicts=shutdown.target [Install] WantedBy=multi-user.target -- cgit v1.2.1 From 80c3b720bf3abbcc9427507d540e286c4ceb3e94 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Mon, 19 Aug 2013 09:20:52 +0800 Subject: fstab-generator: use DefaultDependencies=yes This removes some redundancy between the generator and the core mount handling. --- TODO | 2 -- src/fstab-generator/fstab-generator.c | 52 ++++------------------------------- 2 files changed, 6 insertions(+), 48 deletions(-) diff --git a/TODO b/TODO index 59e0f979e1..b1006bfd6d 100644 --- a/TODO +++ b/TODO @@ -220,8 +220,6 @@ Features: /etc should always override /run+/usr and also any symlink destination. -* remove duplicate default deps logic from fstab-generator vs. mount.c - * when isolating, try to figure out a way how we implicitly can order all units we stop before the isolating unit... diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index 2a779bbccf..6f352d113f 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -116,10 +116,7 @@ static int add_swap(const char *what, struct mntent *me) { fputs("# Automatically generated by systemd-fstab-generator\n\n" "[Unit]\n" - "SourcePath=/etc/fstab\n" - "DefaultDependencies=no\n" - "Conflicts=" SPECIAL_UMOUNT_TARGET "\n" - "Before=" SPECIAL_UMOUNT_TARGET "\n", f); + "SourcePath=/etc/fstab\n", f); if (!noauto && !nofail) fputs("Before=" SPECIAL_SWAP_TARGET "\n", f); @@ -209,9 +206,6 @@ static int add_mount( bool nofail, bool automount, bool isbind, - const char *pre, - const char *pre2, - const char *online, const char *post, const char *source) { _cleanup_free_ char @@ -258,33 +252,9 @@ static int add_mount( fprintf(f, "# Automatically generated by systemd-fstab-generator\n\n" "[Unit]\n" - "SourcePath=%s\n" - "DefaultDependencies=no\n", + "SourcePath=%s\n", source); - if (!path_equal(where, "/")) { - if (pre) - fprintf(f, - "After=%s\n", - pre); - - if (pre2) - fprintf(f, - "After=%s\n", - pre2); - - if (online) - fprintf(f, - "After=%s\n" - "Wants=%s\n", - online, - online); - - fprintf(f, - "Conflicts=" SPECIAL_UMOUNT_TARGET "\n" - "Before=" SPECIAL_UMOUNT_TARGET "\n"); - } - if (post && !noauto && !nofail && !automount) fprintf(f, "Before=%s\n", @@ -368,10 +338,7 @@ static int add_mount( fprintf(f, "# Automatically generated by systemd-fstab-generator\n\n" "[Unit]\n" - "SourcePath=%s\n" - "DefaultDependencies=no\n" - "Conflicts=" SPECIAL_UMOUNT_TARGET "\n" - "Before=" SPECIAL_UMOUNT_TARGET "\n", + "SourcePath=%s\n", source); if (post) @@ -447,7 +414,7 @@ static int parse_fstab(const char *prefix, bool initrd) { k = add_swap(what, me); else { bool noauto, nofail, automount, isbind; - const char *pre, *pre2, *post, *online; + const char *post; noauto = !!hasmntopt(me, "noauto"); nofail = !!hasmntopt(me, "nofail"); @@ -457,25 +424,18 @@ static int parse_fstab(const char *prefix, bool initrd) { isbind = mount_is_bind(me); if (initrd) { - pre = pre2 = online = NULL; post = SPECIAL_INITRD_FS_TARGET; } else if (mount_in_initrd(me)) { - pre = pre2 = online = NULL; post = SPECIAL_INITRD_ROOT_FS_TARGET; } else if (mount_is_network(me)) { - pre = SPECIAL_REMOTE_FS_PRE_TARGET; - pre2 = SPECIAL_NETWORK_TARGET; - online = SPECIAL_NETWORK_ONLINE_TARGET; post = SPECIAL_REMOTE_FS_TARGET; } else { - pre = SPECIAL_LOCAL_FS_PRE_TARGET; - pre2 = online = NULL; post = SPECIAL_LOCAL_FS_TARGET; } k = add_mount(what, where, me->mnt_type, me->mnt_opts, me->mnt_passno, noauto, nofail, automount, - isbind, pre, pre2, online, post, fstab_path); + isbind, post, fstab_path); } if (k < 0) @@ -563,7 +523,7 @@ static int parse_new_root_from_proc_cmdline(void) { log_debug("Found entry what=%s where=/sysroot type=%s", what, type); r = add_mount(what, "/sysroot", type, opts, 0, noauto, nofail, false, - false, NULL, NULL, NULL, SPECIAL_INITRD_ROOT_FS_TARGET, "/proc/cmdline"); + false, SPECIAL_INITRD_ROOT_FS_TARGET, "/proc/cmdline"); return (r < 0) ? r : 0; } -- cgit v1.2.1 From b56a422a919ec5a12f8fa7f9dfc63f7d88c6a077 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Wed, 21 Aug 2013 22:47:26 +0800 Subject: swap: backing device should unconditionally want swap unit There is no need to restrict this to only the 'nofail' case. In the '!nofail' case the unit is already wanted by swap.target, so this is not a functional change. --- src/core/swap.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/swap.c b/src/core/swap.c index 825503f3de..f0e19ad8c4 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -187,8 +187,7 @@ static int swap_add_device_links(Swap *s) { return 0; if (is_device_path(s->what)) - return unit_add_node_link(UNIT(s), s->what, - !p->noauto && p->nofail && + return unit_add_node_link(UNIT(s), s->what, !p->noauto && UNIT(s)->manager->running_as == SYSTEMD_SYSTEM); else /* File based swap devices need to be ordered after -- cgit v1.2.1 From 5073f89f102d98c27c4f3aefb5643b50a5301d10 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Mon, 19 Aug 2013 17:45:24 +0800 Subject: mount: move device links handling from generator This makes mount units work like swap units: when the backing device appears the mount unit will be started. v2: the device should want the mount unconditionally, not only for DefaultDependencies=yes --- src/core/mount.c | 12 ++++++++++- src/fstab-generator/fstab-generator.c | 40 +++-------------------------------- 2 files changed, 14 insertions(+), 38 deletions(-) diff --git a/src/core/mount.c b/src/core/mount.c index c7d29b0c88..d436a84606 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -338,6 +338,12 @@ static bool mount_is_bind(MountParameters *p) { return false; } +static bool mount_is_auto(MountParameters *p) { + assert(p); + + return !mount_test_option(p->options, "noauto"); +} + static bool needs_quota(MountParameters *p) { assert(p); @@ -356,6 +362,7 @@ static bool needs_quota(MountParameters *p) { static int mount_add_device_links(Mount *m) { MountParameters *p; + bool device_wants_mount = false; int r; assert(m); @@ -376,7 +383,10 @@ static int mount_add_device_links(Mount *m) { if (path_equal(m->where, "/")) return 0; - r = unit_add_node_link(UNIT(m), p->what, false); + if (mount_is_auto(p) && UNIT(m)->manager->running_as == SYSTEMD_SYSTEM) + device_wants_mount = true; + + r = unit_add_node_link(UNIT(m), p->what, device_wants_mount); if (r < 0) return r; diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index 6f352d113f..e78001829b 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -170,16 +170,6 @@ static int add_swap(const char *what, struct mntent *me) { return 0; } -static bool mount_is_bind(struct mntent *me) { - assert(me); - - return - hasmntopt(me, "bind") || - streq(me->mnt_type, "bind") || - hasmntopt(me, "rbind") || - streq(me->mnt_type, "rbind"); -} - static bool mount_is_network(struct mntent *me) { assert(me); @@ -205,14 +195,12 @@ static int add_mount( bool noauto, bool nofail, bool automount, - bool isbind, const char *post, const char *source) { _cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL, *device = NULL, *automount_name = NULL, *automount_unit = NULL; _cleanup_fclose_ FILE *f = NULL; - int r; assert(what); assert(where); @@ -296,27 +284,6 @@ static int add_mount( return -errno; } } - - if (!isbind && - !path_equal(where, "/")) { - - r = device_name(what, &device); - if (r < 0) - return r; - - if (r > 0) { - free(lnk); - lnk = strjoin(arg_dest, "/", device, ".wants/", name, NULL); - if (!lnk) - return log_oom(); - - mkdir_parents_label(lnk, 0755); - if (symlink(unit, lnk) < 0) { - log_error("Failed to create symlink %s: %m", lnk); - return -errno; - } - } - } } if (automount && !path_equal(where, "/")) { @@ -413,7 +380,7 @@ static int parse_fstab(const char *prefix, bool initrd) { if (streq(me->mnt_type, "swap")) k = add_swap(what, me); else { - bool noauto, nofail, automount, isbind; + bool noauto, nofail, automount; const char *post; noauto = !!hasmntopt(me, "noauto"); @@ -421,7 +388,6 @@ static int parse_fstab(const char *prefix, bool initrd) { automount = hasmntopt(me, "comment=systemd.automount") || hasmntopt(me, "x-systemd.automount"); - isbind = mount_is_bind(me); if (initrd) { post = SPECIAL_INITRD_FS_TARGET; @@ -435,7 +401,7 @@ static int parse_fstab(const char *prefix, bool initrd) { k = add_mount(what, where, me->mnt_type, me->mnt_opts, me->mnt_passno, noauto, nofail, automount, - isbind, post, fstab_path); + post, fstab_path); } if (k < 0) @@ -523,7 +489,7 @@ static int parse_new_root_from_proc_cmdline(void) { log_debug("Found entry what=%s where=/sysroot type=%s", what, type); r = add_mount(what, "/sysroot", type, opts, 0, noauto, nofail, false, - false, SPECIAL_INITRD_ROOT_FS_TARGET, "/proc/cmdline"); + SPECIAL_INITRD_ROOT_FS_TARGET, "/proc/cmdline"); return (r < 0) ? r : 0; } -- cgit v1.2.1 From 88ac30a1979365a926bc85a9cd7150da85823077 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Mon, 19 Aug 2013 12:34:13 +0800 Subject: mount: filesystems mounted in the initrd should not conflict with umount.target in the real root These mounts should be kept around and unmounted in the shutdown ramfs. Currently, we will still attempt to umount these in the final kill spree, but we should consider avoiding that too. Also, the should_umount function should be generalised and put into util.c or something like that, but we are still discussing precisely how. --- src/core/mount.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/core/mount.c b/src/core/mount.c index d436a84606..5c18d4e463 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -447,6 +447,21 @@ static int mount_add_quota_links(Mount *m) { return 0; } +static bool should_umount(Mount *m) { + MountParameters *p; + + if (path_equal(m->where, "/") || + path_equal(m->where, "/usr")) + return false; + + p = get_mount_parameters(m); + if (p && mount_test_option(p->options, "x-initrd.mount") && + !in_initrd()) + return false; + + return true; +} + static int mount_add_default_dependencies(Mount *m) { const char *after, *after2, *online; MountParameters *p; @@ -491,9 +506,11 @@ static int mount_add_default_dependencies(Mount *m) { return r; } - r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true); - if (r < 0) - return r; + if (should_umount(m)) { + r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true); + if (r < 0) + return r; + } return 0; } @@ -1553,8 +1570,7 @@ static int mount_add_one( if (r < 0) goto fail; - if (!path_equal(where, "/") && - !path_equal(where, "/usr")) { + if (should_umount(MOUNT(u))) { r = unit_add_dependency_by_name(u, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true); if (r < 0) goto fail; -- cgit v1.2.1 From 64347fc2b983f33e7efb0fd2bb44e133fb9f30f4 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Wed, 21 Aug 2013 22:48:56 +0800 Subject: swap: handle nofail/noauto in core --- src/core/swap.c | 15 +++++++++ src/fstab-generator/fstab-generator.c | 59 ++--------------------------------- 2 files changed, 18 insertions(+), 56 deletions(-) diff --git a/src/core/swap.c b/src/core/swap.c index f0e19ad8c4..57d15eb34b 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -197,6 +197,7 @@ static int swap_add_device_links(Swap *s) { } static int swap_add_default_dependencies(Swap *s) { + bool nofail = false, noauto = false; int r; assert(s); @@ -211,6 +212,20 @@ static int swap_add_default_dependencies(Swap *s) { if (r < 0) return r; + if (s->from_fragment) { + SwapParameters *p = &s->parameters_fragment; + + nofail = p->nofail; + noauto = p->noauto; + } + + if (!noauto) { + r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, (nofail ? UNIT_WANTED_BY : UNIT_REQUIRED_BY), + SPECIAL_SWAP_TARGET, NULL, true); + if (r < 0) + return r; + } + return 0; } diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index e78001829b..6ebe8aa673 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -38,22 +38,6 @@ static const char *arg_dest = "/tmp"; static bool arg_enabled = true; -static int device_name(const char *path, char **unit) { - char *p; - - assert(path); - - if (!is_device_path(path)) - return 0; - - p = unit_name_from_path(path, ".device"); - if (!p) - return log_oom(); - - *unit = p; - return 1; -} - static int mount_find_pri(struct mntent *me, int *ret) { char *end, *pri; unsigned long r; @@ -82,7 +66,6 @@ static int mount_find_pri(struct mntent *me, int *ret) { static int add_swap(const char *what, struct mntent *me) { _cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL, *device = NULL; _cleanup_fclose_ FILE *f = NULL; - bool noauto, nofail; int r, pri = -1; assert(what); @@ -94,9 +77,6 @@ static int add_swap(const char *what, struct mntent *me) { return pri; } - noauto = !!hasmntopt(me, "noauto"); - nofail = !!hasmntopt(me, "nofail"); - name = unit_name_from_path(what, ".swap"); if (!name) return log_oom(); @@ -114,14 +94,10 @@ static int add_swap(const char *what, struct mntent *me) { return -errno; } - fputs("# Automatically generated by systemd-fstab-generator\n\n" - "[Unit]\n" - "SourcePath=/etc/fstab\n", f); - - if (!noauto && !nofail) - fputs("Before=" SPECIAL_SWAP_TARGET "\n", f); - fprintf(f, + "# Automatically generated by systemd-fstab-generator\n\n" + "[Unit]\n" + "SourcePath=/etc/fstab\n" "\n" "[Swap]\n" "What=%s\n", @@ -138,35 +114,6 @@ static int add_swap(const char *what, struct mntent *me) { return -errno; } - if (!noauto) { - lnk = strjoin(arg_dest, "/" SPECIAL_SWAP_TARGET ".wants/", name, NULL); - if (!lnk) - return log_oom(); - - mkdir_parents_label(lnk, 0755); - if (symlink(unit, lnk) < 0) { - log_error("Failed to create symlink %s: %m", lnk); - return -errno; - } - - r = device_name(what, &device); - if (r < 0) - return r; - - if (r > 0) { - free(lnk); - lnk = strjoin(arg_dest, "/", device, ".wants/", name, NULL); - if (!lnk) - return log_oom(); - - mkdir_parents_label(lnk, 0755); - if (symlink(unit, lnk) < 0) { - log_error("Failed to create symlink %s: %m", lnk); - return -errno; - } - } - } - return 0; } -- cgit v1.2.1 From 404dac4d96f4aaf66026e8b412c4b67e8773cffa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20B=C3=A4chler?= Date: Sun, 18 Aug 2013 18:24:13 +0200 Subject: cryptsetup: Retry indefinitely if tries=0 option has been set. When running from initrd, entering a wrong passphrase usually means that you cannot boot. Therefore, we allow trying indefinitely. --- man/crypttab.xml | 4 +++- src/cryptsetup/cryptsetup.c | 7 +++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/man/crypttab.xml b/man/crypttab.xml index 15c86d3897..90d8ce95fe 100644 --- a/man/crypttab.xml +++ b/man/crypttab.xml @@ -330,7 +330,9 @@ tries= Specifies the maximum number of - times the user is queried for a password. + times the user is queried for a password. + The default is 3. If set to 0, the user is + queried for a password indefinitely. diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c index ba0fdbc8e8..22b5eead72 100644 --- a/src/cryptsetup/cryptsetup.c +++ b/src/cryptsetup/cryptsetup.c @@ -41,7 +41,7 @@ static unsigned opt_key_size = 0; static unsigned opt_keyfile_size = 0; static unsigned opt_keyfile_offset = 0; static char *opt_hash = NULL; -static unsigned opt_tries = 0; +static unsigned opt_tries = 3; static bool opt_readonly = false; static bool opt_verify = false; static bool opt_discards = false; @@ -576,7 +576,6 @@ int main(int argc, char *argv[]) { else until = 0; - opt_tries = opt_tries > 0 ? opt_tries : 3; opt_key_size = (opt_key_size > 0 ? opt_key_size : 256); if (key_file) { @@ -588,7 +587,7 @@ int main(int argc, char *argv[]) { log_warning("Key file %s is world-readable. This is not a good idea!", key_file); } - for (tries = 0; tries < opt_tries; tries++) { + for (tries = 0; opt_tries == 0 || tries < opt_tries; tries++) { _cleanup_strv_free_ char **passwords = NULL; if (!key_file) { @@ -616,7 +615,7 @@ int main(int argc, char *argv[]) { log_warning("Invalid passphrase."); } - if (tries >= opt_tries) { + if (opt_tries != 0 && tries >= opt_tries) { log_error("Too many attempts; giving up."); r = EXIT_FAILURE; goto finish; -- cgit v1.2.1 From 4c3a31668e4f3be9a35177a35d5b9794cdff663e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 11 Sep 2013 17:44:25 +0200 Subject: Update TODO --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index b1006bfd6d..5fd9a59a7d 100644 --- a/TODO +++ b/TODO @@ -58,6 +58,8 @@ CGroup Rework Completion: Features: +* document that in instead of FsckPassNo= people should just add a manual dep to systemd-fsck@.service to their mount units. + * better error message if you run systemctl without systemd running * tiny tool that saves/restores backlight -- cgit v1.2.1 From 44ded3abc28620279633f51a05f2416e5aa3e8e2 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Wed, 11 Sep 2013 18:48:20 +0200 Subject: sd-login: add a public accessor for the VT number The VT number was already part of the DBus API, but was not exposed in the C API. --- Makefile-man.am | 5 +++++ man/sd_session_is_active.xml | 13 +++++++++++++ src/login/libsystemd-login.sym | 5 +++++ src/login/sd-login.c | 17 +++++++++++++++++ src/systemd/sd-login.h | 3 +++ 5 files changed, 43 insertions(+) diff --git a/Makefile-man.am b/Makefile-man.am index 1c264fa3fb..1f635956e2 100644 --- a/Makefile-man.am +++ b/Makefile-man.am @@ -854,6 +854,7 @@ MANPAGES_ALIAS += \ man/sd_session_get_tty.3 \ man/sd_session_get_type.3 \ man/sd_session_get_uid.3 \ + man/sd_session_get_vt.3 \ man/sd_uid_get_seats.3 \ man/sd_uid_get_sessions.3 \ man/sd_uid_is_on_seat.3 \ @@ -882,6 +883,7 @@ man/sd_session_get_state.3: man/sd_session_is_active.3 man/sd_session_get_tty.3: man/sd_session_is_active.3 man/sd_session_get_type.3: man/sd_session_is_active.3 man/sd_session_get_uid.3: man/sd_session_is_active.3 +man/sd_session_get_vt.3: man/sd_session_is_active.3 man/sd_uid_get_seats.3: man/sd_uid_get_state.3 man/sd_uid_get_sessions.3: man/sd_uid_get_state.3 man/sd_uid_is_on_seat.3: man/sd_uid_get_state.3 @@ -958,6 +960,9 @@ man/sd_session_get_type.html: man/sd_session_is_active.html man/sd_session_get_uid.html: man/sd_session_is_active.html $(html-alias) +man/sd_session_get_vt.html: man/sd_session_is_active.html + $(html-alias) + man/sd_uid_get_seats.html: man/sd_uid_get_state.html $(html-alias) diff --git a/man/sd_session_is_active.xml b/man/sd_session_is_active.xml index e89117d990..9362fbcc55 100644 --- a/man/sd_session_is_active.xml +++ b/man/sd_session_is_active.xml @@ -52,6 +52,7 @@ sd_session_get_class sd_session_get_display sd_session_get_tty + sd_session_get_vt Determine state of a specific session @@ -111,6 +112,12 @@ const char* session char** tty + + + int sd_session_get_vt + const char* session + unsigned* vt + @@ -202,6 +209,12 @@ free3 call after use. + sd_session_get_vt() + may be used to determine the VT number of the + session identified by the specified session + identifier. This function will return an error if + the seat does not support VTs. + If the session parameter of any of these functions is passed as NULL the operation is executed diff --git a/src/login/libsystemd-login.sym b/src/login/libsystemd-login.sym index 0720704dbf..54aa91c609 100644 --- a/src/login/libsystemd-login.sym +++ b/src/login/libsystemd-login.sym @@ -80,3 +80,8 @@ LIBSYSTEMD_LOGIN_205 { global: sd_pid_get_slice; } LIBSYSTEMD_LOGIN_203; + +LIBSYSTEMD_LOGIN_207 { +global: + sd_session_get_vt; +} LIBSYSTEMD_LOGIN_205; diff --git a/src/login/sd-login.c b/src/login/sd-login.c index 06587921cd..8a7838d566 100644 --- a/src/login/sd-login.c +++ b/src/login/sd-login.c @@ -347,6 +347,23 @@ _public_ int sd_session_get_tty(const char *session, char **tty) { return session_get_string(session, "TTY", tty); } +_public_ int sd_session_get_vt(const char *session, unsigned *vtnr) { + _cleanup_free_ char *vtnr_string; + unsigned u; + int r; + + r = session_get_string(session, "VTNr", &vtnr_string); + if (r < 0) + return r; + + r = safe_atou(vtnr_string, &u); + if (r < 0) + return r; + + *vtnr = u; + return 0; +} + _public_ int sd_session_get_service(const char *session, char **service) { return session_get_string(session, "SERVICE", service); } diff --git a/src/systemd/sd-login.h b/src/systemd/sd-login.h index e37aeda2bb..c5837f0ca0 100644 --- a/src/systemd/sd-login.h +++ b/src/systemd/sd-login.h @@ -124,6 +124,9 @@ int sd_session_get_display(const char *session, char **display); /* Determine the TTY of this session. */ int sd_session_get_tty(const char *session, char **display); +/* Determine the VT number of this session. */ +int sd_session_get_vt(const char *session, unsigned *vtnr); + /* Return active session and user of seat */ int sd_seat_get_active(const char *seat, char **session, uid_t *uid); -- cgit v1.2.1 From 7b617155b50fdaad5d06359eb03e98f0c7b3087b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 11 Sep 2013 19:26:47 +0200 Subject: core: failed scope units may not be restarted We don't allow reusing of scopes. --- TODO | 2 ++ src/core/scope.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/TODO b/TODO index 5fd9a59a7d..519657fa81 100644 --- a/TODO +++ b/TODO @@ -58,6 +58,8 @@ CGroup Rework Completion: Features: +* ensure scope units may be started only a single time + * document that in instead of FsckPassNo= people should just add a manual dep to systemd-fsck@.service to their mount units. * better error message if you run systemctl without systemd running diff --git a/src/core/scope.c b/src/core/scope.c index 20a969d913..b94f3ff7ba 100644 --- a/src/core/scope.c +++ b/src/core/scope.c @@ -239,6 +239,9 @@ static int scope_start(Unit *u) { assert(s); + if (s->state == SCOPE_FAILED) + return -EPERM; + if (s->state == SCOPE_STOP_SIGTERM || s->state == SCOPE_STOP_SIGKILL) return -EAGAIN; -- cgit v1.2.1 From 5c390a4ae0d383b2003074ed011d47876c7e630c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 11 Sep 2013 14:31:14 -0400 Subject: Add pam configuration to allow user sessions to work out of the box systemd-logind will start user@.service. user@.service unit uses PAM with service name 'systemd-user' to perform account and session managment tasks. Previously, the name was 'systemd-shared', it is now changed to 'systemd-user'. Most PAM installations use one common setup for different callers. Based on a quick poll, distributions fall into two camps: those that have system-auth (Redhat, Fedora, CentOS, Arch, Gentoo, Mageia, Mandriva), and those that have common-auth (Debian, Ubuntu, OpenSUSE). Distributions that have system-auth have just one configuration file that contains auth, password, account, and session blocks, and distributions that have common-auth also have common-session, common-password, and common-account. It is thus impossible to use one configuration file which would work for everybody. systemd-user now refers to system-auth, because it seems that the approach with one file is more popular and also easier, so let's follow that. --- Makefile.am | 5 +++++ configure.ac | 7 +++++++ src/login/pam-module.c | 4 ++-- src/login/systemd-user | 8 ++++++++ units/user@.service.in | 2 +- 5 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 src/login/systemd-user diff --git a/Makefile.am b/Makefile.am index c8283d59e0..3cb6c494c1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -64,6 +64,7 @@ dbussessionservicedir=@dbussessionservicedir@ dbussystemservicedir=@dbussystemservicedir@ dbusinterfacedir=@dbusinterfacedir@ pamlibdir=@pamlibdir@ +pamconfdir=@pamconfdir@ pkgconfigdatadir=$(datadir)/pkgconfig pkgconfiglibdir=$(libdir)/pkgconfig polkitpolicydir=$(datadir)/polkit-1/actions @@ -3905,6 +3906,9 @@ pam_systemd_la_LIBADD = \ pamlib_LTLIBRARIES = \ pam_systemd.la + +dist_pamconf_DATA = \ + src/login/systemd-user endif # move lib from $(libdir) to $(rootlibdir) and update devel link, if needed @@ -4460,6 +4464,7 @@ DISTCHECK_CONFIGURE_FLAGS = \ --with-bashcompletiondir=$$dc_install_base/$(bashcompletiondir) \ --with-zshcompletiondir=$$dc_install_base/$(zshcompletiondir) \ --with-pamlibdir=$$dc_install_base/$(pamlibdir) \ + --with-pamconfdir=$$dc_install_base/$(pamconfdir) \ --with-rootprefix=$$dc_install_base \ --disable-split-usr diff --git a/configure.ac b/configure.ac index 2541344f0c..c6978c72a5 100644 --- a/configure.ac +++ b/configure.ac @@ -943,6 +943,11 @@ AC_ARG_WITH([pamlibdir], [], [with_pamlibdir=${with_rootlibdir}/security]) +AC_ARG_WITH([pamconfdir], + AS_HELP_STRING([--with-pamconfdir=DIR], [Directory for PAM configuration]), + [], + [with_pamconfdir=${sysconfdir}/pam.d]) + AC_ARG_ENABLE([split-usr], AS_HELP_STRING([--enable-split-usr], [Assume that /bin, /sbin aren\'t symlinks into /usr]), [], @@ -975,6 +980,7 @@ AC_SUBST([dbusinterfacedir], [$with_dbusinterfacedir]) AC_SUBST([bashcompletiondir], [$with_bashcompletiondir]) AC_SUBST([zshcompletiondir], [$with_zshcompletiondir]) AC_SUBST([pamlibdir], [$with_pamlibdir]) +AC_SUBST([pamconfdir], [$with_pamconfdir]) AC_SUBST([rootprefix], [$with_rootprefix]) AC_SUBST([rootlibdir], [$with_rootlibdir]) @@ -1047,6 +1053,7 @@ AC_MSG_RESULT([ Installation Python: ${PYTHON_BINARY} firmware path: ${FIRMWARE_PATH} PAM modules dir: ${with_pamlibdir} + PAM configuration dir: ${with_pamconfdir} D-Bus policy dir: ${with_dbuspolicydir} D-Bus session dir: ${with_dbussessionservicedir} D-Bus system dir: ${with_dbussystemservicedir} diff --git a/src/login/pam-module.c b/src/login/pam-module.c index 8c5b3a10f3..49296b5d63 100644 --- a/src/login/pam-module.c +++ b/src/login/pam-module.c @@ -220,11 +220,11 @@ _public_ PAM_EXTERN int pam_sm_open_session( /* Make sure we don't enter a loop by talking to * systemd-logind when it is actually waiting for the * background to finish start-up. If the service is - * "systemd-shared" we simply set XDG_RUNTIME_DIR and + * "systemd-user" we simply set XDG_RUNTIME_DIR and * leave. */ pam_get_item(handle, PAM_SERVICE, (const void**) &service); - if (streq_ptr(service, "systemd-shared")) { + if (streq_ptr(service, "systemd-user")) { char *p, *rt = NULL; if (asprintf(&p, "/run/systemd/users/%lu", (unsigned long) pw->pw_uid) < 0) { diff --git a/src/login/systemd-user b/src/login/systemd-user new file mode 100644 index 0000000000..7b57dbf784 --- /dev/null +++ b/src/login/systemd-user @@ -0,0 +1,8 @@ +#%PAM-1.0 + +# Used by systemd when launching systemd user instances. + +account include system-auth +session include system-auth +auth required pam_deny.so +password required pam_deny.so diff --git a/units/user@.service.in b/units/user@.service.in index 8f9a3b3347..3f8b59d07f 100644 --- a/units/user@.service.in +++ b/units/user@.service.in @@ -11,7 +11,7 @@ After=systemd-user-sessions.service [Service] User=%I -PAMName=systemd-shared +PAMName=systemd-user Type=notify ExecStart=-@rootlibexecdir@/systemd --user Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%I/dbus/user_bus_socket -- cgit v1.2.1 From 89dc5bcff13ffc755a8ebfe3b9e34dd527f61915 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 11 Sep 2013 23:09:12 +0200 Subject: hwdb: update --- hwdb/20-OUI.hwdb | 1299 ++++++++++++++++++++++++++++++----------- hwdb/20-pci-vendor-model.hwdb | 722 +++++++++++++++++++---- hwdb/20-usb-vendor-model.hwdb | 863 ++++++++++++++++++++++++++- 3 files changed, 2429 insertions(+), 455 deletions(-) diff --git a/hwdb/20-OUI.hwdb b/hwdb/20-OUI.hwdb index baf1df17ac..463397744a 100644 --- a/hwdb/20-OUI.hwdb +++ b/hwdb/20-OUI.hwdb @@ -602,7 +602,7 @@ OUI:0050C20CF* ID_OUI_FROM_DATABASE=PCSC OUI:0050C20D0* - ID_OUI_FROM_DATABASE=Telegrang AB + ID_OUI_FROM_DATABASE=Telefrang AB OUI:0050C20D1* ID_OUI_FROM_DATABASE=Renaissance Networking, Inc. @@ -4070,7 +4070,7 @@ OUI:0050C2556* ID_OUI_FROM_DATABASE=Freiburger BlickZentrum OUI:0050C2557* - ID_OUI_FROM_DATABASE=Netcomsec + ID_OUI_FROM_DATABASE=Netcomsec Co Ltd OUI:0050C2558* ID_OUI_FROM_DATABASE=Bedo Elektronik GmbH @@ -13204,6 +13204,93 @@ OUI:40D855152* OUI:40D855153* ID_OUI_FROM_DATABASE=BlinkPipe Ltd +OUI:40D855154* + ID_OUI_FROM_DATABASE=iart + +OUI:40D855155* + ID_OUI_FROM_DATABASE=Telefrang AB + +OUI:40D855156* + ID_OUI_FROM_DATABASE=Emphysys, Inc. + +OUI:40D855157* + ID_OUI_FROM_DATABASE=Hitachi Power Solutions Co., Ltd. + +OUI:40D855158* + ID_OUI_FROM_DATABASE=Exibea AB + +OUI:40D855159* + ID_OUI_FROM_DATABASE=PLATINUM GmbH + +OUI:40D85515A* + ID_OUI_FROM_DATABASE=DORLET S.A.U + +OUI:40D85515B* + ID_OUI_FROM_DATABASE=SQF Spezialelektronik GmbH + +OUI:40D85515C* + ID_OUI_FROM_DATABASE=Spectratech Inc. + +OUI:40D85515D* + ID_OUI_FROM_DATABASE=Actronic Technologies + +OUI:40D85515E* + ID_OUI_FROM_DATABASE=Prodco International Inc. + +OUI:40D85515F* + ID_OUI_FROM_DATABASE=CT COMPANY + +OUI:40D855160* + ID_OUI_FROM_DATABASE=Thermo Fisher Sceintific + +OUI:40D855161* + ID_OUI_FROM_DATABASE=Solidscape Inc + +OUI:40D855162* + ID_OUI_FROM_DATABASE=LUNA-NEXUS + +OUI:40D855163* + ID_OUI_FROM_DATABASE=KMtronic LTD + +OUI:40D855164* + ID_OUI_FROM_DATABASE=NFT Automatisierungssysteme GmbH + +OUI:40D855165* + ID_OUI_FROM_DATABASE=TECHBOARD SRL + +OUI:40D855166* + ID_OUI_FROM_DATABASE=Anhui Jiante Network Technology Co., Ltd. + +OUI:40D855167* + ID_OUI_FROM_DATABASE=Assembly Contracts Ltd + +OUI:40D855168* + ID_OUI_FROM_DATABASE=OPASCA Systems GmbH + +OUI:40D855169* + ID_OUI_FROM_DATABASE=Photop Koncent + +OUI:40D85516A* + ID_OUI_FROM_DATABASE=Aplex Technology Inc. + +OUI:40D85516B* + ID_OUI_FROM_DATABASE=TECHWAY + +OUI:40D85516D* + ID_OUI_FROM_DATABASE=GENERAL DYNAMICS C4 SYSTEMS + +OUI:40D85516E* + ID_OUI_FROM_DATABASE=Secuinfo Co.Ltd + +OUI:40D85516F* + ID_OUI_FROM_DATABASE=BrightLeaf Power + +OUI:40D855170* + ID_OUI_FROM_DATABASE=ICS Eletronics + +OUI:40D855171* + ID_OUI_FROM_DATABASE=Sicon srl + OUI:000000* ID_OUI_FROM_DATABASE=XEROX CORPORATION @@ -15554,7 +15641,7 @@ OUI:00030F* ID_OUI_FROM_DATABASE=Digital China (Shanghai) Networks Ltd. OUI:000310* - ID_OUI_FROM_DATABASE=ITX E-Globaledge Corporation + ID_OUI_FROM_DATABASE=E-Globaledge Corporation OUI:000311* ID_OUI_FROM_DATABASE=Micro Technology Co., Ltd. @@ -15947,7 +16034,7 @@ OUI:000392* ID_OUI_FROM_DATABASE=Hyundai Teletek Co., Ltd. OUI:000393* - ID_OUI_FROM_DATABASE=Apple Computer, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:000394* ID_OUI_FROM_DATABASE=Connect One @@ -16178,7 +16265,7 @@ OUI:0003DF* ID_OUI_FROM_DATABASE=Desana Systems OUI:0003E0* - ID_OUI_FROM_DATABASE=Motorola, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:0003E1* ID_OUI_FROM_DATABASE=Winmate Communication, Inc. @@ -16574,7 +16661,7 @@ OUI:000463* ID_OUI_FROM_DATABASE=Bosch Security Systems OUI:000464* - ID_OUI_FROM_DATABASE=Fantasma Networks, Inc. + ID_OUI_FROM_DATABASE=Pulse-Link Inc OUI:000465* ID_OUI_FROM_DATABASE=i.s.t isdn-support technik GmbH @@ -16841,7 +16928,7 @@ OUI:0004BC* ID_OUI_FROM_DATABASE=Giantec, Inc. OUI:0004BD* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:0004BE* ID_OUI_FROM_DATABASE=OptXCon, Inc. @@ -16889,7 +16976,7 @@ OUI:0004CC* ID_OUI_FROM_DATABASE=Peek Traffic B.V. OUI:0004CD* - ID_OUI_FROM_DATABASE=Informedia Research Group + ID_OUI_FROM_DATABASE=Extenway Solutions Inc OUI:0004CE* ID_OUI_FROM_DATABASE=Patria Ailon @@ -17048,7 +17135,7 @@ OUI:000501* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. OUI:000502* - ID_OUI_FROM_DATABASE=APPLE COMPUTER + ID_OUI_FROM_DATABASE=Apple OUI:000503* ID_OUI_FROM_DATABASE=ICONAG @@ -19382,7 +19469,7 @@ OUI:00080D* ID_OUI_FROM_DATABASE=Toshiba OUI:00080E* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:00080F* ID_OUI_FROM_DATABASE=Proximion Fiber Optics AB @@ -20909,7 +20996,7 @@ OUI:000A26* ID_OUI_FROM_DATABASE=CEIA S.p.A. OUI:000A27* - ID_OUI_FROM_DATABASE=Apple Computer, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:000A28* ID_OUI_FROM_DATABASE=Motorola @@ -21239,7 +21326,7 @@ OUI:000A94* ID_OUI_FROM_DATABASE=ShangHai cellink CO., LTD OUI:000A95* - ID_OUI_FROM_DATABASE=Apple Computer, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:000A96* ID_OUI_FROM_DATABASE=MEWTEL TECHNOLOGY INC. @@ -21578,7 +21665,7 @@ OUI:000B05* ID_OUI_FROM_DATABASE=Pacific Broadband Networks OUI:000B06* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:000B07* ID_OUI_FROM_DATABASE=Voxpath Networks @@ -23006,7 +23093,7 @@ OUI:000CE4* ID_OUI_FROM_DATABASE=NeuroCom International, Inc. OUI:000CE5* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:000CE6* ID_OUI_FROM_DATABASE=Meru Networks Inc @@ -23066,7 +23153,7 @@ OUI:000CF8* ID_OUI_FROM_DATABASE=Nortel Networks OUI:000CF9* - ID_OUI_FROM_DATABASE=ITT Flygt AB + ID_OUI_FROM_DATABASE=Xylem Water Solutions OUI:000CFA* ID_OUI_FROM_DATABASE=Digital Systems Corp @@ -23525,7 +23612,7 @@ OUI:000D92* ID_OUI_FROM_DATABASE=Arima Communication Corporation OUI:000D93* - ID_OUI_FROM_DATABASE=Apple Computer + ID_OUI_FROM_DATABASE=Apple OUI:000D94* ID_OUI_FROM_DATABASE=AFAR Communications,Inc @@ -23852,7 +23939,7 @@ OUI:000E02* ID_OUI_FROM_DATABASE=Advantech AMT Inc. OUI:000E03* - ID_OUI_FROM_DATABASE=Emulex + ID_OUI_FROM_DATABASE=Emulex Corporation OUI:000E04* ID_OUI_FROM_DATABASE=CMA/Microdialysis AB @@ -24110,7 +24197,7 @@ OUI:000E5B* ID_OUI_FROM_DATABASE=ParkerVision - Direct2Data OUI:000E5C* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:000E5D* ID_OUI_FROM_DATABASE=Triple Play Technologies A/S @@ -24164,7 +24251,7 @@ OUI:000E6D* ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. OUI:000E6E* - ID_OUI_FROM_DATABASE=MICRELEC ELECTRONICS S.A + ID_OUI_FROM_DATABASE=MAT S.A. (Mircrelec Advanced Technology) OUI:000E6F* ID_OUI_FROM_DATABASE=IRIS Corporation Berhad @@ -25073,7 +25160,7 @@ OUI:000F9E* ID_OUI_FROM_DATABASE=Murrelektronik GmbH OUI:000F9F* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:000FA0* ID_OUI_FROM_DATABASE=CANON KOREA BUSINESS SOLUTIONS INC. @@ -25715,7 +25802,7 @@ OUI:001074* ID_OUI_FROM_DATABASE=ATEN INTERNATIONAL CO., LTD. OUI:001075* - ID_OUI_FROM_DATABASE=Maxtor Corporation + ID_OUI_FROM_DATABASE=Segate Technology LLC OUI:001076* ID_OUI_FROM_DATABASE=EUREM GmbH @@ -26114,7 +26201,7 @@ OUI:0010F9* ID_OUI_FROM_DATABASE=UNIQUE SYSTEMS, INC. OUI:0010FA* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:0010FB* ID_OUI_FROM_DATABASE=ZIDA TECHNOLOGIES LIMITED @@ -26210,7 +26297,7 @@ OUI:001119* ID_OUI_FROM_DATABASE=Solteras, Inc. OUI:00111A* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:00111B* ID_OUI_FROM_DATABASE=Targa Systems Div L-3 Communications Canada @@ -26240,7 +26327,7 @@ OUI:001123* ID_OUI_FROM_DATABASE=Appointech, Inc. OUI:001124* - ID_OUI_FROM_DATABASE=Apple Computer + ID_OUI_FROM_DATABASE=Apple OUI:001125* ID_OUI_FROM_DATABASE=IBM Corp @@ -26516,7 +26603,7 @@ OUI:00117F* ID_OUI_FROM_DATABASE=Neotune Information Technology Corporation,.LTD OUI:001180* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:001181* ID_OUI_FROM_DATABASE=InterEnergy Co.Ltd, @@ -26654,7 +26741,7 @@ OUI:0011AD* ID_OUI_FROM_DATABASE=Shanghai Ruijie Technology OUI:0011AE* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:0011AF* ID_OUI_FROM_DATABASE=Medialink-i,Inc @@ -27011,7 +27098,7 @@ OUI:001224* ID_OUI_FROM_DATABASE=NexQL Corporation OUI:001225* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:001226* ID_OUI_FROM_DATABASE=Japan Direx Corporation @@ -27314,7 +27401,7 @@ OUI:001289* ID_OUI_FROM_DATABASE=Advance Sterilization Products OUI:00128A* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:00128B* ID_OUI_FROM_DATABASE=Sensory Networks Inc @@ -27503,7 +27590,7 @@ OUI:0012C8* ID_OUI_FROM_DATABASE=Perfect tech OUI:0012C9* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:0012CA* ID_OUI_FROM_DATABASE=Mechatronic Brick Aps @@ -28007,7 +28094,7 @@ OUI:001370* ID_OUI_FROM_DATABASE=Nokia Danmark A/S OUI:001371* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:001372* ID_OUI_FROM_DATABASE=Dell ESG PCBA Test @@ -28448,7 +28535,7 @@ OUI:001403* ID_OUI_FROM_DATABASE=Renasis, LLC OUI:001404* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:001405* ID_OUI_FROM_DATABASE=OpenIB, Inc. @@ -28523,7 +28610,7 @@ OUI:00141C* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. OUI:00141D* - ID_OUI_FROM_DATABASE=Lust Antriebstechnik GmbH + ID_OUI_FROM_DATABASE=LTi DRIVES GmbH OUI:00141E* ID_OUI_FROM_DATABASE=P.A. Semi, Inc. @@ -28679,7 +28766,7 @@ OUI:001450* ID_OUI_FROM_DATABASE=Heim Systems GmbH OUI:001451* - ID_OUI_FROM_DATABASE=Apple Computer Inc. + ID_OUI_FROM_DATABASE=Apple OUI:001452* ID_OUI_FROM_DATABASE=CALCULEX,INC. @@ -28898,7 +28985,7 @@ OUI:001499* ID_OUI_FROM_DATABASE=Helicomm Inc OUI:00149A* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:00149B* ID_OUI_FROM_DATABASE=Nokota Communications, LLC @@ -29132,7 +29219,7 @@ OUI:0014E7* ID_OUI_FROM_DATABASE=Stolinx,. Inc OUI:0014E8* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:0014E9* ID_OUI_FROM_DATABASE=Nortech International @@ -29345,7 +29432,7 @@ OUI:00152E* ID_OUI_FROM_DATABASE=PacketHop, Inc. OUI:00152F* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:001530* ID_OUI_FROM_DATABASE=EMC Corporation @@ -29666,7 +29753,7 @@ OUI:001599* ID_OUI_FROM_DATABASE=Samsung Electronics Co., LTD OUI:00159A* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:00159B* ID_OUI_FROM_DATABASE=Nortel @@ -29708,7 +29795,7 @@ OUI:0015A7* ID_OUI_FROM_DATABASE=Robatech AG OUI:0015A8* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:0015A9* ID_OUI_FROM_DATABASE=KWANG WOO I&C CO.,LTD @@ -30086,7 +30173,7 @@ OUI:001625* ID_OUI_FROM_DATABASE=Impinj, Inc. OUI:001626* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:001627* ID_OUI_FROM_DATABASE=embedded-logic DESIGN AND MORE GmbH @@ -30323,7 +30410,7 @@ OUI:001674* ID_OUI_FROM_DATABASE=EuroCB (Phils.), Inc. OUI:001675* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:001676* ID_OUI_FROM_DATABASE=Intel Corporate @@ -30512,7 +30599,7 @@ OUI:0016B3* ID_OUI_FROM_DATABASE=Photonicbridges (China) Co., Ltd. OUI:0016B5* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:0016B6* ID_OUI_FROM_DATABASE=Cisco-Linksys @@ -30578,7 +30665,7 @@ OUI:0016CA* ID_OUI_FROM_DATABASE=Nortel OUI:0016CB* - ID_OUI_FROM_DATABASE=Apple Computer + ID_OUI_FROM_DATABASE=Apple OUI:0016CC* ID_OUI_FROM_DATABASE=Xcute Mobile Corp. @@ -30737,7 +30824,7 @@ OUI:0016FF* ID_OUI_FROM_DATABASE=Wamin Optocomm Mfg Corp OUI:001700* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:001701* ID_OUI_FROM_DATABASE=KDE, Inc. @@ -31024,9 +31111,6 @@ OUI:00175F* OUI:001760* ID_OUI_FROM_DATABASE=Naito Densei Machida MFG.CO.,LTD -OUI:001761* - ID_OUI_FROM_DATABASE=ZKSoftware Inc. - OUI:001762* ID_OUI_FROM_DATABASE=Solar Technology, Inc. @@ -31130,7 +31214,7 @@ OUI:001783* ID_OUI_FROM_DATABASE=Texas Instruments OUI:001784* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:001785* ID_OUI_FROM_DATABASE=Sparr Electronics Ltd @@ -31412,7 +31496,7 @@ OUI:0017E1* ID_OUI_FROM_DATABASE=DACOS Technologies Co., Ltd. OUI:0017E2* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:0017E3* ID_OUI_FROM_DATABASE=Texas Instruments @@ -31448,7 +31532,7 @@ OUI:0017ED* ID_OUI_FROM_DATABASE=WooJooIT Ltd. OUI:0017EE* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:0017EF* ID_OUI_FROM_DATABASE=IBM Corp @@ -31460,7 +31544,7 @@ OUI:0017F1* ID_OUI_FROM_DATABASE=Renu Electronics Pvt Ltd OUI:0017F2* - ID_OUI_FROM_DATABASE=Apple Computer + ID_OUI_FROM_DATABASE=Apple OUI:0017F3* ID_OUI_FROM_DATABASE=Harris Corparation @@ -31991,7 +32075,7 @@ OUI:0018A3* ID_OUI_FROM_DATABASE=ZIPPY TECHNOLOGY CORP. OUI:0018A4* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:0018A5* ID_OUI_FROM_DATABASE=ADigit Technologies Corp. @@ -32075,7 +32159,7 @@ OUI:0018BF* ID_OUI_FROM_DATABASE=Essence Technology Solution, Inc. OUI:0018C0* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:0018C1* ID_OUI_FROM_DATABASE=Almitec Informática e Comércio @@ -32399,7 +32483,7 @@ OUI:00192B* ID_OUI_FROM_DATABASE=Aclara RF Systems Inc. OUI:00192C* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:00192D* ID_OUI_FROM_DATABASE=Nokia Corporation @@ -32549,7 +32633,7 @@ OUI:00195D* ID_OUI_FROM_DATABASE=ShenZhen XinHuaTong Opto Electronics Co.,Ltd OUI:00195E* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:00195F* ID_OUI_FROM_DATABASE=Valemount Networks Corporation @@ -32765,7 +32849,7 @@ OUI:0019A5* ID_OUI_FROM_DATABASE=RadarFind Corporation OUI:0019A6* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:0019A7* ID_OUI_FROM_DATABASE=ITU-T @@ -32843,7 +32927,7 @@ OUI:0019BF* ID_OUI_FROM_DATABASE=Citiway technology Co.,ltd OUI:0019C0* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:0019C1* ID_OUI_FROM_DATABASE=Alps Electric Co., Ltd @@ -32948,7 +33032,7 @@ OUI:0019E2* ID_OUI_FROM_DATABASE=Juniper Networks OUI:0019E3* - ID_OUI_FROM_DATABASE=Apple Computer Inc. + ID_OUI_FROM_DATABASE=Apple OUI:0019E4* ID_OUI_FROM_DATABASE=2Wire, Inc @@ -33116,7 +33200,7 @@ OUI:001A1A* ID_OUI_FROM_DATABASE=Gentex Corporation/Electro-Acoustic Products OUI:001A1B* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:001A1C* ID_OUI_FROM_DATABASE=GT&T Engineering Pte Ltd @@ -33341,7 +33425,7 @@ OUI:001A65* ID_OUI_FROM_DATABASE=Seluxit OUI:001A66* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:001A67* ID_OUI_FROM_DATABASE=Infinite QL Sdn Bhd @@ -33392,7 +33476,7 @@ OUI:001A76* ID_OUI_FROM_DATABASE=SDT information Technology Co.,LTD. OUI:001A77* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:001A78* ID_OUI_FROM_DATABASE=ubtos @@ -33554,7 +33638,7 @@ OUI:001AAC* ID_OUI_FROM_DATABASE=Corelatus AB OUI:001AAD* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:001AAE* ID_OUI_FROM_DATABASE=Savant Systems LLC @@ -33692,7 +33776,7 @@ OUI:001ADA* ID_OUI_FROM_DATABASE=Biz-2-Me Inc. OUI:001ADB* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:001ADC* ID_OUI_FROM_DATABASE=Nokia Danmark A/S @@ -33701,7 +33785,7 @@ OUI:001ADD* ID_OUI_FROM_DATABASE=PePWave Ltd OUI:001ADE* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:001ADF* ID_OUI_FROM_DATABASE=Interactivetv Pty Limited @@ -34049,7 +34133,7 @@ OUI:001B51* ID_OUI_FROM_DATABASE=Vector Technology Corp. OUI:001B52* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:001B53* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. @@ -34100,7 +34184,7 @@ OUI:001B62* ID_OUI_FROM_DATABASE=JHT Optoelectronics Co.,Ltd. OUI:001B63* - ID_OUI_FROM_DATABASE=Apple Computer Inc. + ID_OUI_FROM_DATABASE=Apple OUI:001B64* ID_OUI_FROM_DATABASE=IsaacLandKorea Co., Ltd, @@ -34112,7 +34196,7 @@ OUI:001B66* ID_OUI_FROM_DATABASE=Sennheiser electronic GmbH & Co. KG OUI:001B67* - ID_OUI_FROM_DATABASE=Ubiquisys Ltd + ID_OUI_FROM_DATABASE=Cisco Systems Inc OUI:001B68* ID_OUI_FROM_DATABASE=Modnnet Co., Ltd @@ -34466,7 +34550,7 @@ OUI:001BDC* ID_OUI_FROM_DATABASE=Vencer Co., Ltd. OUI:001BDD* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:001BDE* ID_OUI_FROM_DATABASE=Renkus-Heinz, Inc. @@ -34622,10 +34706,10 @@ OUI:001C10* ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC OUI:001C11* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:001C12* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:001C13* ID_OUI_FROM_DATABASE=OPTSYS TECHNOLOGY CO., LTD. @@ -35108,7 +35192,7 @@ OUI:001CB2* ID_OUI_FROM_DATABASE=BPT SPA OUI:001CB3* - ID_OUI_FROM_DATABASE=APPLE, INC + ID_OUI_FROM_DATABASE=Apple OUI:001CB4* ID_OUI_FROM_DATABASE=Iridium Satellite LLC @@ -35150,7 +35234,7 @@ OUI:001CC0* ID_OUI_FROM_DATABASE=Intel Corporate OUI:001CC1* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:001CC2* ID_OUI_FROM_DATABASE=Part II Research, Inc. @@ -35324,7 +35408,7 @@ OUI:001CFA* ID_OUI_FROM_DATABASE=Alarm.com OUI:001CFB* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:001CFC* ID_OUI_FROM_DATABASE=Suminet Communication Technologies (Shanghai) Co., Ltd. @@ -35576,7 +35660,7 @@ OUI:001D4E* ID_OUI_FROM_DATABASE=TCM Mobile LLC OUI:001D4F* - ID_OUI_FROM_DATABASE=Apple Computer Inc. + ID_OUI_FROM_DATABASE=Apple OUI:001D50* ID_OUI_FROM_DATABASE=SPINETIX SA @@ -35660,7 +35744,7 @@ OUI:001D6A* ID_OUI_FROM_DATABASE=Alpha Networks Inc. OUI:001D6B* - ID_OUI_FROM_DATABASE=Motorola (formerly Netopia, Inc + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:001D6C* ID_OUI_FROM_DATABASE=ClariPhy Communications, Inc. @@ -35909,7 +35993,7 @@ OUI:001DBD* ID_OUI_FROM_DATABASE=Versamed Inc. OUI:001DBE* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:001DBF* ID_OUI_FROM_DATABASE=Radiient Technologies, Inc. @@ -36317,7 +36401,7 @@ OUI:001E45* ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB OUI:001E46* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:001E47* ID_OUI_FROM_DATABASE=PT. Hariff Daya Tunggal Engineering @@ -36353,7 +36437,7 @@ OUI:001E51* ID_OUI_FROM_DATABASE=Converter Industry Srl OUI:001E52* - ID_OUI_FROM_DATABASE=Apple Computer Inc + ID_OUI_FROM_DATABASE=Apple OUI:001E53* ID_OUI_FROM_DATABASE=Further Tech Co., LTD @@ -36377,7 +36461,7 @@ OUI:001E59* ID_OUI_FROM_DATABASE=Silicon Turnkey Express, LLC OUI:001E5A* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:001E5B* ID_OUI_FROM_DATABASE=Unitron Company, Inc. @@ -36530,7 +36614,7 @@ OUI:001E8C* ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. OUI:001E8D* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:001E8E* ID_OUI_FROM_DATABASE=Hunkeler AG @@ -36689,7 +36773,7 @@ OUI:001EC1* ID_OUI_FROM_DATABASE=3COM EUROPE LTD OUI:001EC2* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:001EC3* ID_OUI_FROM_DATABASE=Kozio, Inc. @@ -36704,79 +36788,79 @@ OUI:001EC6* ID_OUI_FROM_DATABASE=Obvius Holdings LLC OUI:001EC7* - ID_OUI_FROM_DATABASE=2Wire + ID_OUI_FROM_DATABASE=2Wire, Inc. OUI:001EC8* - ID_OUI_FROM_DATABASE=Rapid Mobile (Pty) Ltd + ID_OUI_FROM_DATABASE=2Wire, Inc. OUI:001EC9* - ID_OUI_FROM_DATABASE=Dell Inc + ID_OUI_FROM_DATABASE=2Wire, Inc. OUI:001ECA* - ID_OUI_FROM_DATABASE=Nortel + ID_OUI_FROM_DATABASE=2Wire, Inc. OUI:001ECB* - ID_OUI_FROM_DATABASE="RPC "Energoautomatika" Ltd + ID_OUI_FROM_DATABASE=2Wire, Inc. OUI:001ECC* - ID_OUI_FROM_DATABASE=CDVI + ID_OUI_FROM_DATABASE=2Wire, Inc. OUI:001ECD* - ID_OUI_FROM_DATABASE=KYLAND + ID_OUI_FROM_DATABASE=2Wire, Inc. OUI:001ECE* - ID_OUI_FROM_DATABASE=BISA Technologies (Hong Kong) Limited + ID_OUI_FROM_DATABASE=2Wire, Inc. OUI:001ECF* - ID_OUI_FROM_DATABASE=PHILIPS ELECTRONICS UK LTD + ID_OUI_FROM_DATABASE=2Wire, Inc. OUI:001ED0* - ID_OUI_FROM_DATABASE=Ingespace + ID_OUI_FROM_DATABASE=2Wire, Inc. OUI:001ED1* - ID_OUI_FROM_DATABASE=Keyprocessor B.V. + ID_OUI_FROM_DATABASE=2Wire, Inc. OUI:001ED2* - ID_OUI_FROM_DATABASE=Ray Shine Video Technology Inc + ID_OUI_FROM_DATABASE=2Wire, Inc. OUI:001ED3* - ID_OUI_FROM_DATABASE=Dot Technology Int'l Co., Ltd. + ID_OUI_FROM_DATABASE=2Wire, Inc. OUI:001ED4* - ID_OUI_FROM_DATABASE=Doble Engineering + ID_OUI_FROM_DATABASE=2Wire, Inc. OUI:001ED5* - ID_OUI_FROM_DATABASE=Tekon-Automatics + ID_OUI_FROM_DATABASE=2Wire, Inc. OUI:001ED6* - ID_OUI_FROM_DATABASE=Alentec & Orion AB + ID_OUI_FROM_DATABASE=2Wire, Inc. OUI:001ED7* - ID_OUI_FROM_DATABASE=H-Stream Wireless, Inc. + ID_OUI_FROM_DATABASE=2Wire, Inc. OUI:001ED8* - ID_OUI_FROM_DATABASE=Digital United Inc. + ID_OUI_FROM_DATABASE=2Wire, Inc. OUI:001ED9* - ID_OUI_FROM_DATABASE=Mitsubishi Precision Co.,LTd. + ID_OUI_FROM_DATABASE=2Wire, Inc. OUI:001EDA* - ID_OUI_FROM_DATABASE=Wesemann Elektrotechniek B.V. + ID_OUI_FROM_DATABASE=2Wire, Inc. OUI:001EDB* - ID_OUI_FROM_DATABASE=Giken Trastem Co., Ltd. + ID_OUI_FROM_DATABASE=2Wire, Inc. OUI:001EDC* - ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB + ID_OUI_FROM_DATABASE=2Wire, Inc. OUI:001EDD* - ID_OUI_FROM_DATABASE=WASKO S.A. + ID_OUI_FROM_DATABASE=2Wire, Inc. OUI:001EDE* - ID_OUI_FROM_DATABASE=BYD COMPANY LIMITED + ID_OUI_FROM_DATABASE=2Wire, Inc. OUI:001EDF* - ID_OUI_FROM_DATABASE=Master Industrialization Center Kista + ID_OUI_FROM_DATABASE=2Wire, Inc. OUI:001EE0* ID_OUI_FROM_DATABASE=Urmet Domus SpA @@ -37148,7 +37232,7 @@ OUI:001F5A* ID_OUI_FROM_DATABASE=Beckwith Electric Co. OUI:001F5B* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:001F5C* ID_OUI_FROM_DATABASE=Nokia Danmark A/S @@ -37253,7 +37337,7 @@ OUI:001F7D* ID_OUI_FROM_DATABASE=embedded wireless GmbH OUI:001F7E* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:001F7F* ID_OUI_FROM_DATABASE=Phabrix Limited @@ -37463,7 +37547,7 @@ OUI:001FC3* ID_OUI_FROM_DATABASE=SmartSynch, Inc OUI:001FC4* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:001FC5* ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. @@ -37604,7 +37688,7 @@ OUI:001FF2* ID_OUI_FROM_DATABASE=VIA Technologies, Inc. OUI:001FF3* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:001FF4* ID_OUI_FROM_DATABASE=Power Monitors, Inc. @@ -37835,7 +37919,7 @@ OUI:00203F* ID_OUI_FROM_DATABASE=JUKI CORPORATION OUI:002040* - ID_OUI_FROM_DATABASE=Motorola Broadband Communications Sector + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:002041* ID_OUI_FROM_DATABASE=DATA NET @@ -38498,7 +38582,7 @@ OUI:00211D* ID_OUI_FROM_DATABASE=Dataline AB OUI:00211E* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:00211F* ID_OUI_FROM_DATABASE=SHINSUNG DELTATECH CO.,LTD. @@ -38570,7 +38654,7 @@ OUI:002135* ID_OUI_FROM_DATABASE=ALCATEL-LUCENT OUI:002136* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:002137* ID_OUI_FROM_DATABASE=Bay Controls, LLC @@ -38609,7 +38693,7 @@ OUI:002142* ID_OUI_FROM_DATABASE=Advanced Control Systems doo OUI:002143* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:002144* ID_OUI_FROM_DATABASE=SS Telecoms @@ -38792,7 +38876,7 @@ OUI:00217F* ID_OUI_FROM_DATABASE=Intraco Technology Pte Ltd OUI:002180* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:002181* ID_OUI_FROM_DATABASE=Si2 Microsystems Limited @@ -39107,7 +39191,7 @@ OUI:0021E8* ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. OUI:0021E9* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:0021EA* ID_OUI_FROM_DATABASE=Bystronic Laser AG @@ -39224,7 +39308,7 @@ OUI:00220F* ID_OUI_FROM_DATABASE=MoCA (Multimedia over Coax Alliance) OUI:002210* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:002211* ID_OUI_FROM_DATABASE=Rohati Systems @@ -39368,7 +39452,7 @@ OUI:002240* ID_OUI_FROM_DATABASE=Universal Telecom S/A OUI:002241* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:002242* ID_OUI_FROM_DATABASE=Alacron Inc. @@ -39713,7 +39797,7 @@ OUI:0022B3* ID_OUI_FROM_DATABASE=Sei S.p.A. OUI:0022B4* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:0022B5* ID_OUI_FROM_DATABASE=NOVITA @@ -39971,7 +40055,7 @@ OUI:00230A* ID_OUI_FROM_DATABASE=ARBURG GmbH & Co KG OUI:00230B* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:00230C* ID_OUI_FROM_DATABASE=CLOVER ELECTRONICS CO.,LTD. @@ -39992,7 +40076,7 @@ OUI:002311* ID_OUI_FROM_DATABASE=Gloscom Co., Ltd. OUI:002312* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:002313* ID_OUI_FROM_DATABASE=Qool Technologies Ltd. @@ -40088,7 +40172,7 @@ OUI:002331* ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. OUI:002332* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:002333* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. @@ -40259,7 +40343,7 @@ OUI:00236B* ID_OUI_FROM_DATABASE=Xembedded, Inc. OUI:00236C* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:00236D* ID_OUI_FROM_DATABASE=ResMed Ltd @@ -40283,10 +40367,10 @@ OUI:002373* ID_OUI_FROM_DATABASE=GridIron Systems, Inc. OUI:002374* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:002375* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:002376* ID_OUI_FROM_DATABASE=HTC Corporation @@ -40379,7 +40463,7 @@ OUI:002394* ID_OUI_FROM_DATABASE=Samjeon OUI:002395* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:002396* ID_OUI_FROM_DATABASE=ANDES TECHNOLOGY CORPORATION @@ -40418,10 +40502,10 @@ OUI:0023A1* ID_OUI_FROM_DATABASE=Trend Electronics Ltd OUI:0023A2* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:0023A3* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:0023A4* ID_OUI_FROM_DATABASE=New Concepts Development Corp. @@ -40457,7 +40541,7 @@ OUI:0023AE* ID_OUI_FROM_DATABASE=Dell Inc. OUI:0023AF* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:0023B0* ID_OUI_FROM_DATABASE=COMXION Technology Inc. @@ -40601,7 +40685,7 @@ OUI:0023DE* ID_OUI_FROM_DATABASE=Ansync Inc. OUI:0023DF* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:0023E0* ID_OUI_FROM_DATABASE=INO Therapeutics LLC @@ -40643,10 +40727,10 @@ OUI:0023EC* ID_OUI_FROM_DATABASE=Algorithmix GmbH OUI:0023ED* - ID_OUI_FROM_DATABASE=Motorola CHS + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:0023EE* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:0023EF* ID_OUI_FROM_DATABASE=Zuend Systemtechnik AG @@ -40853,7 +40937,7 @@ OUI:002435* ID_OUI_FROM_DATABASE=WIDE CORPORATION OUI:002436* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:002437* ID_OUI_FROM_DATABASE=Motorola - BSG @@ -41126,13 +41210,13 @@ OUI:002492* ID_OUI_FROM_DATABASE=Motorola, Broadband Solutions Group OUI:002493* - ID_OUI_FROM_DATABASE=Motorola, Inc + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:002494* ID_OUI_FROM_DATABASE=Shenzhen Baoxin Tech CO., Ltd. OUI:002495* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:002496* ID_OUI_FROM_DATABASE=Ginzinger electronic systems @@ -41165,10 +41249,10 @@ OUI:00249F* ID_OUI_FROM_DATABASE=RIM Testing Services OUI:0024A0* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:0024A1* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:0024A2* ID_OUI_FROM_DATABASE=Hong Kong Middleware Technology Limited @@ -41264,7 +41348,7 @@ OUI:0024C0* ID_OUI_FROM_DATABASE=NTI COMODO INC OUI:0024C1* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:0024C2* ID_OUI_FROM_DATABASE=Asumo Co.,Ltd. @@ -41450,7 +41534,7 @@ OUI:0024FF* ID_OUI_FROM_DATABASE=QLogic Corporation OUI:002500* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:002501* ID_OUI_FROM_DATABASE=JSC "Supertel" @@ -41669,7 +41753,7 @@ OUI:00254A* ID_OUI_FROM_DATABASE=RingCube Technologies, Inc. OUI:00254B* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:00254C* ID_OUI_FROM_DATABASE=Videon Central, Inc. @@ -42005,7 +42089,7 @@ OUI:0025BB* ID_OUI_FROM_DATABASE=INNERINT Co., Ltd. OUI:0025BC* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:0025BD* ID_OUI_FROM_DATABASE=Italdata Ingegneria dell'Idea S.p.A. @@ -42161,10 +42245,10 @@ OUI:0025F0* ID_OUI_FROM_DATABASE=Suga Electronics Limited OUI:0025F1* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:0025F2* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:0025F3* ID_OUI_FROM_DATABASE=Nordwestdeutsche Zählerrevision @@ -42227,7 +42311,7 @@ OUI:002607* ID_OUI_FROM_DATABASE=Enabling Technology Pty Ltd OUI:002608* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:002609* ID_OUI_FROM_DATABASE=Phyllis Co., Ltd. @@ -42365,7 +42449,7 @@ OUI:002635* ID_OUI_FROM_DATABASE=Bluetechnix GmbH OUI:002636* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:002637* ID_OUI_FROM_DATABASE=Samsung Electro-Mechanics @@ -42398,10 +42482,10 @@ OUI:002640* ID_OUI_FROM_DATABASE=Baustem Broadband Technologies, Ltd. OUI:002641* - ID_OUI_FROM_DATABASE=Motorola, Inc + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:002642* - ID_OUI_FROM_DATABASE=Motorola, Inc + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:002643* ID_OUI_FROM_DATABASE=Alps Electric Co., Ltd @@ -42422,7 +42506,7 @@ OUI:002648* ID_OUI_FROM_DATABASE=Emitech Corp. OUI:00264A* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:00264C* ID_OUI_FROM_DATABASE=Shanghai DigiVision Technology Co., Ltd. @@ -42722,7 +42806,7 @@ OUI:0026AF* ID_OUI_FROM_DATABASE=Duelco A/S OUI:0026B0* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:0026B1* ID_OUI_FROM_DATABASE=Navis Auto Motive Systems, Inc. @@ -42752,10 +42836,10 @@ OUI:0026B9* ID_OUI_FROM_DATABASE=Dell Inc OUI:0026BA* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:0026BB* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:0026BC* ID_OUI_FROM_DATABASE=General Jack Technology Ltd. @@ -43382,7 +43466,7 @@ OUI:003064* ID_OUI_FROM_DATABASE=ADLINK TECHNOLOGY, INC. OUI:003065* - ID_OUI_FROM_DATABASE=APPLE COMPUTER, INC. + ID_OUI_FROM_DATABASE=Apple OUI:003066* ID_OUI_FROM_DATABASE=RFM @@ -43892,7 +43976,7 @@ OUI:003D41* ID_OUI_FROM_DATABASE=Hatteland Computer AS OUI:003EE1* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:004000* ID_OUI_FROM_DATABASE=PCI COMPONENTES DA AMZONIA LTD @@ -44405,7 +44489,7 @@ OUI:0040A9* ID_OUI_FROM_DATABASE=DATACOM INC. OUI:0040AA* - ID_OUI_FROM_DATABASE=VALMET AUTOMATION INC. + ID_OUI_FROM_DATABASE=Metso Automation OUI:0040AB* ID_OUI_FROM_DATABASE=ROLAND DG CORPORATION @@ -45311,10 +45395,10 @@ OUI:0050E2* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. OUI:0050E3* - ID_OUI_FROM_DATABASE=Motorola, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:0050E4* - ID_OUI_FROM_DATABASE=APPLE COMPUTER, INC. + ID_OUI_FROM_DATABASE=Apple OUI:0050E6* ID_OUI_FROM_DATABASE=HAKUSAN CORPORATION @@ -46195,6 +46279,12 @@ OUI:0070B0* OUI:0070B3* ID_OUI_FROM_DATABASE=DATA RECALL LTD. +OUI:00738D* + ID_OUI_FROM_DATABASE=Tinno Mobile Technology Corp + +OUI:0073E0* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:0075E1* ID_OUI_FROM_DATABASE=Ampt, LLC @@ -47465,7 +47555,7 @@ OUI:00909B* ID_OUI_FROM_DATABASE=MARKEM-IMAJE OUI:00909C* - ID_OUI_FROM_DATABASE=Motorola, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:00909D* ID_OUI_FROM_DATABASE=NovaTech Process Solutions, LLC @@ -47747,7 +47837,7 @@ OUI:0090F9* ID_OUI_FROM_DATABASE=LEITCH OUI:0090FA* - ID_OUI_FROM_DATABASE=EMULEX Corp + ID_OUI_FROM_DATABASE=Emulex Corporation OUI:0090FB* ID_OUI_FROM_DATABASE=PORTWELL, INC. @@ -47978,7 +48068,7 @@ OUI:00A03F* ID_OUI_FROM_DATABASE=COMPUTER SOCIETY MICROPROCESSOR & MICROPROCESSOR STANDARDS C OUI:00A040* - ID_OUI_FROM_DATABASE=APPLE COMPUTER + ID_OUI_FROM_DATABASE=Apple OUI:00A041* ID_OUI_FROM_DATABASE=INFICON @@ -49496,7 +49586,7 @@ OUI:00C5DB* ID_OUI_FROM_DATABASE=Datatech Sistemas Digitales Avanzados SL OUI:00C610* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:00CBBD* ID_OUI_FROM_DATABASE=Cambridge Broadband Networks Ltd. @@ -49916,7 +50006,7 @@ OUI:00D087* ID_OUI_FROM_DATABASE=MICROFIRST INC. OUI:00D088* - ID_OUI_FROM_DATABASE=Motorola, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:00D089* ID_OUI_FROM_DATABASE=DYNACOLOR, INC. @@ -50678,7 +50768,7 @@ OUI:00E06E* ID_OUI_FROM_DATABASE=FAR SYSTEMS S.p.A. OUI:00E06F* - ID_OUI_FROM_DATABASE=Motorola, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:00E070* ID_OUI_FROM_DATABASE=DH TECHNOLOGY @@ -50960,7 +51050,7 @@ OUI:00E0CC* ID_OUI_FROM_DATABASE=HERO SYSTEMS, LTD. OUI:00E0CD* - ID_OUI_FROM_DATABASE=SENSIS CORPORATION + ID_OUI_FROM_DATABASE=SAAB SENSIS CORPORATION OUI:00E0CE* ID_OUI_FROM_DATABASE=ARN @@ -51137,7 +51227,7 @@ OUI:00F403* ID_OUI_FROM_DATABASE=Orbis Systems Oy OUI:00F4B9* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:00F860* ID_OUI_FROM_DATABASE=PT. Panggung Electric Citrabuana @@ -51200,7 +51290,7 @@ OUI:040AE0* ID_OUI_FROM_DATABASE=XMIT AG COMPUTER NETWORKS OUI:040CCE* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:040EC2* ID_OUI_FROM_DATABASE=ViewSonic Mobile China Limited @@ -51214,6 +51304,9 @@ OUI:04180F* OUI:0418D6* ID_OUI_FROM_DATABASE=Ubiquiti Networks +OUI:041A04* + ID_OUI_FROM_DATABASE=WaveIP + OUI:041B94* ID_OUI_FROM_DATABASE=Host Mobility AB @@ -51224,7 +51317,7 @@ OUI:041D10* ID_OUI_FROM_DATABASE=Dream Ware Inc. OUI:041E64* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:04209A* ID_OUI_FROM_DATABASE=Panasonic AVC Networks Company @@ -51272,7 +51365,7 @@ OUI:044FAA* ID_OUI_FROM_DATABASE=Ruckus Wireless OUI:045453* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:0455CA* ID_OUI_FROM_DATABASE=BriView (Xiamen) Corp. @@ -51391,6 +51484,9 @@ OUI:04C5A4* OUI:04C880* ID_OUI_FROM_DATABASE=Samtec Inc +OUI:04CB1D* + ID_OUI_FROM_DATABASE=Traka plc + OUI:04CE14* ID_OUI_FROM_DATABASE=Wilocity LTD. @@ -51406,6 +51502,9 @@ OUI:04D783* OUI:04DAD2* ID_OUI_FROM_DATABASE=Cisco +OUI:04DB56* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:04DD4C* ID_OUI_FROM_DATABASE=Velocytech @@ -51482,7 +51581,7 @@ OUI:080006* ID_OUI_FROM_DATABASE=SIEMENS AG OUI:080007* - ID_OUI_FROM_DATABASE=APPLE COMPUTER INC. + ID_OUI_FROM_DATABASE=Apple OUI:080008* ID_OUI_FROM_DATABASE=BOLT BERANEK AND NEWMAN INC. @@ -51991,6 +52090,9 @@ OUI:084EBF* OUI:08512E* ID_OUI_FROM_DATABASE=Orion Diagnostica Oy +OUI:085240* + ID_OUI_FROM_DATABASE=EbV Elektronikbau- und Vertriebs GmbH + OUI:085B0E* ID_OUI_FROM_DATABASE=Fortinet, Inc. @@ -52057,6 +52159,9 @@ OUI:088F2C* OUI:0896D7* ID_OUI_FROM_DATABASE=AVM GmbH +OUI:089758* + ID_OUI_FROM_DATABASE=Shenzhen Strong Rising Electronics Co.,Ltd DongGuan Subsidiary + OUI:089E01* ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC. @@ -52093,6 +52198,9 @@ OUI:08BD43* OUI:08BE09* ID_OUI_FROM_DATABASE=Astrol Electronic AG +OUI:08CA45* + ID_OUI_FROM_DATABASE=Toyou Feiji Electronics Co., Ltd. + OUI:08CC68* ID_OUI_FROM_DATABASE=Cisco @@ -52193,7 +52301,7 @@ OUI:0C2D89* ID_OUI_FROM_DATABASE=QiiQ Communications Inc. OUI:0C3021* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:0C37DC* ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd @@ -52214,7 +52322,7 @@ OUI:0C4C39* ID_OUI_FROM_DATABASE=Mitrastar Technology OUI:0C4DE9* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:0C51F7* ID_OUI_FROM_DATABASE=CHAUVIN ARNOUX @@ -52250,13 +52358,13 @@ OUI:0C722C* ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. OUI:0C74C2* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:0C7523* ID_OUI_FROM_DATABASE=BEIJING GEHUA CATV NETWORK CO.,LTD OUI:0C771A* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:0C7D7C* ID_OUI_FROM_DATABASE=Kexiang Information Technology Co, Ltd. @@ -52282,6 +52390,9 @@ OUI:0C84DC* OUI:0C8525* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. +OUI:0C8910* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,LTD + OUI:0C8BFD* ID_OUI_FROM_DATABASE=Intel Corporate @@ -52360,6 +52471,9 @@ OUI:0CC81F* OUI:0CC9C6* ID_OUI_FROM_DATABASE=Samwin Hong Kong Limited +OUI:0CCB8D* + ID_OUI_FROM_DATABASE=ASCO Numatics GmbH + OUI:0CCDD3* ID_OUI_FROM_DATABASE=EASTRIVER TECHNOLOGY CO., LTD. @@ -52513,6 +52627,9 @@ OUI:102D96* OUI:102EAF* ID_OUI_FROM_DATABASE=Texas Instruments +OUI:103378* + ID_OUI_FROM_DATABASE=FLECTRON Co., LTD + OUI:103711* ID_OUI_FROM_DATABASE=Simlink AS @@ -52523,7 +52640,7 @@ OUI:103DEA* ID_OUI_FROM_DATABASE=HFC Technology (Beijing) Ltd. Co. OUI:1040F3* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:104369* ID_OUI_FROM_DATABASE=Soundmax Electronic Limited @@ -52619,13 +52736,13 @@ OUI:108CCF* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. OUI:1093E9* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:109AB9* ID_OUI_FROM_DATABASE=Tosibox Oy OUI:109ADD* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:109FA9* ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc @@ -52639,6 +52756,9 @@ OUI:10A743* OUI:10A932* ID_OUI_FROM_DATABASE=Beijing Cyber Cloud Technology Co. ,Ltd. +OUI:10B26B* + ID_OUI_FROM_DATABASE=base Co.,Ltd. + OUI:10B7F6* ID_OUI_FROM_DATABASE=Plastoform Industries Ltd. @@ -52739,7 +52859,7 @@ OUI:140D4F* ID_OUI_FROM_DATABASE=Flextronics International OUI:14109F* - ID_OUI_FROM_DATABASE=Apple Inc + ID_OUI_FROM_DATABASE=Apple OUI:141330* ID_OUI_FROM_DATABASE=Anakreon UK LLP @@ -52811,10 +52931,10 @@ OUI:145412* ID_OUI_FROM_DATABASE=Entis Co., Ltd. OUI:145A05* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:145BD1* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:146080* ID_OUI_FROM_DATABASE=zte corporation @@ -52850,7 +52970,7 @@ OUI:148A70* ID_OUI_FROM_DATABASE=ADS GmbH OUI:148FC6* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:149090* ID_OUI_FROM_DATABASE=KongTop industrial(shen zhen)CO.,LTD @@ -52885,6 +53005,9 @@ OUI:14B73D* OUI:14C21D* ID_OUI_FROM_DATABASE=Sabtech Industries +OUI:14CC20* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD + OUI:14CF8D* ID_OUI_FROM_DATABASE=OHSUNG ELECTRONICS CO., LTD. @@ -52954,6 +53077,9 @@ OUI:180675* OUI:180B52* ID_OUI_FROM_DATABASE=Nanotron Technologies GmbH +OUI:180C14* + ID_OUI_FROM_DATABASE=iSonea Limited + OUI:180C77* ID_OUI_FROM_DATABASE=Westinghouse Electric Company, LLC @@ -52978,11 +53104,14 @@ OUI:181725* OUI:18193F* ID_OUI_FROM_DATABASE=Tamtron Oy +OUI:181BEB* + ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc + OUI:181EB0* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd OUI:182032* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:182666* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd @@ -53006,7 +53135,7 @@ OUI:18339D* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. OUI:183451* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:1836FC* ID_OUI_FROM_DATABASE=Elecsys International Corporation @@ -53059,6 +53188,9 @@ OUI:185AE8* OUI:18622C* ID_OUI_FROM_DATABASE=SAGEMCOM SAS +OUI:186472* + ID_OUI_FROM_DATABASE=Aruba Networks + OUI:1866E3* ID_OUI_FROM_DATABASE=Veros Systems, Inc. @@ -53117,7 +53249,7 @@ OUI:189A67* ID_OUI_FROM_DATABASE=CSE-Servelec Limited OUI:189EFC* - ID_OUI_FROM_DATABASE=Apple Inc + ID_OUI_FROM_DATABASE=Apple OUI:18A905* ID_OUI_FROM_DATABASE=Hewlett-Packard Company @@ -53125,6 +53257,9 @@ OUI:18A905* OUI:18A99B* ID_OUI_FROM_DATABASE=Dell Inc PCBA Test +OUI:18AA45* + ID_OUI_FROM_DATABASE=Fon Japan K. K. + OUI:18ABF5* ID_OUI_FROM_DATABASE=Ultra Electronics - Electrics @@ -53134,6 +53269,9 @@ OUI:18AD4D* OUI:18AEBB* ID_OUI_FROM_DATABASE=Siemens Convergence Creators GmbH&Co.KG +OUI:18AF61* + ID_OUI_FROM_DATABASE=Apple, Inc + OUI:18AF8F* ID_OUI_FROM_DATABASE=Apple @@ -53161,6 +53299,9 @@ OUI:18C086* OUI:18C451* ID_OUI_FROM_DATABASE=Tucson Embedded Systems +OUI:18C8E7* + ID_OUI_FROM_DATABASE=Shenzhen Hualistone Technology Co.,Ltd + OUI:18D071* ID_OUI_FROM_DATABASE=DASAN SMC, Inc. @@ -53183,7 +53324,7 @@ OUI:18E2C2* ID_OUI_FROM_DATABASE=Samsung Electronics OUI:18E7F4* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:18E80F* ID_OUI_FROM_DATABASE=Viking Electronics Inc. @@ -53231,7 +53372,7 @@ OUI:1C129D* ID_OUI_FROM_DATABASE=IEEE PES PSRC/SUB OUI:1C1448* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:1C17D3* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. @@ -53311,6 +53452,9 @@ OUI:1C5FFF* OUI:1C62B8* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +OUI:1C63B7* + ID_OUI_FROM_DATABASE=OpenProducts 237 AB + OUI:1C659D* ID_OUI_FROM_DATABASE=Liteon Technology Corporation @@ -53390,7 +53534,7 @@ OUI:1CAA07* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. OUI:1CABA7* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:1CAF05* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd @@ -53419,6 +53563,9 @@ OUI:1CBD0E* OUI:1CBDB9* ID_OUI_FROM_DATABASE=D-LINK INTERNATIONAL PTE LIMITED +OUI:1CC11A* + ID_OUI_FROM_DATABASE=Wavetronix + OUI:1CC1DE* ID_OUI_FROM_DATABASE=Hewlett-Packard Company @@ -53648,7 +53795,7 @@ OUI:20C8B3* ID_OUI_FROM_DATABASE=SHENZHEN BUL-TECH CO.,LTD. OUI:20C9D0* - ID_OUI_FROM_DATABASE=Apple Inc + ID_OUI_FROM_DATABASE=Apple OUI:20CD39* ID_OUI_FROM_DATABASE=Texas Instruments, Inc @@ -53659,6 +53806,12 @@ OUI:20CEC4* OUI:20CF30* ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. +OUI:20D21F* + ID_OUI_FROM_DATABASE=Wincal Technology Corp. + +OUI:20D390* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:20D5AB* ID_OUI_FROM_DATABASE=Korea Infocom Co.,Ltd. @@ -53684,7 +53837,10 @@ OUI:20E52A* ID_OUI_FROM_DATABASE=NETGEAR INC., OUI:20E564* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +OUI:20E791* + ID_OUI_FROM_DATABASE=Siemens Healthcare Diagnostics, Inc OUI:20EEC6* ID_OUI_FROM_DATABASE=Elefirst Science & Tech Co ., ltd @@ -53809,6 +53965,9 @@ OUI:2486F4* OUI:248707* ID_OUI_FROM_DATABASE=SEnergy Corporation +OUI:2493CA* + ID_OUI_FROM_DATABASE=Voxtronic Technology Computer-Systeme GmbH + OUI:249442* ID_OUI_FROM_DATABASE=OPEN ROAD SOLUTIONS , INC. @@ -53821,11 +53980,14 @@ OUI:24A42C* OUI:24A43C* ID_OUI_FROM_DATABASE=Ubiquiti Networks, INC +OUI:24A495* + ID_OUI_FROM_DATABASE=Thales Canada Inc. + OUI:24A937* ID_OUI_FROM_DATABASE=PURE Storage OUI:24AB81* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:24AF4A* ID_OUI_FROM_DATABASE=Alcatel-Lucent-IPD @@ -53866,6 +54028,9 @@ OUI:24C0B3* OUI:24C696* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +OUI:24C848* + ID_OUI_FROM_DATABASE=mywerk system GmbH + OUI:24C86E* ID_OUI_FROM_DATABASE=Chaney Instrument Co. @@ -53899,6 +54064,9 @@ OUI:24DBAD* OUI:24DEC6* ID_OUI_FROM_DATABASE=Aruba Networks +OUI:24E271* + ID_OUI_FROM_DATABASE=Qingdao Hisense Communications Co.,Ltd + OUI:24E6BA* ID_OUI_FROM_DATABASE=JSC Zavod im. Kozitsky @@ -53939,7 +54107,7 @@ OUI:28068D* ID_OUI_FROM_DATABASE=ITL, LLC OUI:280B5C* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:280CB8* ID_OUI_FROM_DATABASE=Mikrosay Yazilim ve Elektronik A.S. @@ -53984,7 +54152,7 @@ OUI:283410* ID_OUI_FROM_DATABASE=Enigma Diagnostics Limited OUI:283737* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:2838CF* ID_OUI_FROM_DATABASE=Gen2wave @@ -54001,6 +54169,9 @@ OUI:28401A* OUI:284121* ID_OUI_FROM_DATABASE=OptiSense Network, LLC +OUI:284430* + ID_OUI_FROM_DATABASE=GenesisTechnical Systems (UK) Ltd + OUI:2847AA* ID_OUI_FROM_DATABASE=Nokia Corporation @@ -54019,6 +54190,9 @@ OUI:284FCE* OUI:285132* ID_OUI_FROM_DATABASE=Shenzhen Prayfly Technology Co.,Ltd +OUI:285767* + ID_OUI_FROM_DATABASE=Echostar Technologies Corp + OUI:285FDB* ID_OUI_FROM_DATABASE=Shenzhen Huawei Communication Technologies Co., Ltd @@ -54029,10 +54203,10 @@ OUI:286094* ID_OUI_FROM_DATABASE=CAPELEC OUI:286AB8* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:286ABA* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:286D97* ID_OUI_FROM_DATABASE=SAMJIN Co., Ltd. @@ -54058,6 +54232,9 @@ OUI:28852D* OUI:288915* ID_OUI_FROM_DATABASE=CashGuard Sverige AB +OUI:288A1C* + ID_OUI_FROM_DATABASE=Juniper networks + OUI:2891D0* ID_OUI_FROM_DATABASE=Stage Tec Entwicklungsgesellschaft für professionelle Audiotechnik mbH @@ -54152,7 +54329,7 @@ OUI:28CD9C* ID_OUI_FROM_DATABASE=Shenzhen Dynamax Software Development Co.,Ltd. OUI:28CFDA* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:28CFE9* ID_OUI_FROM_DATABASE=Apple @@ -54176,6 +54353,9 @@ OUI:28DB81* ID_OUI_FROM_DATABASE=Shanghai Guao Electronic Technology Co., Ltd OUI:28E02C* + ID_OUI_FROM_DATABASE=Apple + +OUI:28E14C* ID_OUI_FROM_DATABASE=Apple, Inc. OUI:28E297* @@ -54188,7 +54368,7 @@ OUI:28E794* ID_OUI_FROM_DATABASE=Microtime Computer Inc. OUI:28E7CF* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:28ED58* ID_OUI_FROM_DATABASE=JAG Jakob AG @@ -54208,6 +54388,9 @@ OUI:28F606* OUI:28FBD3* ID_OUI_FROM_DATABASE=Ragentek Technology Group +OUI:28FC51* + ID_OUI_FROM_DATABASE=The Electric Controller and Manufacturing Co., LLC + OUI:2C002C* ID_OUI_FROM_DATABASE=UNOWHY @@ -54223,6 +54406,9 @@ OUI:2C0623* OUI:2C10C1* ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. +OUI:2C18AE* + ID_OUI_FROM_DATABASE=Trend Electronics Co., Ltd. + OUI:2C1984* ID_OUI_FROM_DATABASE=IDN Telecom, Inc. @@ -54262,6 +54448,9 @@ OUI:2C36A0* OUI:2C36F8* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. +OUI:2C3731* + ID_OUI_FROM_DATABASE=ShenZhen Yifang Digital Technology Co.,LTD + OUI:2C3996* ID_OUI_FROM_DATABASE=SAGEMCOM @@ -54301,6 +54490,9 @@ OUI:2C59E5* OUI:2C5AA3* ID_OUI_FROM_DATABASE=PROMATE ELECTRONIC CO.LTD +OUI:2C5D93* + ID_OUI_FROM_DATABASE=Ruckus Wireless + OUI:2C5FF3* ID_OUI_FROM_DATABASE=Pertronic Industries @@ -54362,7 +54554,7 @@ OUI:2C9717* ID_OUI_FROM_DATABASE=I.C.Y. B.V. OUI:2C9E5F* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:2C9EFC* ID_OUI_FROM_DATABASE=CANON INC. @@ -54541,6 +54733,9 @@ OUI:304C7E* OUI:304EC3* ID_OUI_FROM_DATABASE=Tianjin Techua Technology Co., Ltd. +OUI:3051F8* + ID_OUI_FROM_DATABASE=BYK-Gardner GmbH + OUI:30525A* ID_OUI_FROM_DATABASE=NST Co., LTD @@ -54613,6 +54808,9 @@ OUI:3090AB* OUI:3092F6* ID_OUI_FROM_DATABASE=SHANGHAI SUNMON COMMUNICATION TECHNOGY CO.,LTD +OUI:309BAD* + ID_OUI_FROM_DATABASE=BBK Electronics Corp., Ltd., + OUI:30AABD* ID_OUI_FROM_DATABASE=Shanghai Reallytek Information Technology Co.,Ltd @@ -54686,7 +54884,7 @@ OUI:3413E8* ID_OUI_FROM_DATABASE=Intel Corporate OUI:34159E* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:341A4C* ID_OUI_FROM_DATABASE=SHENZHEN WEIBU ELECTRONICS CO.,LTD. @@ -54697,6 +54895,9 @@ OUI:341B22* OUI:342109* ID_OUI_FROM_DATABASE=Jensen Scandinavia AS +OUI:342387* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + OUI:3423BA* ID_OUI_FROM_DATABASE=Samsung Electro Mechanics co.,LTD. @@ -54725,7 +54926,7 @@ OUI:344F69* ID_OUI_FROM_DATABASE=EKINOPS SAS OUI:3451C9* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:345B11* ID_OUI_FROM_DATABASE=EVI HEAT AB @@ -54805,6 +55006,9 @@ OUI:34A3BF* OUI:34A55D* ID_OUI_FROM_DATABASE=TECHNOSOFT INTERNATIONAL SRL +OUI:34A5E1* + ID_OUI_FROM_DATABASE=Sensorist ApS + OUI:34A68C* ID_OUI_FROM_DATABASE=Shine Profit Development Limited @@ -55037,7 +55241,7 @@ OUI:386793* ID_OUI_FROM_DATABASE=Asia Optical Co., Inc. OUI:386BBB* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:386E21* ID_OUI_FROM_DATABASE=Wasion Group Ltd. @@ -55066,6 +55270,9 @@ OUI:389592* OUI:389F83* ID_OUI_FROM_DATABASE=OTN Systems N.V. +OUI:38A53C* + ID_OUI_FROM_DATABASE=Veenstra Instruments + OUI:38A5B6* ID_OUI_FROM_DATABASE=SHENZHEN MEGMEET ELECTRICAL CO.,LTD @@ -55087,6 +55294,9 @@ OUI:38B12D* OUI:38B5BD* ID_OUI_FROM_DATABASE=E.G.O. Elektro-Ger +OUI:38B74D* + ID_OUI_FROM_DATABASE=Fijowave Limited + OUI:38BB23* ID_OUI_FROM_DATABASE=OzVision America LLC @@ -55108,6 +55318,9 @@ OUI:38C85C* OUI:38D135* ID_OUI_FROM_DATABASE=EasyIO Corporation Sdn. Bhd. +OUI:38DBBB* + ID_OUI_FROM_DATABASE=Sunbow Telecom Co., Ltd. + OUI:38DE60* ID_OUI_FROM_DATABASE=Mohlenhoff GmbH @@ -55157,7 +55370,7 @@ OUI:3C05AB* ID_OUI_FROM_DATABASE=Product Creation Studio OUI:3C0754* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:3C0771* ID_OUI_FROM_DATABASE=Sony Corporation @@ -55171,12 +55384,18 @@ OUI:3C096D* OUI:3C0FC1* ID_OUI_FROM_DATABASE=KBC Networks +OUI:3C1040* + ID_OUI_FROM_DATABASE=daesung network + OUI:3C106F* ID_OUI_FROM_DATABASE=ALBAHITH TECHNOLOGIES OUI:3C15EA* ID_OUI_FROM_DATABASE=TESCOM CO., LTD. +OUI:3C18A0* + ID_OUI_FROM_DATABASE=Luxshare Precision Industry Co.,Ltd. + OUI:3C1915* ID_OUI_FROM_DATABASE=GFI Chrono Time @@ -55220,7 +55439,7 @@ OUI:3C404F* ID_OUI_FROM_DATABASE=Guangdong Pisen Electronics Co. Ltd. OUI:3C438E* - ID_OUI_FROM_DATABASE=Motorola Mobility, LLC. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:3C4A92* ID_OUI_FROM_DATABASE=Hewlett-Packard Company @@ -55258,6 +55477,9 @@ OUI:3C672C* OUI:3C6A7D* ID_OUI_FROM_DATABASE=Niigata Power Systems Co., Ltd. +OUI:3C6E63* + ID_OUI_FROM_DATABASE=Mitron OY + OUI:3C6F45* ID_OUI_FROM_DATABASE=Fiberpro Inc. @@ -55271,7 +55493,7 @@ OUI:3C7437* ID_OUI_FROM_DATABASE=RIM OUI:3C754A* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:3C77E6* ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. @@ -55357,11 +55579,14 @@ OUI:3CC243* OUI:3CC99E* ID_OUI_FROM_DATABASE=Huiyang Technology Co., Ltd +OUI:3CCA87* + ID_OUI_FROM_DATABASE=Iders Incorporated + OUI:3CCE73* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. OUI:3CD0F8* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:3CD16E* ID_OUI_FROM_DATABASE=Telepower Communication Co., Ltd @@ -55402,6 +55627,9 @@ OUI:3CF52C* OUI:3CF72A* ID_OUI_FROM_DATABASE=Nokia Corporation +OUI:3CF748* + ID_OUI_FROM_DATABASE=Shenzhen Linsn Technology Development Co.,Ltd + OUI:3CFB96* ID_OUI_FROM_DATABASE=Emcraft Systems LLC @@ -55460,7 +55688,7 @@ OUI:402CF4* ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd. OUI:403004* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:40336C* ID_OUI_FROM_DATABASE=Godrej & Boyce Mfg. co. ltd @@ -55469,7 +55697,7 @@ OUI:4037AD* ID_OUI_FROM_DATABASE=Macro Image Technology, Inc. OUI:403CFC* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:404022* ID_OUI_FROM_DATABASE=ZIV @@ -55526,17 +55754,23 @@ OUI:406AAB* ID_OUI_FROM_DATABASE=RIM OUI:406C8F* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:406F2A* ID_OUI_FROM_DATABASE=Research In Motion +OUI:407009* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + OUI:40704A* ID_OUI_FROM_DATABASE=Power Idea Technology Limited OUI:407074* ID_OUI_FROM_DATABASE=Life Technology (China) Co., Ltd +OUI:407496* + ID_OUI_FROM_DATABASE=aFUN TECHNOLOGY INC. + OUI:407A80* ID_OUI_FROM_DATABASE=Nokia Corporation @@ -55583,7 +55817,7 @@ OUI:40A6A4* ID_OUI_FROM_DATABASE=PassivSystems Ltd OUI:40A6D9* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:40AC8D* ID_OUI_FROM_DATABASE=Data Management, Inc. @@ -55604,7 +55838,7 @@ OUI:40B4F0* ID_OUI_FROM_DATABASE=Juniper Networks OUI:40B7F3* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:40BA61* ID_OUI_FROM_DATABASE=Arima Communications Corp. @@ -55637,7 +55871,7 @@ OUI:40CD3A* ID_OUI_FROM_DATABASE=Z3 Technology OUI:40D32D* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:40D40E* ID_OUI_FROM_DATABASE=Biodata Ltd @@ -55676,7 +55910,7 @@ OUI:40F52E* ID_OUI_FROM_DATABASE=Leica Microsystems (Schweiz) AG OUI:40FC89* - ID_OUI_FROM_DATABASE=Motorola Mobility, LLC. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:4403A7* ID_OUI_FROM_DATABASE=Cisco @@ -55703,7 +55937,7 @@ OUI:4425BB* ID_OUI_FROM_DATABASE=Bamboo Entertainment Corporation OUI:442A60* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:442AFF* ID_OUI_FROM_DATABASE=E3 Technology, Inc. @@ -55711,6 +55945,9 @@ OUI:442AFF* OUI:442B03* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. +OUI:443192* + ID_OUI_FROM_DATABASE=Hewlett Packard + OUI:44322A* ID_OUI_FROM_DATABASE=Avaya, Inc @@ -55748,7 +55985,7 @@ OUI:444A65* ID_OUI_FROM_DATABASE=Silverflare Ltd. OUI:444C0C* - ID_OUI_FROM_DATABASE=Apple Inc + ID_OUI_FROM_DATABASE=Apple OUI:444E1A* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd @@ -55801,6 +56038,9 @@ OUI:446D57* OUI:44700B* ID_OUI_FROM_DATABASE=IFFU +OUI:447BC4* + ID_OUI_FROM_DATABASE=DualShine Technology(SZ)Co.,Ltd + OUI:447C7F* ID_OUI_FROM_DATABASE=Innolight Technology Corporation @@ -55819,6 +56059,9 @@ OUI:448500* OUI:4487FC* ID_OUI_FROM_DATABASE=ELITEGROUP COMPUTER SYSTEM CO., LTD. +OUI:448A5B* + ID_OUI_FROM_DATABASE=Micro-Star INT'L CO., LTD. + OUI:448C52* ID_OUI_FROM_DATABASE=KTIS CO., Ltd @@ -55895,7 +56138,7 @@ OUI:44D832* ID_OUI_FROM_DATABASE=Azurewave Technologies, Inc. OUI:44D884* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:44DC91* ID_OUI_FROM_DATABASE=PLANEX COMMUNICATIONS INC. @@ -55918,6 +56161,9 @@ OUI:44E8A5* OUI:44ED57* ID_OUI_FROM_DATABASE=Longicorn, inc. +OUI:44EE30* + ID_OUI_FROM_DATABASE=Budelmann Elektronik GmbH + OUI:44F459* ID_OUI_FROM_DATABASE=Samsung Electronics @@ -55966,6 +56212,9 @@ OUI:4844F7* OUI:4846F1* ID_OUI_FROM_DATABASE=Uros Oy +OUI:4846FB* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + OUI:485261* ID_OUI_FROM_DATABASE=SOREEL @@ -55979,7 +56228,7 @@ OUI:485D60* ID_OUI_FROM_DATABASE=Azurewave Technologies, Inc. OUI:4860BC* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:4861A3* ID_OUI_FROM_DATABASE=Concern "Axion" JSC @@ -56170,6 +56419,9 @@ OUI:4C3910* OUI:4C3B74* ID_OUI_FROM_DATABASE=VOGTEC(H.K.) Co., Ltd +OUI:4C3C16* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:4C4B68* ID_OUI_FROM_DATABASE=Mobile Device, Inc. @@ -56282,11 +56534,14 @@ OUI:4CB16C* ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD OUI:4CB199* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:4CB4EA* ID_OUI_FROM_DATABASE=HRD (S) PTE., LTD. +OUI:4CB81C* + ID_OUI_FROM_DATABASE=SAM Electronics GmbH + OUI:4CB9C8* ID_OUI_FROM_DATABASE=CONET CO., LTD. @@ -56329,6 +56584,9 @@ OUI:4CEB42* OUI:4CEDDE* ID_OUI_FROM_DATABASE=Askey Computer Corp +OUI:4CF02E* + ID_OUI_FROM_DATABASE=Vifa Denmark A/S + OUI:4CF737* ID_OUI_FROM_DATABASE=SamJi Electronics Co., Ltd @@ -56356,6 +56614,9 @@ OUI:5011EB* OUI:5017FF* ID_OUI_FROM_DATABASE=Cisco +OUI:50206B* + ID_OUI_FROM_DATABASE=Emerson Climate Technologies Transportation Solutions + OUI:502267* ID_OUI_FROM_DATABASE=PixeLINK @@ -56383,6 +56644,9 @@ OUI:502DA2* OUI:502DF4* ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH +OUI:502E5C* + ID_OUI_FROM_DATABASE=HTC Corporation + OUI:502ECE* ID_OUI_FROM_DATABASE=Asahi Electronics Co.,Ltd @@ -56518,6 +56782,9 @@ OUI:50B888* OUI:50B8A2* ID_OUI_FROM_DATABASE=ImTech Technologies LLC, +OUI:50C006* + ID_OUI_FROM_DATABASE=Carmanah Signs + OUI:50C271* ID_OUI_FROM_DATABASE=SECURETECH INC @@ -56527,6 +56794,9 @@ OUI:50C58D* OUI:50C971* ID_OUI_FROM_DATABASE=GN Netcom A/S +OUI:50C9A0* + ID_OUI_FROM_DATABASE=SKIPPER Electronics AS + OUI:50CCF8* ID_OUI_FROM_DATABASE=Samsung Electro Mechanics @@ -56542,15 +56812,21 @@ OUI:50D274* OUI:50D6D7* ID_OUI_FROM_DATABASE=Takahata Precision +OUI:50E0C7* + ID_OUI_FROM_DATABASE=TurControlSystme AG + OUI:50E549* ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD. OUI:50EAD6* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:50EB1A* ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. +OUI:50ED78* + ID_OUI_FROM_DATABASE=Changzhou Yongse Infotech Co.,Ltd + OUI:50ED94* ID_OUI_FROM_DATABASE=Egatel SL @@ -56617,6 +56893,9 @@ OUI:542A9C* OUI:542CEA* ID_OUI_FROM_DATABASE=PROTECTRON +OUI:542F89* + ID_OUI_FROM_DATABASE=Euclid Laboratories, Inc. + OUI:543131* ID_OUI_FROM_DATABASE=Raster Vision Ltd @@ -56695,6 +56974,9 @@ OUI:548998* OUI:5492BE* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +OUI:549359* + ID_OUI_FROM_DATABASE=SHENZHEN TWOWING TECHNOLOGIES CO.,LTD. + OUI:549478* ID_OUI_FROM_DATABASE=Silvershore Technology Partners @@ -56749,6 +57031,9 @@ OUI:54E032* OUI:54E3B0* ID_OUI_FROM_DATABASE=JVL Industri Elektronik +OUI:54E43A* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:54E63F* ID_OUI_FROM_DATABASE=ShenZhen LingKeWeiEr Technology Co., Ltd. @@ -56795,7 +57080,7 @@ OUI:581D91* ID_OUI_FROM_DATABASE=Advanced Mobile Telecom co.,ltd. OUI:581FAA* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:581FEF* ID_OUI_FROM_DATABASE=Tuttnaer LTD @@ -56843,10 +57128,10 @@ OUI:5850E6* ID_OUI_FROM_DATABASE=Best Buy Corporation OUI:5855CA* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:5856E8* - ID_OUI_FROM_DATABASE=Motorola Mobility Inc + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:58570D* ID_OUI_FROM_DATABASE=Danfoss Solar Inverters @@ -56933,7 +57218,7 @@ OUI:58A76F* ID_OUI_FROM_DATABASE=iD corporation OUI:58B035* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:58B0D4* ID_OUI_FROM_DATABASE=ZuniData Systems Inc. @@ -57031,6 +57316,9 @@ OUI:5C0CBB* OUI:5C0E8B* ID_OUI_FROM_DATABASE=Motorola +OUI:5C1193* + ID_OUI_FROM_DATABASE=Seal One AG + OUI:5C1437* ID_OUI_FROM_DATABASE=Thyssenkrupp Aufzugswerke GmbH @@ -57076,6 +57364,9 @@ OUI:5C353B* OUI:5C35DA* ID_OUI_FROM_DATABASE=There Corporation Oy +OUI:5C36B8* + ID_OUI_FROM_DATABASE=TCL King Electrical Appliances (Huizhou) Ltd. + OUI:5C38E0* ID_OUI_FROM_DATABASE=Shanghai Super Electronics Technology Co.,LTD @@ -57110,7 +57401,7 @@ OUI:5C57C8* ID_OUI_FROM_DATABASE=Nokia Corporation OUI:5C5948* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:5C5EAB* ID_OUI_FROM_DATABASE=Juniper Networks @@ -57152,7 +57443,7 @@ OUI:5C89D4* ID_OUI_FROM_DATABASE=Beijing Banner Electric Co.,Ltd OUI:5C95AE* - ID_OUI_FROM_DATABASE=Apple Inc + ID_OUI_FROM_DATABASE=Apple OUI:5C969D* ID_OUI_FROM_DATABASE=Apple @@ -57253,12 +57544,18 @@ OUI:5CF6DC* OUI:5CF8A1* ID_OUI_FROM_DATABASE=Murata Manufactuaring Co.,Ltd. +OUI:5CF938* + ID_OUI_FROM_DATABASE=Apple, Inc + OUI:5CF9DD* ID_OUI_FROM_DATABASE=Dell Inc OUI:5CFF35* ID_OUI_FROM_DATABASE=Wistron Corporation +OUI:5CFFFF* + ID_OUI_FROM_DATABASE=Shenzhen Kezhonglong Optoelectronic Technology Co., Ltd + OUI:6002B4* ID_OUI_FROM_DATABASE=Wistron NeWeb Corp. @@ -57302,7 +57599,7 @@ OUI:6032F0* ID_OUI_FROM_DATABASE=Mplus technology OUI:60334B* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:603553* ID_OUI_FROM_DATABASE=Buwon Technology @@ -57355,6 +57652,9 @@ OUI:6064A1* OUI:606720* ID_OUI_FROM_DATABASE=Intel Corporate +OUI:606944* + ID_OUI_FROM_DATABASE=Apple, Inc + OUI:60699B* ID_OUI_FROM_DATABASE=isepos GmbH @@ -57446,7 +57746,7 @@ OUI:60C397* ID_OUI_FROM_DATABASE=2Wire Inc OUI:60C547* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:60C5A8* ID_OUI_FROM_DATABASE=Beijing LT Honway Technology Co.,Ltd @@ -57478,6 +57778,9 @@ OUI:60D819* OUI:60DA23* ID_OUI_FROM_DATABASE=Estech Co.,Ltd +OUI:60DB2A* + ID_OUI_FROM_DATABASE=HNS + OUI:60DE44* ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD @@ -57512,10 +57815,10 @@ OUI:60F673* ID_OUI_FROM_DATABASE=TERUMO CORPORATION OUI:60FACD* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:60FB42* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:60FE1E* ID_OUI_FROM_DATABASE=China Palms Telecom.Ltd @@ -57566,7 +57869,7 @@ OUI:641E81* ID_OUI_FROM_DATABASE=Dowslake Microsystems OUI:64200C* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:642184* ID_OUI_FROM_DATABASE=Nippon Denki Kagaku Co.,LTD @@ -57592,6 +57895,9 @@ OUI:64317E* OUI:643409* ID_OUI_FROM_DATABASE=BITwave Pte Ltd +OUI:643F5F* + ID_OUI_FROM_DATABASE=Exablaze + OUI:644214* ID_OUI_FROM_DATABASE=Swisscom Energy Solutions AG @@ -57628,6 +57934,9 @@ OUI:645563* OUI:64557F* ID_OUI_FROM_DATABASE=NSFOCUS Information Technology Co., Ltd. +OUI:645601* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD + OUI:645A04* ID_OUI_FROM_DATABASE=Chicony Electronics Co., Ltd. @@ -57764,7 +58073,10 @@ OUI:64B64A* ID_OUI_FROM_DATABASE=ViVOtech, Inc. OUI:64B9E8* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple + +OUI:64BABD* + ID_OUI_FROM_DATABASE=SDJ Technologies, Inc. OUI:64BC11* ID_OUI_FROM_DATABASE=CombiQ AB @@ -57821,7 +58133,7 @@ OUI:64E599* ID_OUI_FROM_DATABASE=EFM Networks OUI:64E682* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:64E84F* ID_OUI_FROM_DATABASE=Serialway Communication Technology Co. Ltd @@ -57829,8 +58141,11 @@ OUI:64E84F* OUI:64E8E6* ID_OUI_FROM_DATABASE=global moisture management system +OUI:64E950* + ID_OUI_FROM_DATABASE=Cisco + OUI:64ED57* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:64ED62* ID_OUI_FROM_DATABASE=WOORI SYSTEMS Co., Ltd @@ -57854,7 +58169,10 @@ OUI:6805CA* ID_OUI_FROM_DATABASE=Intel Corporate OUI:680927* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple + +OUI:680AD7* + ID_OUI_FROM_DATABASE=Yancheng Kecheng Optoelectronic Technology Co., Ltd OUI:68122D* ID_OUI_FROM_DATABASE=Special Instrument Development Co., Ltd. @@ -57923,7 +58241,7 @@ OUI:68597F* ID_OUI_FROM_DATABASE=Alcatel Lucent OUI:685B35* - ID_OUI_FROM_DATABASE=Apple inc + ID_OUI_FROM_DATABASE=Apple OUI:685B36* ID_OUI_FROM_DATABASE=POWERTECH INDUSTRIAL CO., LTD. @@ -57937,6 +58255,9 @@ OUI:685E6B* OUI:686359* ID_OUI_FROM_DATABASE=Advanced Digital Broadcast SA +OUI:68692E* + ID_OUI_FROM_DATABASE=Zycoo Co.,Ltd + OUI:6869F2* ID_OUI_FROM_DATABASE=ComAp s.r.o. @@ -57946,6 +58267,9 @@ OUI:686E23* OUI:687251* ID_OUI_FROM_DATABASE=Ubiquiti Networks +OUI:68764F* + ID_OUI_FROM_DATABASE=Sony Mobile Communications AB + OUI:68784C* ID_OUI_FROM_DATABASE=Nortel Networks @@ -57979,6 +58303,9 @@ OUI:6886E7* OUI:68876B* ID_OUI_FROM_DATABASE=INQ Mobile Limited +OUI:688AB5* + ID_OUI_FROM_DATABASE=EDP Servicos + OUI:689234* ID_OUI_FROM_DATABASE=Ruckus Wireless @@ -57986,7 +58313,7 @@ OUI:689423* ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. OUI:68967B* - ID_OUI_FROM_DATABASE=Apple Inc + ID_OUI_FROM_DATABASE=Apple OUI:68974B* ID_OUI_FROM_DATABASE=Shenzhen Costar Electronics Co. Ltd. @@ -58010,7 +58337,7 @@ OUI:68A40E* ID_OUI_FROM_DATABASE=BSH Bosch and Siemens Home Appliances GmbH OUI:68A86D* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:68AAD2* ID_OUI_FROM_DATABASE=DATECS LTD., @@ -58099,6 +58426,9 @@ OUI:68F895* OUI:68FB95* ID_OUI_FROM_DATABASE=Generalplus Technology Inc. +OUI:68FCB3* + ID_OUI_FROM_DATABASE=Next Level Security Systems, Inc. + OUI:6C0460* ID_OUI_FROM_DATABASE=RBH Access Technologies Inc. @@ -58108,6 +58438,9 @@ OUI:6C0E0D* OUI:6C0F6A* ID_OUI_FROM_DATABASE=JDC Tech Co., Ltd. +OUI:6C15F9* + ID_OUI_FROM_DATABASE=Nautronix Limited + OUI:6C1811* ID_OUI_FROM_DATABASE=Decatur Electronics @@ -58145,7 +58478,7 @@ OUI:6C3BE5* ID_OUI_FROM_DATABASE=Hewlett Packard OUI:6C3E6D* - ID_OUI_FROM_DATABASE=Apple Inc + ID_OUI_FROM_DATABASE=Apple OUI:6C3E9C* ID_OUI_FROM_DATABASE=KE Knestel Elektronik GmbH @@ -58156,6 +58489,9 @@ OUI:6C40C6* OUI:6C416A* ID_OUI_FROM_DATABASE=Cisco +OUI:6C4B7F* + ID_OUI_FROM_DATABASE=Vossloh-Schwabe Deutschland GmbH + OUI:6C504D* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. @@ -58222,6 +58558,9 @@ OUI:6C90B1* OUI:6C92BF* ID_OUI_FROM_DATABASE=Inspur Electronic Information Industry Co.,Ltd. +OUI:6C98EB* + ID_OUI_FROM_DATABASE=Xyne GmbH + OUI:6C9AC9* ID_OUI_FROM_DATABASE=Valentine Research, Inc. @@ -58277,10 +58616,10 @@ OUI:6CBEE9* ID_OUI_FROM_DATABASE=Alcatel-Lucent-IPD OUI:6CC1D2* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:6CC26B* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:6CD032* ID_OUI_FROM_DATABASE=LG Electronics @@ -58366,6 +58705,9 @@ OUI:701A04* OUI:701AED* ID_OUI_FROM_DATABASE=ADVAS CO., LTD. +OUI:701D7F* + ID_OUI_FROM_DATABASE=Comtech Technology Co., Ltd. + OUI:702393* ID_OUI_FROM_DATABASE=fos4X GmbH @@ -58387,6 +58729,9 @@ OUI:702F97* OUI:703018* ID_OUI_FROM_DATABASE=Avaya, Inc +OUI:70305E* + ID_OUI_FROM_DATABASE=Nanjing Zhongke Menglian Information Technology Co.,LTD + OUI:703187* ID_OUI_FROM_DATABASE=ACX GmbH @@ -58426,6 +58771,9 @@ OUI:704CED* OUI:7052C5* ID_OUI_FROM_DATABASE=Avaya, Inc. +OUI:70533F* + ID_OUI_FROM_DATABASE=Alfa Instrumentos Eletronicos Ltda. + OUI:7054D2* ID_OUI_FROM_DATABASE=PEGATRON CORPORATION @@ -58433,7 +58781,7 @@ OUI:7054F5* ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD OUI:705681* - ID_OUI_FROM_DATABASE=Apple Inc + ID_OUI_FROM_DATABASE=Apple OUI:705812* ID_OUI_FROM_DATABASE=Panasonic AVC Networks Company @@ -58441,6 +58789,9 @@ OUI:705812* OUI:705957* ID_OUI_FROM_DATABASE=Medallion Instrumentation Systems +OUI:705986* + ID_OUI_FROM_DATABASE=OOO TTV + OUI:705AB6* ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD. @@ -58450,6 +58801,9 @@ OUI:705CAD* OUI:705EAA* ID_OUI_FROM_DATABASE=Action Target, Inc. +OUI:7060DE* + ID_OUI_FROM_DATABASE=LaVision GmbH + OUI:706173* ID_OUI_FROM_DATABASE=Calantec GmbH @@ -58472,7 +58826,7 @@ OUI:7072CF* ID_OUI_FROM_DATABASE=EdgeCore Networks OUI:7073CB* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:707630* ID_OUI_FROM_DATABASE=Pace plc. @@ -58487,7 +58841,7 @@ OUI:707BE8* ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD OUI:707E43* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:707EDE* ID_OUI_FROM_DATABASE=NASTEC LTD. @@ -58501,9 +58855,15 @@ OUI:70820E* OUI:70828E* ID_OUI_FROM_DATABASE=OleumTech Corporation +OUI:7085C6* + ID_OUI_FROM_DATABASE=Pace plc. + OUI:708B78* ID_OUI_FROM_DATABASE=citygrow technology co., ltd +OUI:708D09* + ID_OUI_FROM_DATABASE=Nokia Corporation + OUI:7093F8* ID_OUI_FROM_DATABASE=Space Monkey, Inc. @@ -58565,7 +58925,7 @@ OUI:70CA9B* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. OUI:70CD60* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:70D4F2* ID_OUI_FROM_DATABASE=RIM @@ -58586,7 +58946,7 @@ OUI:70DDA1* ID_OUI_FROM_DATABASE=Tellabs OUI:70DEE2* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:70E027* ID_OUI_FROM_DATABASE=HONGYU COMMUNICATION TECHNOLOGY LIMITED @@ -58621,6 +58981,9 @@ OUI:70F395* OUI:70F927* ID_OUI_FROM_DATABASE=Samsung Electronics +OUI:70FF76* + ID_OUI_FROM_DATABASE=Texas Instruments + OUI:740ABC* ID_OUI_FROM_DATABASE=JSJS Designs (Europe) Limited @@ -58688,7 +59051,7 @@ OUI:745327* ID_OUI_FROM_DATABASE=COMMSEN CO., LIMITED OUI:745612* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:745798* ID_OUI_FROM_DATABASE=TRUMPF Laser GmbH + Co. KG @@ -58826,10 +59189,10 @@ OUI:74E06E* ID_OUI_FROM_DATABASE=Ergophone GmbH OUI:74E1B6* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:74E2F5* - ID_OUI_FROM_DATABASE=Apple Inc + ID_OUI_FROM_DATABASE=Apple OUI:74E424* ID_OUI_FROM_DATABASE=APISTE CORPORATION @@ -58844,7 +59207,7 @@ OUI:74E543* ID_OUI_FROM_DATABASE=Liteon Technology Corporation OUI:74E7C6* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:74EA3A* ID_OUI_FROM_DATABASE=TP-LINK Technologies Co.,Ltd. @@ -58862,7 +59225,7 @@ OUI:74F102* ID_OUI_FROM_DATABASE=Beijing HCHCOM Technology Co., Ltd OUI:74F612* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:74F726* ID_OUI_FROM_DATABASE=Neuron Robotics @@ -58936,6 +59299,9 @@ OUI:78324F* OUI:783CE3* ID_OUI_FROM_DATABASE=Kai-EE +OUI:783D5B* + ID_OUI_FROM_DATABASE=TELNET Redes Inteligentes S.A. + OUI:783F15* ID_OUI_FROM_DATABASE=EasySYNC Ltd. @@ -59057,7 +59423,7 @@ OUI:78A2A0* ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. OUI:78A3E4* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:78A5DD* ID_OUI_FROM_DATABASE=Shenzhen Smarteye Digital Electronics Co., Ltd @@ -59114,7 +59480,7 @@ OUI:78CA04* ID_OUI_FROM_DATABASE=Nokia Corporation OUI:78CA39* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:78CB33* ID_OUI_FROM_DATABASE=DHC Software Co.,Ltd @@ -59143,6 +59509,9 @@ OUI:78D6F0* OUI:78D99F* ID_OUI_FROM_DATABASE=NuCom HK Ltd. +OUI:78DA6E* + ID_OUI_FROM_DATABASE=Cisco + OUI:78DAB3* ID_OUI_FROM_DATABASE=GBO Technology @@ -59216,7 +59585,7 @@ OUI:7C0623* ID_OUI_FROM_DATABASE=Ultra Electronics, CIS OUI:7C08D9* - ID_OUI_FROM_DATABASE=Shanghai Engineering Research Center for Broadband Technologies and Applications + ID_OUI_FROM_DATABASE=Shanghai B-Star Technology Co OUI:7C092B* ID_OUI_FROM_DATABASE=Bekey A/S @@ -59225,7 +59594,7 @@ OUI:7C0A50* ID_OUI_FROM_DATABASE=J-MEX Inc. OUI:7C11BE* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:7C1476* ID_OUI_FROM_DATABASE=Damall Technologies SAS @@ -59302,9 +59671,15 @@ OUI:7C6097* OUI:7C6193* ID_OUI_FROM_DATABASE=HTC Corporation +OUI:7C669D* + ID_OUI_FROM_DATABASE=Texas Instruments + OUI:7C69F6* ID_OUI_FROM_DATABASE=Cisco +OUI:7C6AB3* + ID_OUI_FROM_DATABASE=IBC TECHNOLOGIES INC. + OUI:7C6ADB* ID_OUI_FROM_DATABASE=SafeTone Technology Co.,Ltd @@ -59321,7 +59696,7 @@ OUI:7C6C8F* ID_OUI_FROM_DATABASE=AMS NEVE LTD OUI:7C6D62* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:7C6F06* ID_OUI_FROM_DATABASE=Caterpillar Trimble Control Technologies @@ -59398,14 +59773,17 @@ OUI:7CBB6F* OUI:7CBD06* ID_OUI_FROM_DATABASE=AE REFUsol +OUI:7CBF88* + ID_OUI_FROM_DATABASE=Mobilicom LTD + OUI:7CBFB1* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:7CC3A1* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:7CC537* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:7CC8AB* ID_OUI_FROM_DATABASE=Acro Associates, Inc. @@ -59419,11 +59797,14 @@ OUI:7CC8D7* OUI:7CCB0D* ID_OUI_FROM_DATABASE=Antaira Technologies, LLC +OUI:7CCD3C* + ID_OUI_FROM_DATABASE=Guangzhou Juzing Technology Co., Ltd + OUI:7CCFCF* ID_OUI_FROM_DATABASE=Shanghai SEARI Intelligent System Co., Ltd OUI:7CD1C3* - ID_OUI_FROM_DATABASE=Apple Inc + ID_OUI_FROM_DATABASE=Apple OUI:7CD762* ID_OUI_FROM_DATABASE=Freestyle Technology Pty Ltd @@ -59468,7 +59849,7 @@ OUI:7CEF8A* ID_OUI_FROM_DATABASE=Inhon International Ltd. OUI:7CF05F* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:7CF098* ID_OUI_FROM_DATABASE=Bee Beans Technologies, Inc. @@ -59560,8 +59941,11 @@ OUI:80427C* OUI:804731* ID_OUI_FROM_DATABASE=Packet Design, Inc. +OUI:8048A5* + ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOM CO.,LTD + OUI:804971* - ID_OUI_FROM_DATABASE=Apple Inc + ID_OUI_FROM_DATABASE=Apple OUI:804B20* ID_OUI_FROM_DATABASE=Ventilation Control @@ -59572,6 +59956,12 @@ OUI:804F58* OUI:80501B* ID_OUI_FROM_DATABASE=Nokia Corporation +OUI:8056F2* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:805719* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:8058C5* ID_OUI_FROM_DATABASE=NovaTec Kommunikationstechnik GmbH @@ -59645,7 +60035,7 @@ OUI:80946C* ID_OUI_FROM_DATABASE=TOKYO RADAR CORPORATION OUI:8096B1* - ID_OUI_FROM_DATABASE=Motorola Mobility, LLC. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:80971B* ID_OUI_FROM_DATABASE=Altenergy Power System,Inc. @@ -59716,6 +60106,9 @@ OUI:80DB31* OUI:80EE73* ID_OUI_FROM_DATABASE=Shuttle Inc. +OUI:80F25E* + ID_OUI_FROM_DATABASE=Kyynel + OUI:80F593* ID_OUI_FROM_DATABASE=IRCO Sistemas de Telecomunicación S.A. @@ -59777,7 +60170,7 @@ OUI:842914* ID_OUI_FROM_DATABASE=EMPORIA TELECOM Produktions- und VertriebsgesmbH & Co KG OUI:842999* - ID_OUI_FROM_DATABASE=Apple Inc + ID_OUI_FROM_DATABASE=Apple OUI:842B2B* ID_OUI_FROM_DATABASE=Dell Inc. @@ -59818,6 +60211,9 @@ OUI:844915* OUI:844BF5* ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. +OUI:844F03* + ID_OUI_FROM_DATABASE=Ablelink Electronics Ltd + OUI:845181* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd @@ -59845,6 +60241,9 @@ OUI:846EB1* OUI:84742A* ID_OUI_FROM_DATABASE=zte corporation +OUI:847616* + ID_OUI_FROM_DATABASE=Addat S.r.o. + OUI:8478AC* ID_OUI_FROM_DATABASE=Cisco @@ -59861,7 +60260,7 @@ OUI:848371* ID_OUI_FROM_DATABASE=Avaya, Inc OUI:848506* - ID_OUI_FROM_DATABASE=Apple Inc + ID_OUI_FROM_DATABASE=Apple OUI:848D84* ID_OUI_FROM_DATABASE=Rajant Corporation @@ -60016,6 +60415,9 @@ OUI:883612* OUI:8841C1* ID_OUI_FROM_DATABASE=ORBISAT DA AMAZONIA IND E AEROL SA +OUI:8841FC* + ID_OUI_FROM_DATABASE=AirTies Wireless Netowrks + OUI:8843E1* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. @@ -60067,6 +60469,9 @@ OUI:887556* OUI:88789C* ID_OUI_FROM_DATABASE=Game Technologies SA +OUI:888603* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + OUI:8886A0* ID_OUI_FROM_DATABASE=Simton Technologies, Ltd. @@ -60085,6 +60490,9 @@ OUI:888B5D* OUI:888C19* ID_OUI_FROM_DATABASE=Brady Corp Asia Pacific Ltd +OUI:889166* + ID_OUI_FROM_DATABASE=Viewcooper Corp. + OUI:8891DD* ID_OUI_FROM_DATABASE=Racktivity @@ -60137,7 +60545,7 @@ OUI:88C36E* ID_OUI_FROM_DATABASE=Beijing Ereneben lnformation Technology Limited OUI:88C663* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:88CB87* ID_OUI_FROM_DATABASE=Apple @@ -60193,6 +60601,9 @@ OUI:8C078C* OUI:8C088B* ID_OUI_FROM_DATABASE=Remote Solution +OUI:8C09F4* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + OUI:8C0C90* ID_OUI_FROM_DATABASE=Ruckus Wireless @@ -60218,7 +60629,7 @@ OUI:8C278A* ID_OUI_FROM_DATABASE=Vocollect Inc OUI:8C2DAA* - ID_OUI_FROM_DATABASE=Apple Inc + ID_OUI_FROM_DATABASE=Apple OUI:8C2F39* ID_OUI_FROM_DATABASE=IBA Dosimetry GmbH @@ -60263,7 +60674,7 @@ OUI:8C57FD* ID_OUI_FROM_DATABASE=LVX Western OUI:8C5877* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:8C598B* ID_OUI_FROM_DATABASE=C Technologies AB @@ -60311,7 +60722,7 @@ OUI:8C7716* ID_OUI_FROM_DATABASE=LONGCHEER TELECOMMUNICATION LIMITED OUI:8C7B9D* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:8C7CB5* ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. @@ -60352,9 +60763,15 @@ OUI:8CA982* OUI:8CAE4C* ID_OUI_FROM_DATABASE=Plugable Technologies +OUI:8CAE89* + ID_OUI_FROM_DATABASE=Y-cam Solutions Ltd + OUI:8CB64F* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. +OUI:8CB7F7* + ID_OUI_FROM_DATABASE=Shenzhen UniStrong Science & Technology Co., Ltd + OUI:8CB82C* ID_OUI_FROM_DATABASE=IPitomy Communications @@ -60419,7 +60836,7 @@ OUI:8CF9C9* ID_OUI_FROM_DATABASE=MESADA Technology Co.,Ltd. OUI:8CFABA* - ID_OUI_FROM_DATABASE=Apple Inc + ID_OUI_FROM_DATABASE=Apple OUI:8CFDF0* ID_OUI_FROM_DATABASE=QUALCOMM Incorporated @@ -60430,6 +60847,9 @@ OUI:90004E* OUI:90013B* ID_OUI_FROM_DATABASE=SAGEMCOM +OUI:90028A* + ID_OUI_FROM_DATABASE=Shenzhen Shidean Legrand Electronic Products Co.,Ltd + OUI:9002A9* ID_OUI_FROM_DATABASE=ZHEJIANG DAHUA TECHNOLOGY CO.,LTD @@ -60460,6 +60880,9 @@ OUI:9018AE* OUI:901900* ID_OUI_FROM_DATABASE=SCS SA +OUI:901ACA* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + OUI:901B0E* ID_OUI_FROM_DATABASE=Fujitsu Technology Solutions GmbH @@ -60476,7 +60899,7 @@ OUI:902155* ID_OUI_FROM_DATABASE=HTC Corporation OUI:9027E4* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:902B34* ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD. @@ -60490,6 +60913,9 @@ OUI:90342B* OUI:9034FC* ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. +OUI:90356E* + ID_OUI_FROM_DATABASE=Vodafone Omnitel N.V. + OUI:9038DF* ID_OUI_FROM_DATABASE=Changzhou Tiannengbo System Co. Ltd. @@ -60590,7 +61016,7 @@ OUI:908260* ID_OUI_FROM_DATABASE=IEEE 1904.1 Working Group OUI:90840D* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:9088A2* ID_OUI_FROM_DATABASE=IONICS TECHNOLOGY ME LTDA @@ -60601,6 +61027,9 @@ OUI:908C44* OUI:908D1D* ID_OUI_FROM_DATABASE=GH Technologies +OUI:908F93* + ID_OUI_FROM_DATABASE=MakerBot Industries + OUI:908FCF* ID_OUI_FROM_DATABASE=UNO System Co., Ltd @@ -60644,7 +61073,7 @@ OUI:90B11C* ID_OUI_FROM_DATABASE=Dell Inc. OUI:90B134* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:90B21F* ID_OUI_FROM_DATABASE=Apple @@ -60703,6 +61132,9 @@ OUI:90EA60* OUI:90F278* ID_OUI_FROM_DATABASE=Radius Gateway +OUI:90F3B7* + ID_OUI_FROM_DATABASE=Kirisun Communications Co., Ltd. + OUI:90F4C1* ID_OUI_FROM_DATABASE=Rand McNally @@ -60781,6 +61213,9 @@ OUI:9439E5* OUI:943AF0* ID_OUI_FROM_DATABASE=Nokia Corporation +OUI:943BB1* + ID_OUI_FROM_DATABASE=KAONMEDIA + OUI:9440A2* ID_OUI_FROM_DATABASE=Anywave Communication Technologies, Inc. @@ -60829,6 +61264,12 @@ OUI:9481A4* OUI:94857A* ID_OUI_FROM_DATABASE=Evantage Industries Corp +OUI:9486D4* + ID_OUI_FROM_DATABASE=Surveillance Pro Corporation + +OUI:94877C* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + OUI:948854* ID_OUI_FROM_DATABASE=Texas Instruments @@ -60871,6 +61312,9 @@ OUI:94AE61* OUI:94B8C5* ID_OUI_FROM_DATABASE=RuggedCom Inc. +OUI:94B9B4* + ID_OUI_FROM_DATABASE=Aptos Technology + OUI:94BA31* ID_OUI_FROM_DATABASE=Visiontec da Amazônia Ltda. @@ -60880,6 +61324,12 @@ OUI:94BA56* OUI:94BF1E* ID_OUI_FROM_DATABASE=eflow Inc. / Smart Device Planning and Development Division +OUI:94C150* + ID_OUI_FROM_DATABASE=2Wire Inc + +OUI:94C3E4* + ID_OUI_FROM_DATABASE=SCA Schucker Gmbh & Co KG + OUI:94C4E9* ID_OUI_FROM_DATABASE=PowerLayer Microsystems HongKong Limited @@ -60896,7 +61346,7 @@ OUI:94CA0F* ID_OUI_FROM_DATABASE=Honeywell Analytics OUI:94CCB9* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:94CDAC* ID_OUI_FROM_DATABASE=Creowave Oy @@ -60949,6 +61399,12 @@ OUI:94E711* OUI:94E848* ID_OUI_FROM_DATABASE=FYLDE MICRO LTD +OUI:94E98C* + ID_OUI_FROM_DATABASE=Alcatel-Lucent + +OUI:94EB2C* + ID_OUI_FROM_DATABASE=Google Inc. + OUI:94EBCD* ID_OUI_FROM_DATABASE=Research In Motion Limited @@ -60977,7 +61433,7 @@ OUI:9803A0* ID_OUI_FROM_DATABASE=ABB n.v. Power Quality Products OUI:9803D8* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:980C82* ID_OUI_FROM_DATABASE=Samsung Electro Mechanics @@ -61027,6 +61483,9 @@ OUI:983F9F* OUI:984246* ID_OUI_FROM_DATABASE=SOL INDUSTRY PTE., LTD +OUI:9843DA* + ID_OUI_FROM_DATABASE=INTERTECH + OUI:98473C* ID_OUI_FROM_DATABASE=SHANGHAI SUNMON COMMUNICATION TECHNOGY CO.,LTD @@ -61034,7 +61493,7 @@ OUI:984A47* ID_OUI_FROM_DATABASE=CHG Hospital Beds OUI:984B4A* - ID_OUI_FROM_DATABASE=Motorola Mobility, LLC. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:984BE1* ID_OUI_FROM_DATABASE=Hewlett-Packard Company @@ -61154,7 +61613,7 @@ OUI:98D686* ID_OUI_FROM_DATABASE=Chyi Lee industry Co., ltd. OUI:98D6BB* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:98D6F7* ID_OUI_FROM_DATABASE=LG Electronics @@ -61183,6 +61642,9 @@ OUI:98F8C1* OUI:98F8DB* ID_OUI_FROM_DATABASE=Marini Impianti Industriali s.r.l. +OUI:98FB12* + ID_OUI_FROM_DATABASE=Grand Electronics (HK) Ltd + OUI:98FC11* ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC @@ -61190,7 +61652,7 @@ OUI:98FE03* ID_OUI_FROM_DATABASE=Ericsson - North America OUI:98FE94* - ID_OUI_FROM_DATABASE=Apple Inc + ID_OUI_FROM_DATABASE=Apple OUI:9C0111* ID_OUI_FROM_DATABASE=Shenzhen Newabel Electronic Co., Ltd. @@ -61198,6 +61660,9 @@ OUI:9C0111* OUI:9C0298* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +OUI:9C039E* + ID_OUI_FROM_DATABASE=Beijing Winchannel Software Technology Co., Ltd + OUI:9C0473* ID_OUI_FROM_DATABASE=Tecmobile (International) Ltd. @@ -61223,7 +61688,10 @@ OUI:9C1FDD* ID_OUI_FROM_DATABASE=Accupix Inc. OUI:9C207B* - ID_OUI_FROM_DATABASE=Apple Inc + ID_OUI_FROM_DATABASE=Apple + +OUI:9C216A* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. OUI:9C220E* ID_OUI_FROM_DATABASE=TASCAN Service GmbH @@ -61330,6 +61798,9 @@ OUI:9C7BD2* OUI:9C807D* ID_OUI_FROM_DATABASE=SYSCABLE Korea Inc. +OUI:9C8888* + ID_OUI_FROM_DATABASE=Simac Techniek NV + OUI:9C8BF1* ID_OUI_FROM_DATABASE=The Warehouse Limited @@ -61369,6 +61840,9 @@ OUI:9CA3BA* OUI:9CA577* ID_OUI_FROM_DATABASE=Osorno Enterprises Inc. +OUI:9CA9E4* + ID_OUI_FROM_DATABASE=zte corporation + OUI:9CADEF* ID_OUI_FROM_DATABASE=Obihai Technology, Inc. @@ -61417,6 +61891,9 @@ OUI:9CD24B* OUI:9CD36D* ID_OUI_FROM_DATABASE=NETGEAR INC., +OUI:9CD643* + ID_OUI_FROM_DATABASE=D-Link International + OUI:9CDF03* ID_OUI_FROM_DATABASE=Harman/Becker Automotive Systems GmbH @@ -61516,6 +61993,9 @@ OUI:A036FA* OUI:A03A75* ID_OUI_FROM_DATABASE=PSS Belgium N.V. +OUI:A03B1B* + ID_OUI_FROM_DATABASE=Inspire Tech + OUI:A04025* ID_OUI_FROM_DATABASE=Actioncable, Inc. @@ -61639,6 +62119,9 @@ OUI:A09BBD* OUI:A0A130* ID_OUI_FROM_DATABASE=DLI Taiwan Branch office +OUI:A0A23C* + ID_OUI_FROM_DATABASE=GPMS + OUI:A0A763* ID_OUI_FROM_DATABASE=Polytron Vertrieb GmbH @@ -61708,6 +62191,9 @@ OUI:A0E295* OUI:A0E534* ID_OUI_FROM_DATABASE=Stratec Biomedical AG +OUI:A0E5E9* + ID_OUI_FROM_DATABASE=enimai Inc + OUI:A0E9DB* ID_OUI_FROM_DATABASE=Ningbo FreeWings Technologies Co.,Ltd @@ -61744,6 +62230,9 @@ OUI:A0FE91* OUI:A40130* ID_OUI_FROM_DATABASE=ABIsystems Co., LTD +OUI:A4059E* + ID_OUI_FROM_DATABASE=STA Infinity LLP + OUI:A40BED* ID_OUI_FROM_DATABASE=Carry Technology Co.,Ltd @@ -61832,7 +62321,7 @@ OUI:A45D36* ID_OUI_FROM_DATABASE=Hewlett Packard OUI:A46706* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:A46E79* ID_OUI_FROM_DATABASE=DFT System Co.Ltd @@ -61841,7 +62330,7 @@ OUI:A479E4* ID_OUI_FROM_DATABASE=KLINFO Corp OUI:A47AA4* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:A47ACF* ID_OUI_FROM_DATABASE=VIBICOM COMMUNICATIONS INC. @@ -61901,7 +62390,7 @@ OUI:A4B121* ID_OUI_FROM_DATABASE=Arantia 2010 S.L. OUI:A4B197* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:A4B1E9* ID_OUI_FROM_DATABASE=Technicolor @@ -61952,7 +62441,7 @@ OUI:A4D1D1* ID_OUI_FROM_DATABASE=ECOtality North America OUI:A4D1D2* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:A4D3B5* ID_OUI_FROM_DATABASE=GLITEL Stropkov, s.r.o. @@ -61966,6 +62455,9 @@ OUI:A4DA3F* OUI:A4DB2E* ID_OUI_FROM_DATABASE=Kingspan Environmental Ltd +OUI:A4DB30* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + OUI:A4DE50* ID_OUI_FROM_DATABASE=Total Walther GmbH @@ -61978,6 +62470,9 @@ OUI:A4E32E* OUI:A4E391* ID_OUI_FROM_DATABASE=DENY FONTAINE +OUI:A4E4B8* + ID_OUI_FROM_DATABASE=BlackBerry Limited + OUI:A4E731* ID_OUI_FROM_DATABASE=Nokia Corporation @@ -61987,11 +62482,14 @@ OUI:A4E7E4* OUI:A4E991* ID_OUI_FROM_DATABASE=SISTEMAS AUDIOVISUALES ITELSIS S.L. +OUI:A4E9A3* + ID_OUI_FROM_DATABASE=Honest Technology Co., Ltd + OUI:A4EBD3* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd OUI:A4ED4E* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:A4EE57* ID_OUI_FROM_DATABASE=SEIKO EPSON CORPORATION @@ -62036,7 +62534,7 @@ OUI:A81FAF* ID_OUI_FROM_DATABASE=KRYPTON POLSKA OUI:A82066* - ID_OUI_FROM_DATABASE=Apple Inc + ID_OUI_FROM_DATABASE=Apple OUI:A826D9* ID_OUI_FROM_DATABASE=HTC Corporation @@ -62125,6 +62623,9 @@ OUI:A88808* OUI:A88CEE* ID_OUI_FROM_DATABASE=MicroMade Galka i Drozdz sp.j. +OUI:A88D7B* + ID_OUI_FROM_DATABASE=SunDroid Global limited. + OUI:A8922C* ID_OUI_FROM_DATABASE=LG Electronics @@ -62159,7 +62660,7 @@ OUI:A8B1D4* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. OUI:A8BBCF* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:A8BD1A* ID_OUI_FROM_DATABASE=Honey Bee (Hong Kong) Limited @@ -62386,6 +62887,9 @@ OUI:AC8317* OUI:AC83F0* ID_OUI_FROM_DATABASE=ImmediaTV Corporation +OUI:AC853D* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + OUI:AC8674* ID_OUI_FROM_DATABASE=Open Mesh, Inc. @@ -62560,6 +63064,9 @@ OUI:B03850* OUI:B0435D* ID_OUI_FROM_DATABASE=NuLEDs, Inc. +OUI:B04545* + ID_OUI_FROM_DATABASE=YACOUB Automation GmbH + OUI:B046FC* ID_OUI_FROM_DATABASE=MitraStar Technology Corp. @@ -62588,7 +63095,7 @@ OUI:B06563* ID_OUI_FROM_DATABASE=Shanghai Railway Communication Factory OUI:B065BD* - ID_OUI_FROM_DATABASE=Apple Inc + ID_OUI_FROM_DATABASE=Apple OUI:B06CBF* ID_OUI_FROM_DATABASE=3ality Digital Systems GmbH @@ -62600,7 +63107,10 @@ OUI:B075D5* ID_OUI_FROM_DATABASE=ZTE Corporation OUI:B077AC* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +OUI:B07908* + ID_OUI_FROM_DATABASE=Cummings Engineering OUI:B0793C* ID_OUI_FROM_DATABASE=Revolv Inc @@ -62713,6 +63223,9 @@ OUI:B0D09C* OUI:B0D2F5* ID_OUI_FROM_DATABASE=Vello Systems, Inc. +OUI:B0DF3A* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:B0E39D* ID_OUI_FROM_DATABASE=CAT SYSTEM CO.,LTD. @@ -62782,6 +63295,9 @@ OUI:B4211D* OUI:B4218A* ID_OUI_FROM_DATABASE=Dog Hunter LLC +OUI:B424E7* + ID_OUI_FROM_DATABASE=Codetek Technology Co.,Ltd + OUI:B428F1* ID_OUI_FROM_DATABASE=E-Prime Co., Ltd. @@ -62830,6 +63346,9 @@ OUI:B45253* OUI:B4527D* ID_OUI_FROM_DATABASE=Sony Mobile Communications AB +OUI:B4527E* + ID_OUI_FROM_DATABASE=Sony Mobile Communications AB + OUI:B45570* ID_OUI_FROM_DATABASE=Borea @@ -62866,6 +63385,9 @@ OUI:B47F5E* OUI:B48255* ID_OUI_FROM_DATABASE=Research Products Corporation +OUI:B4827B* + ID_OUI_FROM_DATABASE=AKG Acoustics GmbH + OUI:B482C5* ID_OUI_FROM_DATABASE=Relay2, Inc. @@ -63002,10 +63524,10 @@ OUI:B81413* ID_OUI_FROM_DATABASE=Keen High Holding(HK) Ltd. OUI:B81619* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:B817C2* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:B81999* ID_OUI_FROM_DATABASE=Nesys @@ -63134,7 +63656,7 @@ OUI:B88A60* ID_OUI_FROM_DATABASE=Intel Corporate OUI:B88D12* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:B88E3A* ID_OUI_FROM_DATABASE=Infinite Technologies JLT @@ -63205,6 +63727,9 @@ OUI:B8BB6D* OUI:B8BEBF* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. +OUI:B8C1A2* + ID_OUI_FROM_DATABASE=Dragon Path Technologies Co., Limited + OUI:B8C46F* ID_OUI_FROM_DATABASE=PRIMMCON INDUSTRIES INC @@ -63215,7 +63740,7 @@ OUI:B8C716* ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD OUI:B8C75D* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:B8C855* ID_OUI_FROM_DATABASE=Shanghai GBCOM Communication Technology Co.,Ltd. @@ -63247,6 +63772,9 @@ OUI:B8DAF7* OUI:B8DC87* ID_OUI_FROM_DATABASE=IAI Corporation +OUI:B8DF6B* + ID_OUI_FROM_DATABASE=SpotCam Co., Ltd. + OUI:B8E589* ID_OUI_FROM_DATABASE=Payter BV @@ -63272,7 +63800,7 @@ OUI:B8F5E7* ID_OUI_FROM_DATABASE=WayTools, LLC OUI:B8F6B1* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:B8F732* ID_OUI_FROM_DATABASE=Aryaka Networks Inc @@ -63287,7 +63815,7 @@ OUI:B8FD32* ID_OUI_FROM_DATABASE=Zhejiang ROICX Microelectronics OUI:B8FF61* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:B8FF6F* ID_OUI_FROM_DATABASE=Shanghai Typrotech Technology Co.Ltd @@ -63367,6 +63895,9 @@ OUI:BC4100* OUI:BC4377* ID_OUI_FROM_DATABASE=Hang Zhou Huite Technology Co.,ltd. +OUI:BC4486* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:BC4760* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd @@ -63380,7 +63911,7 @@ OUI:BC51FE* ID_OUI_FROM_DATABASE=Swann Communications Pty Ltd OUI:BC52B7* - ID_OUI_FROM_DATABASE=Apple Inc + ID_OUI_FROM_DATABASE=Apple OUI:BC5FF4* ID_OUI_FROM_DATABASE=ASRock Incorporation @@ -63389,7 +63920,7 @@ OUI:BC629F* ID_OUI_FROM_DATABASE=Telenet Systems P. Ltd. OUI:BC6778* - ID_OUI_FROM_DATABASE=Apple Inc + ID_OUI_FROM_DATABASE=Apple OUI:BC6784* ID_OUI_FROM_DATABASE=Environics Oy @@ -63442,6 +63973,9 @@ OUI:BC851F* OUI:BC8556* ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. +OUI:BC8893* + ID_OUI_FROM_DATABASE=VILLBAU Ltd. + OUI:BC8B55* ID_OUI_FROM_DATABASE=NPP ELIKS America Inc. DBA T&M Atlantic @@ -63619,6 +64153,9 @@ OUI:C04A00* OUI:C04DF7* ID_OUI_FROM_DATABASE=SERELEC +OUI:C057BC* + ID_OUI_FROM_DATABASE=Avaya, Inc + OUI:C058A7* ID_OUI_FROM_DATABASE=Pico Systems Co., Ltd. @@ -63656,7 +64193,7 @@ OUI:C0830A* ID_OUI_FROM_DATABASE=2Wire OUI:C0847A* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:C0885B* ID_OUI_FROM_DATABASE=SnD Tech Co., Ltd. @@ -63676,11 +64213,14 @@ OUI:C09132* OUI:C09134* ID_OUI_FROM_DATABASE=ProCurve Networking by HP +OUI:C098E5* + ID_OUI_FROM_DATABASE=University of Michigan + OUI:C09C92* ID_OUI_FROM_DATABASE=COBY OUI:C09F42* - ID_OUI_FROM_DATABASE=Apple Inc + ID_OUI_FROM_DATABASE=Apple OUI:C0A0BB* ID_OUI_FROM_DATABASE=D-Link International @@ -63778,6 +64318,9 @@ OUI:C4017C* OUI:C401B1* ID_OUI_FROM_DATABASE=SeekTech INC +OUI:C40415* + ID_OUI_FROM_DATABASE=NETGEAR INC., + OUI:C40938* ID_OUI_FROM_DATABASE=Fujian Star-net Communication Co., Ltd @@ -63821,7 +64364,7 @@ OUI:C42795* ID_OUI_FROM_DATABASE=Technicolor USA Inc. OUI:C42C03* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:C436DA* ID_OUI_FROM_DATABASE=Rusteletech Ltd. @@ -63904,6 +64447,9 @@ OUI:C46AB7* OUI:C46DF1* ID_OUI_FROM_DATABASE=DataGravity +OUI:C46E1F* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD + OUI:C47130* ID_OUI_FROM_DATABASE=Fon Technology S.L. @@ -64000,6 +64546,9 @@ OUI:C4E17C* OUI:C4E7BE* ID_OUI_FROM_DATABASE=SCSpro Co.,Ltd +OUI:C4E92F* + ID_OUI_FROM_DATABASE=AB Sciex + OUI:C4EBE3* ID_OUI_FROM_DATABASE=RRCN SAS @@ -64061,7 +64610,7 @@ OUI:C8292A* ID_OUI_FROM_DATABASE=Barun Electronics OUI:C82A14* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:C82E94* ID_OUI_FROM_DATABASE=Halfa Enterprise Co., Ltd. @@ -64070,7 +64619,7 @@ OUI:C83232* ID_OUI_FROM_DATABASE=Hunting Innova OUI:C8334B* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:C835B8* ID_OUI_FROM_DATABASE=Ericsson, EAB/RWI/K @@ -64196,7 +64745,7 @@ OUI:C8A729* ID_OUI_FROM_DATABASE=SYStronics Co., Ltd. OUI:C8AA21* - ID_OUI_FROM_DATABASE=Motorola Mobility, LLC. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:C8AE9C* ID_OUI_FROM_DATABASE=Shanghai TYD Elecronic Technology Co. Ltd @@ -64208,13 +64757,13 @@ OUI:C8B373* ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC OUI:C8B5B7* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:C8BBD3* ID_OUI_FROM_DATABASE=Embrane OUI:C8BCC8* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:C8BE19* ID_OUI_FROM_DATABASE=D-Link International @@ -64273,6 +64822,9 @@ OUI:C8E1A7* OUI:C8EE08* ID_OUI_FROM_DATABASE=TANGTOP TECHNOLOGY CO.,LTD +OUI:C8EE75* + ID_OUI_FROM_DATABASE=Pishion International Co. Ltd + OUI:C8EEA6* ID_OUI_FROM_DATABASE=Shenzhen SHX Technology Co., Ltd @@ -64322,7 +64874,7 @@ OUI:CC07AB* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd OUI:CC08E0* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:CC09C8* ID_OUI_FROM_DATABASE=IMAQLIQ LTD @@ -64360,6 +64912,9 @@ OUI:CC2D8C* OUI:CC33BB* ID_OUI_FROM_DATABASE=SAGEMCOM SAS +OUI:CC3429* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + OUI:CC34D7* ID_OUI_FROM_DATABASE=GEWISS S.P.A. @@ -64441,6 +64996,9 @@ OUI:CC6DEF* OUI:CC720F* ID_OUI_FROM_DATABASE=Viscount Systems Inc. +OUI:CC7498* + ID_OUI_FROM_DATABASE=Filmetrics Inc. + OUI:CC7669* ID_OUI_FROM_DATABASE=SEETECH @@ -64454,7 +65012,7 @@ OUI:CC7B35* ID_OUI_FROM_DATABASE=zte corporation OUI:CC7D37* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:CC7EE7* ID_OUI_FROM_DATABASE=Panasonic AVC Networks Company @@ -64582,6 +65140,9 @@ OUI:CCF954* OUI:CCF9E8* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +OUI:CCFB65* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + OUI:CCFC6D* ID_OUI_FROM_DATABASE=RIZ TRANSMITTERS @@ -64616,7 +65177,7 @@ OUI:D022BE* ID_OUI_FROM_DATABASE=Samsung Electro Mechanics co.,LTD. OUI:D023DB* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:D02788* ID_OUI_FROM_DATABASE=Hon Hai Precision Ind.Co.Ltd @@ -64633,6 +65194,9 @@ OUI:D03110* OUI:D03761* ID_OUI_FROM_DATABASE=Texas Instruments +OUI:D03972* + ID_OUI_FROM_DATABASE=Texas Instruments + OUI:D046DC* ID_OUI_FROM_DATABASE=Southwest Research Institute @@ -64741,6 +65305,9 @@ OUI:D0B33F* OUI:D0B498* ID_OUI_FROM_DATABASE=Robert Bosch LLC Automotive Electronics +OUI:D0B523* + ID_OUI_FROM_DATABASE=Bestcare Cloucal Corp. + OUI:D0B53D* ID_OUI_FROM_DATABASE=SEPRO ROBOTIQUE @@ -64756,6 +65323,9 @@ OUI:D0C1B1* OUI:D0C282* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. +OUI:D0C42F* + ID_OUI_FROM_DATABASE=Tamagawa Seiki Co.,Ltd. + OUI:D0C789* ID_OUI_FROM_DATABASE=Cisco @@ -64954,9 +65524,15 @@ OUI:D466A8* OUI:D467E7* ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Tech.Co.,Ltd. +OUI:D46867* + ID_OUI_FROM_DATABASE=Neoventus Design Group + OUI:D46A91* ID_OUI_FROM_DATABASE=Snap AV +OUI:D46AA8* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + OUI:D46CBF* ID_OUI_FROM_DATABASE=Goodrich ISR @@ -65012,7 +65588,7 @@ OUI:D496DF* ID_OUI_FROM_DATABASE=SUNGJIN C&T CO.,LTD OUI:D49A20* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:D49C28* ID_OUI_FROM_DATABASE=JayBird Gear LLC @@ -65095,6 +65671,9 @@ OUI:D4D748* OUI:D4D898* ID_OUI_FROM_DATABASE=Korea CNO Tech Co., Ltd +OUI:D4D919* + ID_OUI_FROM_DATABASE=GoPro + OUI:D4DF57* ID_OUI_FROM_DATABASE=Alpinion Medical Systems @@ -65192,7 +65771,7 @@ OUI:D82DE1* ID_OUI_FROM_DATABASE=Tricascade Inc. OUI:D83062* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:D831CF* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd @@ -65273,7 +65852,7 @@ OUI:D89685* ID_OUI_FROM_DATABASE=GoPro OUI:D89695* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:D8973B* ID_OUI_FROM_DATABASE=Emerson Network Power Embedded Power @@ -65288,10 +65867,10 @@ OUI:D89DB9* ID_OUI_FROM_DATABASE=eMegatech International Corp. OUI:D89E3F* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:D8A25E* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:D8AE90* ID_OUI_FROM_DATABASE=Itibia Technologies @@ -65398,6 +65977,9 @@ OUI:DC0265* OUI:DC028E* ID_OUI_FROM_DATABASE=zte corporation +OUI:DC0575* + ID_OUI_FROM_DATABASE=SIEMENS ENERGY AUTOMATION + OUI:DC05ED* ID_OUI_FROM_DATABASE=Nabtesco Corporation @@ -65435,7 +66017,7 @@ OUI:DC2A14* ID_OUI_FROM_DATABASE=Shanghai Longjing Technology Co. OUI:DC2B61* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:DC2B66* ID_OUI_FROM_DATABASE=InfoBLOCK S.A. de C.V. @@ -65474,7 +66056,7 @@ OUI:DC3EF8* ID_OUI_FROM_DATABASE=Nokia Corporation OUI:DC4517* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:DC49C9* ID_OUI_FROM_DATABASE=CASCO SIGNAL LTD @@ -65485,6 +66067,9 @@ OUI:DC4EDE* OUI:DC5726* ID_OUI_FROM_DATABASE=Power-One +OUI:DC5E36* + ID_OUI_FROM_DATABASE=Paterson Technology + OUI:DC647C* ID_OUI_FROM_DATABASE=C.R.S. iiMotion GmbH @@ -65506,6 +66091,9 @@ OUI:DC825B* OUI:DC85DE* ID_OUI_FROM_DATABASE=Azurewave Technologies., inc. +OUI:DC86D8* + ID_OUI_FROM_DATABASE=Apple, Inc + OUI:DC9B1E* ID_OUI_FROM_DATABASE=Intercom, Inc. @@ -65536,6 +66124,9 @@ OUI:DCA971* OUI:DCA989* ID_OUI_FROM_DATABASE=MACANDC +OUI:DCAD9E* + ID_OUI_FROM_DATABASE=GreenPriz + OUI:DCAE04* ID_OUI_FROM_DATABASE=CELOXICA Ltd @@ -65563,6 +66154,9 @@ OUI:DCCBA8* OUI:DCCE41* ID_OUI_FROM_DATABASE=FE GLOBAL HONG KONG LIMITED +OUI:DCCEBC* + ID_OUI_FROM_DATABASE=Shenzhen JSR Technology Co.,Ltd. + OUI:DCCF94* ID_OUI_FROM_DATABASE=Beijing Rongcheng Hutong Technology Co., Ltd. @@ -65746,6 +66340,9 @@ OUI:E09467* OUI:E09579* ID_OUI_FROM_DATABASE=ORTHOsoft inc, d/b/a Zimmer CAS +OUI:E097F2* + ID_OUI_FROM_DATABASE=Atomax Inc. + OUI:E09D31* ID_OUI_FROM_DATABASE=Intel Corporate @@ -65792,7 +66389,7 @@ OUI:E0B9A5* ID_OUI_FROM_DATABASE=Azurewave OUI:E0B9BA* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:E0BC43* ID_OUI_FROM_DATABASE=C2 Microsystems, Inc. @@ -65816,7 +66413,7 @@ OUI:E0C922* ID_OUI_FROM_DATABASE=Jireh Energy Tech., Ltd. OUI:E0C97A* - ID_OUI_FROM_DATABASE=Apple Inc + ID_OUI_FROM_DATABASE=Apple OUI:E0CA4D* ID_OUI_FROM_DATABASE=Shenzhen Unistar Communication Co.,LTD @@ -65879,13 +66476,13 @@ OUI:E0F379* ID_OUI_FROM_DATABASE=Vaddio OUI:E0F5C6* - ID_OUI_FROM_DATABASE=Apple Inc + ID_OUI_FROM_DATABASE=Apple OUI:E0F5CA* ID_OUI_FROM_DATABASE=CHENG UEI PRECISION INDUSTRY CO.,LTD. OUI:E0F847* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:E0F9BE* ID_OUI_FROM_DATABASE=Cloudena Corp. @@ -65978,7 +66575,7 @@ OUI:E457A8* ID_OUI_FROM_DATABASE=Stuart Manufacturing, Inc. OUI:E46449* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:E467BA* ID_OUI_FROM_DATABASE=Danish Interpretation Systems A/S @@ -65995,6 +66592,9 @@ OUI:E47185* OUI:E4751E* ID_OUI_FROM_DATABASE=Getinge Sterilization AB +OUI:E47723* + ID_OUI_FROM_DATABASE=zte corporation + OUI:E4776B* ID_OUI_FROM_DATABASE=AARTESYS AG @@ -66011,7 +66611,7 @@ OUI:E481B3* ID_OUI_FROM_DATABASE=Shenzhen ACT Industrial Co.,Ltd. OUI:E48399* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:E48AD5* ID_OUI_FROM_DATABASE=RF WINDOW CO., LTD. @@ -66034,6 +66634,9 @@ OUI:E496AE* OUI:E497F0* ID_OUI_FROM_DATABASE=Shanghai VLC Technologies Ltd. Co. +OUI:E498D6* + ID_OUI_FROM_DATABASE=Apple, Inc + OUI:E4A5EF* ID_OUI_FROM_DATABASE=TRON LINK ELECTRONICS CO., LTD. @@ -66055,14 +66658,20 @@ OUI:E4B021* OUI:E4C146* ID_OUI_FROM_DATABASE=Objetivos y Servicios de Valor A +OUI:E4C63D* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:E4C6E6* ID_OUI_FROM_DATABASE=Mophie, LLC +OUI:E4C722* + ID_OUI_FROM_DATABASE=Cisco + OUI:E4C806* ID_OUI_FROM_DATABASE=Ceiec Electric Technology Inc. OUI:E4CE8F* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:E4D3F1* ID_OUI_FROM_DATABASE=Cisco @@ -66107,7 +66716,7 @@ OUI:E8039A* ID_OUI_FROM_DATABASE=Samsung Electronics CO., LTD OUI:E8040B* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:E80462* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. @@ -66119,7 +66728,7 @@ OUI:E8056D* ID_OUI_FROM_DATABASE=Nortel Networks OUI:E80688* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:E80B13* ID_OUI_FROM_DATABASE=Akib Systems Taiwan, INC @@ -66221,7 +66830,7 @@ OUI:E86CDA* ID_OUI_FROM_DATABASE=Supercomputers and Neurocomputers Research Center OUI:E86D52* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:E86D54* ID_OUI_FROM_DATABASE=Digit Mobile Inc @@ -66301,6 +66910,9 @@ OUI:E8BA70* OUI:E8BB3D* ID_OUI_FROM_DATABASE=Sino Prime-Tech Limited +OUI:E8BBA8* + ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD. + OUI:E8BE81* ID_OUI_FROM_DATABASE=SAGEMCOM @@ -66373,6 +66985,9 @@ OUI:E8EDF3* OUI:E8F1B0* ID_OUI_FROM_DATABASE=SAGEMCOM SAS +OUI:E8F226* + ID_OUI_FROM_DATABASE=MILLSON CUSTOM SOLUTIONS INC. + OUI:E8F928* ID_OUI_FROM_DATABASE=RFTECH SRL @@ -66413,7 +67028,7 @@ OUI:EC3091* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. OUI:EC3586* - ID_OUI_FROM_DATABASE=Apple` + ID_OUI_FROM_DATABASE=Apple OUI:EC3BF0* ID_OUI_FROM_DATABASE=NovelSat @@ -66482,7 +67097,7 @@ OUI:EC836C* ID_OUI_FROM_DATABASE=RM Tech Co., Ltd. OUI:EC852F* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:EC888F* ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD. @@ -66773,7 +67388,7 @@ OUI:F0AE51* ID_OUI_FROM_DATABASE=Xi3 Corp OUI:F0B479* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:F0B6EB* ID_OUI_FROM_DATABASE=Poslab Technology Co., Ltd. @@ -66787,6 +67402,9 @@ OUI:F0BDF1* OUI:F0BF97* ID_OUI_FROM_DATABASE=Sony Corporation +OUI:F0C1F1* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:F0C24C* ID_OUI_FROM_DATABASE=Zhejiang FeiYue Digital Technology Co., Ltd @@ -66797,7 +67415,7 @@ OUI:F0C88C* ID_OUI_FROM_DATABASE=LeddarTech Inc. OUI:F0CBA1* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:F0D14F* ID_OUI_FROM_DATABASE=LINEAR LLC @@ -66805,6 +67423,9 @@ OUI:F0D14F* OUI:F0D1A9* ID_OUI_FROM_DATABASE=Apple +OUI:F0D3A7* + ID_OUI_FROM_DATABASE=CobaltRay Co., Ltd + OUI:F0D3E7* ID_OUI_FROM_DATABASE=Sensometrix SA @@ -66818,7 +67439,7 @@ OUI:F0DB30* ID_OUI_FROM_DATABASE=Yottabyte OUI:F0DCE2* - ID_OUI_FROM_DATABASE=Apple Inc + ID_OUI_FROM_DATABASE=Apple OUI:F0DE71* ID_OUI_FROM_DATABASE=Shanghai EDO Technologies Co.,Ltd. @@ -67115,7 +67736,7 @@ OUI:F8051C* ID_OUI_FROM_DATABASE=DRS Imaging and Targeting Solutions OUI:F80BBE* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:F80BD0* ID_OUI_FROM_DATABASE=Datang Telecom communication terminal (Tianjin) Co., Ltd. @@ -67148,11 +67769,14 @@ OUI:F81D93* ID_OUI_FROM_DATABASE=Longdhua(Beijing) Controls Technology Co.,Ltd OUI:F81EDF* - ID_OUI_FROM_DATABASE=Apple, Inc + ID_OUI_FROM_DATABASE=Apple OUI:F82285* ID_OUI_FROM_DATABASE=Cypress Technology CO., LTD. +OUI:F82793* + ID_OUI_FROM_DATABASE=Apple, Inc + OUI:F82BC8* ID_OUI_FROM_DATABASE=Jiangsu Switter Co., Ltd @@ -67228,6 +67852,9 @@ OUI:F85BC9* OUI:F85F2A* ID_OUI_FROM_DATABASE=Nokia Corporation +OUI:F862AA* + ID_OUI_FROM_DATABASE=xn systems + OUI:F866F2* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. @@ -67250,7 +67877,7 @@ OUI:F87B62* ID_OUI_FROM_DATABASE=FASTWEL INTERNATIONAL CO., LTD. Taiwan Branch OUI:F87B7A* - ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. OUI:F87B8C* ID_OUI_FROM_DATABASE=Amped Wireless @@ -67276,6 +67903,9 @@ OUI:F8912A* OUI:F893F3* ID_OUI_FROM_DATABASE=VOLANS +OUI:F89550* + ID_OUI_FROM_DATABASE=Proton Products Chengdu Ltd + OUI:F897CF* ID_OUI_FROM_DATABASE=DAESHIN-INFORMATION TECHNOLOGY CO., LTD. @@ -67309,6 +67939,9 @@ OUI:F8B156* OUI:F8B599* ID_OUI_FROM_DATABASE=Guangzhou CHNAVS Digital Technology Co.,Ltd +OUI:F8BC12* + ID_OUI_FROM_DATABASE=Dell Inc PCBA Test + OUI:F8C001* ID_OUI_FROM_DATABASE=Juniper Networks @@ -67438,12 +68071,18 @@ OUI:FC1186* OUI:FC1794* ID_OUI_FROM_DATABASE=InterCreative Co., Ltd +OUI:FC19D0* + ID_OUI_FROM_DATABASE=Cloud Vision Networks Technology Co.,Ltd. + OUI:FC1BFF* ID_OUI_FROM_DATABASE=V-ZUG AG OUI:FC1D59* ID_OUI_FROM_DATABASE=I Smart Cities HK Ltd +OUI:FC1E16* + ID_OUI_FROM_DATABASE=IPEVO corp + OUI:FC1F19* ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS CO., LTD. @@ -67454,7 +68093,7 @@ OUI:FC229C* ID_OUI_FROM_DATABASE=Han Kyung I Net Co.,Ltd. OUI:FC253F* - ID_OUI_FROM_DATABASE=Apple, Inc. + ID_OUI_FROM_DATABASE=Apple OUI:FC2A54* ID_OUI_FROM_DATABASE=Connected Data, Inc. @@ -67612,6 +68251,9 @@ OUI:FCDD55* OUI:FCE192* ID_OUI_FROM_DATABASE=Sichuan Jinwangtong Electronic Science&Technology Co,.Ltd +OUI:FCE1D9* + ID_OUI_FROM_DATABASE=Stable Imaging Solutions LLC + OUI:FCE23F* ID_OUI_FROM_DATABASE=CLAY PAKY SPA @@ -67638,3 +68280,6 @@ OUI:FCFAF7* OUI:FCFBFB* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:FCFE77* + ID_OUI_FROM_DATABASE=Hitachi Reftechno, Inc. diff --git a/hwdb/20-pci-vendor-model.hwdb b/hwdb/20-pci-vendor-model.hwdb index c9830f5bbd..f94f54af18 100644 --- a/hwdb/20-pci-vendor-model.hwdb +++ b/hwdb/20-pci-vendor-model.hwdb @@ -1340,6 +1340,12 @@ pci:v00001000d00000096* pci:v00001000d00000097* ID_MODEL_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3 +pci:v00001000d00000097sv00001028sd00001F45* + ID_MODEL_FROM_DATABASE=12GB/s HBA internal + +pci:v00001000d00000097sv00001028sd00001F46* + ID_MODEL_FROM_DATABASE=12GB/s HBA external + pci:v00001000d00000407* ID_MODEL_FROM_DATABASE=MegaRAID @@ -1821,7 +1827,7 @@ pci:v00001002d00004157* ID_MODEL_FROM_DATABASE=RV350 GL [FireGL T2] pci:v00001002d00004158* - ID_MODEL_FROM_DATABASE=68800AX [Mach32] + ID_MODEL_FROM_DATABASE=68800AX [Graphics Ultra Pro PCI] pci:v00001002d00004164* ID_MODEL_FROM_DATABASE=R300 [Radeon 9500 PRO] (Secondary) @@ -2706,7 +2712,7 @@ pci:v00001002d00004754* ID_MODEL_FROM_DATABASE=3D Rage II/II+ PCI [Mach64 GT] pci:v00001002d00004755* - ID_MODEL_FROM_DATABASE=3D Rage II+ PCI [Mach64 GTB] + ID_MODEL_FROM_DATABASE=Mach64 GTB [3D Rage II+ DVD] pci:v00001002d00004756* ID_MODEL_FROM_DATABASE=3D Rage IIC PCI [Mach64 GT IIC] @@ -5835,7 +5841,7 @@ pci:v00001002d00006810* ID_MODEL_FROM_DATABASE=Pitcairn pci:v00001002d00006811* - ID_MODEL_FROM_DATABASE=Pitcairn + ID_MODEL_FROM_DATABASE=Pitcairn [Radeon R9 200 Series] pci:v00001002d00006816* ID_MODEL_FROM_DATABASE=Pitcairn @@ -5913,10 +5919,19 @@ pci:v00001002d00006831* ID_MODEL_FROM_DATABASE=Cape Verde [AMD Radeon HD 7700M Series] pci:v00001002d00006835* - ID_MODEL_FROM_DATABASE=Cape Verde PRX + ID_MODEL_FROM_DATABASE=Cape Verde PRX [Radeon R7 200 Series] pci:v00001002d00006837* - ID_MODEL_FROM_DATABASE=Cape Verde LE [Radeon HD 7730] + ID_MODEL_FROM_DATABASE=Cape Verde LE [Radeon HD 7730/8730] + +pci:v00001002d00006837sv00001462sd00002796* + ID_MODEL_FROM_DATABASE=Radeon HD 8730 + +pci:v00001002d00006837sv00001462sd00008092* + ID_MODEL_FROM_DATABASE=Radeon HD 8730 + +pci:v00001002d00006837sv0000148Csd00008730* + ID_MODEL_FROM_DATABASE=Radeon HD 8730 pci:v00001002d00006837sv00001787sd00003000* ID_MODEL_FROM_DATABASE=Radeon HD 6570 @@ -8202,7 +8217,7 @@ pci:v00001002d00009490* ID_MODEL_FROM_DATABASE=RV730 XT [Radeon HD 4670] pci:v00001002d00009490sv0000174Bsd0000E880* - ID_MODEL_FROM_DATABASE=Radeon HD 4670 512MB DDR3 + ID_MODEL_FROM_DATABASE=Radeon HD 4670 512MB GDDR3 Dual DVI-I/TVO pci:v00001002d00009491* ID_MODEL_FROM_DATABASE=RV730/M96-CSP [Radeon E4690] @@ -10175,8 +10190,26 @@ pci:v00001014d0000034Asv00001014sd0000035E* pci:v00001014d0000034Asv00001014sd000003FB* ID_MODEL_FROM_DATABASE=PCIe3 28GB Cache RAID SAS Enclosure 6Gb x 16 (57D5) +pci:v00001014d0000034Asv00001014sd000003FE* + ID_MODEL_FROM_DATABASE=PCIe3 x8 Cache SAS RAID Internal Adapter 6Gb (57D8) + +pci:v00001014d0000034Asv00001014sd000003FF* + ID_MODEL_FROM_DATABASE=PCIe3 x8 SAS RAID Internal Adapter 6Gb (57D7) + +pci:v00001014d0000034Asv00001014sd00000474* + ID_MODEL_FROM_DATABASE=PCIe3 x16 Cache SAS RAID Internal Adapter 6Gb (57EB) + +pci:v00001014d0000034Asv00001014sd00000475* + ID_MODEL_FROM_DATABASE=PCIe3 x16 SAS RAID Internal Adapter 6Gb (57EC) + +pci:v00001014d0000034Asv00001014sd00000499* + ID_MODEL_FROM_DATABASE=PCIe3 x16 Cache SAS RAID Internal Adapter 6Gb (57ED) + +pci:v00001014d0000034Asv00001014sd0000049A* + ID_MODEL_FROM_DATABASE=PCIe3 x16 SAS RAID Internal Adapter 6Gb (57EE) + pci:v00001014d000004AA* - ID_MODEL_FROM_DATABASE=Flash Adapter 900GB Full Height + ID_MODEL_FROM_DATABASE=Flash Adapter 90 (PCIe2 0.9TB) pci:v00001014d00003022* ID_MODEL_FROM_DATABASE=QLA3022 Network Adapter @@ -14241,7 +14274,7 @@ pci:v0000104Cd00008023sv0000103Csd0000088C* ID_MODEL_FROM_DATABASE=NC8000 laptop pci:v0000104Cd00008023sv00001043sd0000808B* - ID_MODEL_FROM_DATABASE=K8N4-E Mainboard + ID_MODEL_FROM_DATABASE=K8N4/A8N Series Mainboard pci:v0000104Cd00008023sv00001043sd0000815B* ID_MODEL_FROM_DATABASE=P5W DH Deluxe Motherboard @@ -17276,6 +17309,9 @@ pci:v00001095d00003112sv00009005sd00000250* pci:v00001095d00003114* ID_MODEL_FROM_DATABASE=SiI 3114 [SATALink/SATARaid] Serial ATA Controller +pci:v00001095d00003114sv00001043sd00008167* + ID_MODEL_FROM_DATABASE=A8N-SLI Deluxe/Premium Mainboard + pci:v00001095d00003114sv00001095sd00003114* ID_MODEL_FROM_DATABASE=SiI 3114 SATALink Controller @@ -20280,7 +20316,7 @@ pci:v000010DEd00000050* ID_MODEL_FROM_DATABASE=CK804 ISA Bridge pci:v000010DEd00000050sv00001043sd0000815A* - ID_MODEL_FROM_DATABASE=K8N4-E or A8N-E Mainboard + ID_MODEL_FROM_DATABASE=K8N4/A8N Series Mainboard pci:v000010DEd00000050sv000010F1sd00002865* ID_MODEL_FROM_DATABASE=Tomcat K8E (S2865) @@ -20313,7 +20349,7 @@ pci:v000010DEd00000052sv00001028sd00000225* ID_MODEL_FROM_DATABASE=PowerEdge T105 SMBus pci:v000010DEd00000052sv00001043sd0000815A* - ID_MODEL_FROM_DATABASE=K8N4-E or A8N-E Mainboard + ID_MODEL_FROM_DATABASE=K8N4/A8N Series Mainboard pci:v000010DEd00000052sv000010F1sd00002865* ID_MODEL_FROM_DATABASE=Tomcat K8E (S2865) @@ -20337,7 +20373,7 @@ pci:v000010DEd00000053* ID_MODEL_FROM_DATABASE=CK804 IDE pci:v000010DEd00000053sv00001043sd0000815A* - ID_MODEL_FROM_DATABASE=K8N4-E or A8N-E Mainboard + ID_MODEL_FROM_DATABASE=K8N4/A8N Series Mainboard pci:v000010DEd00000053sv000010F1sd00002865* ID_MODEL_FROM_DATABASE=Tomcat K8E (S2865) @@ -20364,7 +20400,7 @@ pci:v000010DEd00000054sv00001028sd00000225* ID_MODEL_FROM_DATABASE=PowerEdge T105 Serial ATA pci:v000010DEd00000054sv00001043sd0000815A* - ID_MODEL_FROM_DATABASE=A8N-E Mainboard + ID_MODEL_FROM_DATABASE=A8N Series Mainboard pci:v000010DEd00000054sv000010F1sd00002865* ID_MODEL_FROM_DATABASE=Tomcat K8E (S2865) @@ -20391,7 +20427,7 @@ pci:v000010DEd00000055sv00001028sd00000225* ID_MODEL_FROM_DATABASE=PowerEdge T105 Serial ATA pci:v000010DEd00000055sv00001043sd0000815A* - ID_MODEL_FROM_DATABASE=K8N4-E or A8N-E Mainboard + ID_MODEL_FROM_DATABASE=K8N4/A8N Series Mainboard pci:v000010DEd00000055sv000010F1sd00002865* ID_MODEL_FROM_DATABASE=Tomcat K8E (S2865) @@ -20415,7 +20451,7 @@ pci:v000010DEd00000057* ID_MODEL_FROM_DATABASE=CK804 Ethernet Controller pci:v000010DEd00000057sv00001043sd00008141* - ID_MODEL_FROM_DATABASE=K8N4-E or A8N-E Mainboard + ID_MODEL_FROM_DATABASE=K8N4/A8N Series Mainboard pci:v000010DEd00000057sv000010DEsd0000CB84* ID_MODEL_FROM_DATABASE=NF4 Lanparty @@ -20445,7 +20481,7 @@ pci:v000010DEd00000059* ID_MODEL_FROM_DATABASE=CK804 AC'97 Audio Controller pci:v000010DEd00000059sv00001043sd0000812A* - ID_MODEL_FROM_DATABASE=K8N4-E or A8N-E Mainboard + ID_MODEL_FROM_DATABASE=K8N4/A8N Series Mainboard pci:v000010DEd00000059sv000010F1sd00002865* ID_MODEL_FROM_DATABASE=Tomcat K8E (S2865) @@ -20466,7 +20502,7 @@ pci:v000010DEd0000005Asv00001028sd00000225* ID_MODEL_FROM_DATABASE=PowerEdge T105 onboard USB pci:v000010DEd0000005Asv00001043sd0000815A* - ID_MODEL_FROM_DATABASE=K8N4-E or A8N-E Mainboard + ID_MODEL_FROM_DATABASE=K8N4/A8N Series Mainboard pci:v000010DEd0000005Asv000010F1sd00002865* ID_MODEL_FROM_DATABASE=Tomcat K8E (S2865) @@ -20493,7 +20529,7 @@ pci:v000010DEd0000005Bsv00001028sd00000225* ID_MODEL_FROM_DATABASE=PowerEdge T105 onboard USB pci:v000010DEd0000005Bsv00001043sd0000815A* - ID_MODEL_FROM_DATABASE=K8N4-E or A8N-E Mainboard + ID_MODEL_FROM_DATABASE=K8N4/A8N Series Mainboard pci:v000010DEd0000005Bsv000010F1sd00002865* ID_MODEL_FROM_DATABASE=Tomcat K8E (S2865) @@ -20526,7 +20562,7 @@ pci:v000010DEd0000005Esv00001028sd00000225* ID_MODEL_FROM_DATABASE=PowerEdge T105 Memory Controller pci:v000010DEd0000005Esv00001043sd0000815A* - ID_MODEL_FROM_DATABASE=A8N-E Mainboard + ID_MODEL_FROM_DATABASE=A8N Series Mainboard pci:v000010DEd0000005Esv000010DEsd0000005E* ID_MODEL_FROM_DATABASE=ECS Elitegroup NFORCE3-A939 motherboard. @@ -22679,6 +22715,9 @@ pci:v000010DEd00000391* pci:v000010DEd00000391sv00001458sd00003427* ID_MODEL_FROM_DATABASE=GV-NX76T128D-RH +pci:v000010DEd00000391sv00001462sd00000452* + ID_MODEL_FROM_DATABASE=NX7600GT-VT2D256E + pci:v000010DEd00000392* ID_MODEL_FROM_DATABASE=G73 [GeForce 7600 GS] @@ -24725,6 +24764,123 @@ pci:v000010DEd00000A78* pci:v000010DEd00000A7A* ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] +pci:v000010DEd00000A7Asv0000104Dsd0000907E* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv00001179sd0000FC50* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv00001179sd0000FC61* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv00001179sd0000FC71* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv00001179sd0000FC90* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv00001179sd0000FCC0* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv00001179sd0000FCD0* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv00001179sd0000FCE2* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv00001179sd0000FCF2* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv00001179sd0000FD16* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv00001179sd0000FD40* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv00001179sd0000FD50* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv00001179sd0000FD52* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv00001179sd0000FD61* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv00001179sd0000FD71* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv00001179sd0000FD92* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv00001179sd0000FD96* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv00001179sd0000FDD0* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv00001179sd0000FDD2* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv00001179sd0000FDFE* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv0000144Dsd0000C0A2* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv0000144Dsd0000C0B2* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv0000144Dsd0000C581* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv0000144Dsd0000C587* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv0000144Dsd0000C588* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv0000144Dsd0000C597* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv0000144Dsd0000C606* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv00001462sd0000AA51* + ID_MODEL_FROM_DATABASE=GeForce 405 + +pci:v000010DEd00000A7Asv00001462sd0000AA58* + ID_MODEL_FROM_DATABASE=GeForce 405 + +pci:v000010DEd00000A7Asv00001462sd0000AC71* + ID_MODEL_FROM_DATABASE=GeForce 405 + +pci:v000010DEd00000A7Asv00001462sd0000AC81* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv00001462sd0000AC82* + ID_MODEL_FROM_DATABASE=GeForce 405 + +pci:v000010DEd00000A7Asv00001462sd0000AE33* + ID_MODEL_FROM_DATABASE=GeForce 405 + +pci:v000010DEd00000A7Asv000017AAsd00003950* + ID_MODEL_FROM_DATABASE=GeForce 405M + +pci:v000010DEd00000A7Asv000017AAsd0000397D* + ID_MODEL_FROM_DATABASE=GeForce 405M + +pci:v000010DEd00000A7Asv00001B0Asd00002091* + ID_MODEL_FROM_DATABASE=GeForce 315M + +pci:v000010DEd00000A7Asv00001BFDsd00000003* + ID_MODEL_FROM_DATABASE=GeForce 405 + +pci:v000010DEd00000A7Asv00001BFDsd00008006* + ID_MODEL_FROM_DATABASE=GeForce 405 + +pci:v000010DEd00000A7Asv00001BFDsd00008007* + ID_MODEL_FROM_DATABASE=GeForce 315M + pci:v000010DEd00000A7B* ID_MODEL_FROM_DATABASE=GT218 [GeForce 505] @@ -25383,7 +25539,7 @@ pci:v000010DEd00000FDF* ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 740M] pci:v000010DEd00000FE0* - ID_MODEL_FROM_DATABASE=GK107M [GeForce GTX 660M OEM] + ID_MODEL_FROM_DATABASE=GK107M [GeForce GTX 660M Mac Edition] pci:v000010DEd00000FE1* ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 730M] @@ -25391,6 +25547,9 @@ pci:v000010DEd00000FE1* pci:v000010DEd00000FE3* ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 745M] +pci:v000010DEd00000FE3sv000017AAsd00003675* + ID_MODEL_FROM_DATABASE=GeForce GT 745A + pci:v000010DEd00000FE4* ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 750M] @@ -25418,6 +25577,9 @@ pci:v000010DEd00000FF2* pci:v000010DEd00000FF5* ID_MODEL_FROM_DATABASE=GK107GL [Tesla K1 USM] +pci:v000010DEd00000FF6* + ID_MODEL_FROM_DATABASE=GK107GLM [Quadro K1100M] + pci:v000010DEd00000FF7* ID_MODEL_FROM_DATABASE=GK107GL [Quadro K1 USM] @@ -25751,12 +25913,33 @@ pci:v000010DEd00001140sv00001025sd00000781* pci:v000010DEd00001140sv00001025sd00000798* ID_MODEL_FROM_DATABASE=GeForce GT 720M +pci:v000010DEd00001140sv00001025sd00000799* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + pci:v000010DEd00001140sv00001025sd0000079B* ID_MODEL_FROM_DATABASE=GeForce GT 720M +pci:v000010DEd00001140sv00001025sd0000079C* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + +pci:v000010DEd00001140sv00001025sd00000807* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + pci:v000010DEd00001140sv00001025sd00000821* ID_MODEL_FROM_DATABASE=GeForce GT 720M +pci:v000010DEd00001140sv00001025sd00000823* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + +pci:v000010DEd00001140sv00001025sd00000830* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + +pci:v000010DEd00001140sv00001025sd00000837* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + +pci:v000010DEd00001140sv00001025sd00000841* + ID_MODEL_FROM_DATABASE=GeForce 710M + pci:v000010DEd00001140sv00001028sd0000054D* ID_MODEL_FROM_DATABASE=GeForce GT 630M @@ -25802,6 +25985,9 @@ pci:v000010DEd00001140sv00001028sd000005DA* pci:v000010DEd00001140sv00001028sd000005E8* ID_MODEL_FROM_DATABASE=GeForce GT 630M +pci:v000010DEd00001140sv00001028sd000005F4* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + pci:v000010DEd00001140sv0000103Csd000018EF* ID_MODEL_FROM_DATABASE=GeForce GT 630M @@ -25865,9 +26051,18 @@ pci:v000010DEd00001140sv00001043sd0000220A* pci:v000010DEd00001140sv00001043sd0000221A* ID_MODEL_FROM_DATABASE=GeForce GT 720M +pci:v000010DEd00001140sv00001043sd0000223A* + ID_MODEL_FROM_DATABASE=GeForce GT 710M + +pci:v000010DEd00001140sv00001043sd0000224A* + ID_MODEL_FROM_DATABASE=GeForce GT 710M + pci:v000010DEd00001140sv00001043sd00008595* ID_MODEL_FROM_DATABASE=GeForce GT 720M +pci:v000010DEd00001140sv000010CFsd000017F5* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + pci:v000010DEd00001140sv00001179sd0000FA01* ID_MODEL_FROM_DATABASE=GeForce 710M @@ -25979,6 +26174,9 @@ pci:v000010DEd00001140sv00001462sd0000AA33* pci:v000010DEd00001140sv00001462sd0000AAA2* ID_MODEL_FROM_DATABASE=GeForce GT 720M +pci:v000010DEd00001140sv00001462sd0000AE71* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + pci:v000010DEd00001140sv0000152Dsd00000926* ID_MODEL_FROM_DATABASE=GeForce 620M @@ -26009,6 +26207,9 @@ pci:v000010DEd00001140sv000017AAsd00003802* pci:v000010DEd00001140sv000017AAsd00003803* ID_MODEL_FROM_DATABASE=GeForce GT 720M +pci:v000010DEd00001140sv000017AAsd00003804* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + pci:v000010DEd00001140sv000017AAsd00003901* ID_MODEL_FROM_DATABASE=GeForce 610M / GT 620M @@ -26057,12 +26258,27 @@ pci:v000010DEd00001140sv000017AAsd0000501A* pci:v000010DEd00001140sv000017AAsd0000501F* ID_MODEL_FROM_DATABASE=GeForce GT 720M +pci:v000010DEd00001140sv000017AAsd00005025* + ID_MODEL_FROM_DATABASE=GeForce 710M + pci:v000010DEd00001140sv000017AAsd00005027* ID_MODEL_FROM_DATABASE=GeForce 710M pci:v000010DEd00001140sv000017AAsd0000502A* ID_MODEL_FROM_DATABASE=GeForce 710M +pci:v000010DEd00001140sv000017AAsd0000502B* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + +pci:v000010DEd00001140sv000017AAsd0000502D* + ID_MODEL_FROM_DATABASE=GeForce 710M + +pci:v000010DEd00001140sv000017AAsd0000502E* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + +pci:v000010DEd00001140sv000017AAsd0000502F* + ID_MODEL_FROM_DATABASE=GeForce GT 720M + pci:v000010DEd00001140sv00001854sd00000177* ID_MODEL_FROM_DATABASE=GeForce 710M @@ -26093,6 +26309,9 @@ pci:v000010DEd00001184* pci:v000010DEd00001185* ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 660 OEM] +pci:v000010DEd00001185sv000010DEsd0000106F* + ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 760 OEM] + pci:v000010DEd00001187* ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 760] @@ -26102,6 +26321,9 @@ pci:v000010DEd00001188* pci:v000010DEd00001189* ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 670] +pci:v000010DEd00001189sv000010DEsd00001074* + ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 760 Ti OEM] + pci:v000010DEd0000118A* ID_MODEL_FROM_DATABASE=GK104GL [GRID K520] @@ -26117,12 +26339,18 @@ pci:v000010DEd0000118D* pci:v000010DEd0000118Dsv000010DEsd0000101D* ID_MODEL_FROM_DATABASE=GRID K200 +pci:v000010DEd0000118E* + ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 760 OEM] + pci:v000010DEd0000118F* ID_MODEL_FROM_DATABASE=GK104GL [Tesla K10] pci:v000010DEd0000119D* ID_MODEL_FROM_DATABASE=GK104M [GeForce GTX 775M] +pci:v000010DEd0000119E* + ID_MODEL_FROM_DATABASE=GK104M [GeForce GTX 780M] + pci:v000010DEd0000119F* ID_MODEL_FROM_DATABASE=GK104M [GeForce GTX 780M] @@ -26159,6 +26387,9 @@ pci:v000010DEd000011B1* pci:v000010DEd000011B7* ID_MODEL_FROM_DATABASE=GK104GLM [Quadro K4100M] +pci:v000010DEd000011B8* + ID_MODEL_FROM_DATABASE=GK104GLM [Quadro K5100M] + pci:v000010DEd000011BA* ID_MODEL_FROM_DATABASE=GK104GL [Quadro K5000] @@ -26213,6 +26444,12 @@ pci:v000010DEd000011C4* pci:v000010DEd000011C6* ID_MODEL_FROM_DATABASE=GK106 [GeForce GTX 650 Ti] +pci:v000010DEd000011C7* + ID_MODEL_FROM_DATABASE=GK106 [GeForce GTX 750 Ti] + +pci:v000010DEd000011C8* + ID_MODEL_FROM_DATABASE=GK106 [GeForce GTX 650 OEM] + pci:v000010DEd000011E0* ID_MODEL_FROM_DATABASE=GK106M [GeForce GTX 770M] @@ -26303,8 +26540,38 @@ pci:v000010DEd00001247sv00001043sd0000212B* pci:v000010DEd00001247sv00001043sd0000212C* ID_MODEL_FROM_DATABASE=GeForce GT 635M +pci:v000010DEd00001247sv0000152Dsd00000930* + ID_MODEL_FROM_DATABASE=GeForce GT 635M + pci:v000010DEd00001248* - ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 555M] + ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 555M/635M] + +pci:v000010DEd00001248sv0000152Dsd00000930* + ID_MODEL_FROM_DATABASE=GeForce GT 635M + +pci:v000010DEd00001248sv000017C0sd000010E7* + ID_MODEL_FROM_DATABASE=GeForce GT 555M + +pci:v000010DEd00001248sv000017C0sd000010E8* + ID_MODEL_FROM_DATABASE=GeForce GT 555M + +pci:v000010DEd00001248sv000017C0sd000010EA* + ID_MODEL_FROM_DATABASE=GeForce GT 555M + +pci:v000010DEd00001248sv00001854sd00000890* + ID_MODEL_FROM_DATABASE=GeForce GT 555M + +pci:v000010DEd00001248sv00001854sd00000891* + ID_MODEL_FROM_DATABASE=GeForce GT 555M + +pci:v000010DEd00001248sv00001854sd00001795* + ID_MODEL_FROM_DATABASE=GeForce GT 555M + +pci:v000010DEd00001248sv00001854sd00001796* + ID_MODEL_FROM_DATABASE=GeForce GT 555M + +pci:v000010DEd00001248sv00001854sd00003005* + ID_MODEL_FROM_DATABASE=GeForce GT 555M pci:v000010DEd00001249* ID_MODEL_FROM_DATABASE=GF116 [GeForce GTS 450 Rev. 3] @@ -26315,6 +26582,21 @@ pci:v000010DEd0000124B* pci:v000010DEd0000124D* ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 555M/635M] +pci:v000010DEd0000124Dsv00001028sd00000491* + ID_MODEL_FROM_DATABASE=GeForce GT 555M + +pci:v000010DEd0000124Dsv00001028sd00000570* + ID_MODEL_FROM_DATABASE=GeForce GT 555M + +pci:v000010DEd0000124Dsv00001028sd00000571* + ID_MODEL_FROM_DATABASE=GeForce GT 555M + +pci:v000010DEd0000124Dsv00001462sd0000108D* + ID_MODEL_FROM_DATABASE=GeForce GT 555M + +pci:v000010DEd0000124Dsv00001462sd000010CC* + ID_MODEL_FROM_DATABASE=GeForce GT 635M + pci:v000010DEd00001251* ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 560M] @@ -26348,6 +26630,12 @@ pci:v000010DEd00001291* pci:v000010DEd00001292* ID_MODEL_FROM_DATABASE=GK208M [GeForce GT 740M] +pci:v000010DEd00001292sv000017AAsd00003675* + ID_MODEL_FROM_DATABASE=GeForce GT 740A + +pci:v000010DEd00001292sv000017AAsd00003684* + ID_MODEL_FROM_DATABASE=GeForce GT 740A + pci:v000010DEd00001293* ID_MODEL_FROM_DATABASE=GK208M [GeForce GT 730M] @@ -26360,6 +26648,9 @@ pci:v000010DEd00001295* pci:v000010DEd000012A0* ID_MODEL_FROM_DATABASE=GK208 +pci:v000010DEd000012B9* + ID_MODEL_FROM_DATABASE=GK208GLM [Quadro K610M] + pci:v000010DEd000012BA* ID_MODEL_FROM_DATABASE=GK208GLM [Quadro K510M] @@ -26798,6 +27089,9 @@ pci:v000010ECd00005209* pci:v000010ECd00005229* ID_MODEL_FROM_DATABASE=RTS5229 PCI Express Card Reader +pci:v000010ECd00005229sv00001025sd00000813* + ID_MODEL_FROM_DATABASE=Aspire R7-571 + pci:v000010ECd00005288* ID_MODEL_FROM_DATABASE=Barossa PCI Express Card Reader @@ -31175,6 +31469,15 @@ pci:v00001137d00000045sv00001137sd0000004F* pci:v00001137d0000004E* ID_MODEL_FROM_DATABASE=VIC 82 PCIe Upstream Port +pci:v00001137d00000071* + ID_MODEL_FROM_DATABASE=VIC SR-IOV VF + +pci:v00001137d00000084* + ID_MODEL_FROM_DATABASE=VIC 1240 MLOM FCoE HBA + +pci:v00001137d00000085* + ID_MODEL_FROM_DATABASE=VIC 1225 PCIe FCOE HBA + pci:v00001137d000000CF* ID_MODEL_FROM_DATABASE=VIC Userspace NIC @@ -32450,6 +32753,9 @@ pci:v00001180d00000476sv000017AAsd0000201C* pci:v00001180d00000476sv000017AAsd000020C4* ID_MODEL_FROM_DATABASE=ThinkPad T61 +pci:v00001180d00000476sv000017AAsd000020C6* + ID_MODEL_FROM_DATABASE=ThinkPad R61 + pci:v00001180d00000477* ID_MODEL_FROM_DATABASE=RL5c477 @@ -32639,6 +32945,9 @@ pci:v00001180d00000832sv0000103Csd000030CC* pci:v00001180d00000832sv0000103Csd000030CF* ID_MODEL_FROM_DATABASE=Pavilion dv9668eg Laptop +pci:v00001180d00000832sv000017AAsd000020C7* + ID_MODEL_FROM_DATABASE=ThinkPad R61 + pci:v00001180d00000841* ID_MODEL_FROM_DATABASE=R5C841 CardBus/SD/SDIO/MMC/MS/MSPro/xD/IEEE1394 @@ -33182,9 +33491,18 @@ pci:v000011ABd00002A30* pci:v000011ABd00002A40* ID_MODEL_FROM_DATABASE=88W8366 [TopDog] 802.11n Wireless +pci:v000011ABd00002A41* + ID_MODEL_FROM_DATABASE=88W8366 [TopDog] 802.11n Wireless + +pci:v000011ABd00002A42* + ID_MODEL_FROM_DATABASE=88W8366 [TopDog] 802.11n Wireless + pci:v000011ABd00002A43* ID_MODEL_FROM_DATABASE=88W8366 [TopDog] 802.11n Wireless +pci:v000011ABd00002B36* + ID_MODEL_FROM_DATABASE=88W8764 [Avastar] 802.11n Wireless + pci:v000011ABd00004101* ID_MODEL_FROM_DATABASE=OLPC Cafe Controller Secure Digital Controller @@ -35397,13 +35715,28 @@ pci:v0000123E* ID_VENDOR_FROM_DATABASE=Simutech, Inc. pci:v0000123F* - ID_VENDOR_FROM_DATABASE=C-Cube Microsystems + ID_VENDOR_FROM_DATABASE=LSI Logic pci:v0000123Fd000000E4* ID_MODEL_FROM_DATABASE=MPEG pci:v0000123Fd00008120* - ID_MODEL_FROM_DATABASE=E4? + ID_MODEL_FROM_DATABASE=DVxplore Codec + +pci:v0000123Fd00008120sv000010DEsd000001E1* + ID_MODEL_FROM_DATABASE=NVTV PAL + +pci:v0000123Fd00008120sv000010DEsd000001E2* + ID_MODEL_FROM_DATABASE=NVTV NTSC + +pci:v0000123Fd00008120sv000010DEsd000001E3* + ID_MODEL_FROM_DATABASE=NVTV PAL + +pci:v0000123Fd00008120sv000010DEsd00000248* + ID_MODEL_FROM_DATABASE=NVTV NTSC + +pci:v0000123Fd00008120sv000010DEsd00000249* + ID_MODEL_FROM_DATABASE=NVTV PAL pci:v0000123Fd00008120sv000011BDsd00000006* ID_MODEL_FROM_DATABASE=DV500 E4 @@ -35969,6 +36302,9 @@ pci:v0000126Fd00000710* pci:v0000126Fd00000712* ID_MODEL_FROM_DATABASE=SM712 LynxEM+ +pci:v0000126Fd00000718* + ID_MODEL_FROM_DATABASE=SM718 LynxSE+ + pci:v0000126Fd00000720* ID_MODEL_FROM_DATABASE=SM720 Lynx3DM @@ -37496,6 +37832,9 @@ pci:v000012EBd00000001sv000012EBsd00000001* pci:v000012EBd00000001sv00005053sd00003355* ID_MODEL_FROM_DATABASE=Montego +pci:v000012EBd00000001sv000050B2sd00001111* + ID_MODEL_FROM_DATABASE=XLerate + pci:v000012EBd00000002* ID_MODEL_FROM_DATABASE=Vortex 2 @@ -40586,6 +40925,9 @@ pci:v00001425d00004086* pci:v00001425d00004087* ID_MODEL_FROM_DATABASE=T440T-4087 Unified Wire Ethernet Controller +pci:v00001425d00004088* + ID_MODEL_FROM_DATABASE=T440-4088 Unified Wire Ethernet Controller + pci:v00001425d00004401* ID_MODEL_FROM_DATABASE=T420-CR Unified Wire Ethernet Controller @@ -40655,6 +40997,9 @@ pci:v00001425d00004486* pci:v00001425d00004487* ID_MODEL_FROM_DATABASE=T440T-4087 Unified Wire Ethernet Controller +pci:v00001425d00004488* + ID_MODEL_FROM_DATABASE=T440-4088 Unified Wire Ethernet Controller + pci:v00001425d00004501* ID_MODEL_FROM_DATABASE=T420-CR Unified Wire Storage Controller @@ -40724,6 +41069,9 @@ pci:v00001425d00004586* pci:v00001425d00004587* ID_MODEL_FROM_DATABASE=T440T-4087 Unified Wire Storage Controller +pci:v00001425d00004588* + ID_MODEL_FROM_DATABASE=T440-4088 Unified Wire Storage Controller + pci:v00001425d00004601* ID_MODEL_FROM_DATABASE=T420-CR Unified Wire Storage Controller @@ -40793,6 +41141,9 @@ pci:v00001425d00004686* pci:v00001425d00004687* ID_MODEL_FROM_DATABASE=T440T-4087 Unified Wire Storage Controller +pci:v00001425d00004688* + ID_MODEL_FROM_DATABASE=T440-4088 Unified Wire Storage Controller + pci:v00001425d00004701* ID_MODEL_FROM_DATABASE=T420-CR Unified Wire Ethernet Controller @@ -40862,6 +41213,9 @@ pci:v00001425d00004786* pci:v00001425d00004787* ID_MODEL_FROM_DATABASE=T440T-4087 Unified Wire Ethernet Controller +pci:v00001425d00004788* + ID_MODEL_FROM_DATABASE=T440-4088 Unified Wire Ethernet Controller + pci:v00001425d00004801* ID_MODEL_FROM_DATABASE=T420-CR Unified Wire Ethernet Controller @@ -40931,6 +41285,9 @@ pci:v00001425d00004886* pci:v00001425d00004887* ID_MODEL_FROM_DATABASE=T440T-4087 Unified Wire Ethernet Controller +pci:v00001425d00004888* + ID_MODEL_FROM_DATABASE=T440-4088 Unified Wire Ethernet Controller + pci:v00001425d00005001* ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Ethernet Controller @@ -40988,6 +41345,15 @@ pci:v00001425d00005012* pci:v00001425d00005013* ID_MODEL_FROM_DATABASE=T580-CR Unified Wire Ethernet Controller +pci:v00001425d00005014* + ID_MODEL_FROM_DATABASE=T580-LP-SO-CR Unified Wire Ethernet Controller + +pci:v00001425d00005080* + ID_MODEL_FROM_DATABASE=T540-5080 Unified Wire Ethernet Controller + +pci:v00001425d00005081* + ID_MODEL_FROM_DATABASE=T540-5081 Unified Wire Ethernet Controller + pci:v00001425d00005401* ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Ethernet Controller @@ -41045,6 +41411,15 @@ pci:v00001425d00005412* pci:v00001425d00005413* ID_MODEL_FROM_DATABASE=T580-CR Unified Wire Ethernet Controller +pci:v00001425d00005414* + ID_MODEL_FROM_DATABASE=T580-LP-SO-CR Unified Wire Ethernet Controller + +pci:v00001425d00005480* + ID_MODEL_FROM_DATABASE=T540-5080 Unified Wire Ethernet Controller + +pci:v00001425d00005481* + ID_MODEL_FROM_DATABASE=T540-5081 Unified Wire Ethernet Controller + pci:v00001425d00005501* ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Storage Controller @@ -41102,6 +41477,15 @@ pci:v00001425d00005512* pci:v00001425d00005513* ID_MODEL_FROM_DATABASE=T580-CR Unified Wire Storage Controller +pci:v00001425d00005514* + ID_MODEL_FROM_DATABASE=T580-LP-SO-CR Unified Wire Storage Controller + +pci:v00001425d00005580* + ID_MODEL_FROM_DATABASE=T540-5080 Unified Wire Storage Controller + +pci:v00001425d00005581* + ID_MODEL_FROM_DATABASE=T540-5081 Unified Wire Storage Controller + pci:v00001425d00005601* ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Storage Controller @@ -41159,6 +41543,15 @@ pci:v00001425d00005612* pci:v00001425d00005613* ID_MODEL_FROM_DATABASE=T580-CR Unified Wire Storage Controller +pci:v00001425d00005614* + ID_MODEL_FROM_DATABASE=T580-LP-SO-CR Unified Wire Storage Controller + +pci:v00001425d00005680* + ID_MODEL_FROM_DATABASE=T540-5080 Unified Wire Storage Controller + +pci:v00001425d00005681* + ID_MODEL_FROM_DATABASE=T540-5081 Unified Wire Storage Controller + pci:v00001425d00005701* ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Ethernet Controller @@ -41216,6 +41609,15 @@ pci:v00001425d00005712* pci:v00001425d00005713* ID_MODEL_FROM_DATABASE=T580-CR Unified Wire Ethernet Controller +pci:v00001425d00005714* + ID_MODEL_FROM_DATABASE=T580-LP-SO-CR Unified Wire Ethernet Controller + +pci:v00001425d00005780* + ID_MODEL_FROM_DATABASE=T540-5080 Unified Wire Ethernet Controller + +pci:v00001425d00005781* + ID_MODEL_FROM_DATABASE=T540-5081 Unified Wire Ethernet Controller + pci:v00001425d00005801* ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Ethernet Controller @@ -41273,6 +41675,15 @@ pci:v00001425d00005812* pci:v00001425d00005813* ID_MODEL_FROM_DATABASE=T580-CR Unified Wire Ethernet Controller +pci:v00001425d00005814* + ID_MODEL_FROM_DATABASE=T580-LP-SO-CR Unified Wire Ethernet Controller + +pci:v00001425d00005880* + ID_MODEL_FROM_DATABASE=T540-5080 Unified Wire Ethernet Controller + +pci:v00001425d00005881* + ID_MODEL_FROM_DATABASE=T540-5081 Unified Wire Ethernet Controller + pci:v00001425d0000A000* ID_MODEL_FROM_DATABASE=PE10K Unified Wire Ethernet Controller @@ -43118,6 +43529,9 @@ pci:v000014E4d000016B0* pci:v000014E4d000016B1* ID_MODEL_FROM_DATABASE=NetLink BCM57781 Gigabit Ethernet PCIe +pci:v000014E4d000016B1sv00001849sd000096B1* + ID_MODEL_FROM_DATABASE=Z77 Extreme4 motherboard + pci:v000014E4d000016B2* ID_MODEL_FROM_DATABASE=NetLink BCM57791 Gigabit Ethernet PCIe @@ -43854,7 +44268,7 @@ pci:v000014E4d00004714* ID_MODEL_FROM_DATABASE=BCM47xx Sentry5 External Interface pci:v000014E4d00004715* - ID_MODEL_FROM_DATABASE=Sentry5 USB Controller + ID_MODEL_FROM_DATABASE=BCM47xx Sentry5 USB / Ethernet Controller pci:v000014E4d00004716* ID_MODEL_FROM_DATABASE=BCM47xx Sentry5 USB Host Controller @@ -44144,6 +44558,9 @@ pci:v000014F1d00001055* pci:v000014F1d00001056* ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp Modem (Worldwide) +pci:v000014F1d00001056sv0000122Dsd00004035* + ID_MODEL_FROM_DATABASE=MDP3900V-W + pci:v000014F1d00001057* ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp Modem (Worldwide) @@ -45360,7 +45777,13 @@ pci:v00001555* ID_VENDOR_FROM_DATABASE=GESYTEC GmBH pci:v00001556* - ID_VENDOR_FROM_DATABASE=PLD APPLICATIONS + ID_VENDOR_FROM_DATABASE=PLDA + +pci:v00001556d00001100* + ID_MODEL_FROM_DATABASE=PCI Express Core Reference Design + +pci:v00001556d0000110F* + ID_MODEL_FROM_DATABASE=PCI Express Core Reference Design Virtual Function pci:v00001557* ID_VENDOR_FROM_DATABASE=MEDIASTAR Co Ltd @@ -46382,6 +46805,9 @@ pci:v00001619d00000640* pci:v00001619d00001610* ID_MODEL_FROM_DATABASE=FarSync TE1 (T1,E1) +pci:v00001619d00001612* + ID_MODEL_FROM_DATABASE=FarSync TE1 PCI Express (T1,E1) + pci:v00001619d00002610* ID_MODEL_FROM_DATABASE=FarSync DSL-S1 (SHDSL) @@ -46491,7 +46917,7 @@ pci:v00001657d00000021* ID_MODEL_FROM_DATABASE=804 8Gbps FC HBA for HP Bladesystem c-class pci:v00001657d00000022* - ID_MODEL_FROM_DATABASE=1867/1860: 16Gbps/10Gbps Fabric Adapter + ID_MODEL_FROM_DATABASE=1860 16Gbps/10Gbps Fabric Adapter pci:v00001657d00000022sv00001657sd00000022* ID_MODEL_FROM_DATABASE=10Gbps CNA - FCOE @@ -46503,7 +46929,7 @@ pci:v00001657d00000022sv00001657sd00000024* ID_MODEL_FROM_DATABASE=16Gbps FC HBA pci:v00001657d00000023* - ID_MODEL_FROM_DATABASE=1869 16Gbps FC HBA + ID_MODEL_FROM_DATABASE=1867/1869 16Gbps FC HBA pci:v00001657d00000646* ID_MODEL_FROM_DATABASE=400 4Gbps PCIe FC HBA @@ -46520,6 +46946,9 @@ pci:v0000165Ad0000D200* pci:v0000165Ad0000D300* ID_MODEL_FROM_DATABASE=PIXCI(R) D3X Digital Video Capture Board [custom QL5232] +pci:v0000165Ad0000EB01* + ID_MODEL_FROM_DATABASE=PIXCI(R) EB1 PCI Camera Link Video Capture Board + pci:v0000165D* ID_VENDOR_FROM_DATABASE=Hsing Tech. Enterprise Co., Ltd. @@ -48779,6 +49208,9 @@ pci:v000018DD* pci:v000018DDd00004C6F* ID_MODEL_FROM_DATABASE=Artimi RTMI-100 UWB adapter +pci:v000018DF* + ID_VENDOR_FROM_DATABASE=LeWiz Communications + pci:v000018E6* ID_VENDOR_FROM_DATABASE=MPL AG @@ -49373,6 +49805,15 @@ pci:v00001924d00000813sv00001924sd00007104* pci:v00001924d00000813sv00001924sd00007904* ID_MODEL_FROM_DATABASE=SFN5151T-R4 10GBASE-T Server Adapter +pci:v00001924d00000903* + ID_MODEL_FROM_DATABASE=SFC9120 + +pci:v00001924d00000903sv00001924sd00008002* + ID_MODEL_FROM_DATABASE=SFN7122F-R1 SFP+ Server Adapter + +pci:v00001924d00000903sv00001924sd00008006* + ID_MODEL_FROM_DATABASE=SFN7022F-R1 SFP+ Server Adapter + pci:v00001924d00001803* ID_MODEL_FROM_DATABASE=SFC9020 Virtual Function [Solarstorm] @@ -50261,6 +50702,9 @@ pci:v00001A4Ad00001010* pci:v00001A4Ad00002000* ID_MODEL_FROM_DATABASE=PGPCard - 4 Lane +pci:v00001A4Ad00002001* + ID_MODEL_FROM_DATABASE=PGPCard - 8 Lane Plus EVR + pci:v00001A4Ad00002010* ID_MODEL_FROM_DATABASE=PCI-Express EVR @@ -50603,12 +51047,21 @@ pci:v00001B21d00000611* pci:v00001B21d00000612* ID_MODEL_FROM_DATABASE=ASM1062 Serial ATA Controller +pci:v00001B21d00000612sv00001849sd00000612* + ID_MODEL_FROM_DATABASE=Motherboard + pci:v00001B21d00001042* ID_MODEL_FROM_DATABASE=ASM1042 SuperSpeed USB Host Controller +pci:v00001B21d00001042sv00001849sd00001042* + ID_MODEL_FROM_DATABASE=Motherboard + pci:v00001B21d00001080* ID_MODEL_FROM_DATABASE=ASM1083/1085 PCIe to PCI Bridge +pci:v00001B21d00001080sv00001849sd00001080* + ID_MODEL_FROM_DATABASE=Motherboard + pci:v00001B2C* ID_VENDOR_FROM_DATABASE=Opal-RT Technologies Inc. @@ -50822,6 +51275,9 @@ pci:v00001BBFd00000004* pci:v00001BF4* ID_VENDOR_FROM_DATABASE=VTI Instruments Corporation +pci:v00001BFD* + ID_VENDOR_FROM_DATABASE=EeeTOP + pci:v00001C1C* ID_VENDOR_FROM_DATABASE=Symphony @@ -50864,6 +51320,12 @@ pci:v00001C8Ad00000001* pci:v00001CB1* ID_VENDOR_FROM_DATABASE=Collion UG & Co.KG +pci:v00001CC5* + ID_VENDOR_FROM_DATABASE=Embedded Intelligence, Inc. + +pci:v00001CC5d00000100* + ID_MODEL_FROM_DATABASE=CAN-PCIe-02 + pci:v00001D44* ID_VENDOR_FROM_DATABASE=DPT @@ -51998,9 +52460,6 @@ pci:v00005053d00002010* pci:v000050B2* ID_VENDOR_FROM_DATABASE=TerraTec Electronic GmbH -pci:v000050B2d00001111* - ID_MODEL_FROM_DATABASE=Terratec XLerate - pci:v00005136* ID_VENDOR_FROM_DATABASE=S S Technologies @@ -52967,6 +53426,9 @@ pci:v00008086d00000150* pci:v00008086d00000150sv00001043sd000084CA* ID_MODEL_FROM_DATABASE=P8H77-I Motherboard +pci:v00008086d00000150sv00001849sd00000150* + ID_MODEL_FROM_DATABASE=Motherboard + pci:v00008086d00000151* ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor PCI Express Root Port @@ -52991,6 +53453,9 @@ pci:v00008086d00000153sv00001043sd00001517* pci:v00008086d00000154* ID_MODEL_FROM_DATABASE=3rd Gen Core processor DRAM Controller +pci:v00008086d00000154sv00001025sd00000813* + ID_MODEL_FROM_DATABASE=Aspire R7-571 + pci:v00008086d00000154sv0000103Csd000017F6* ID_MODEL_FROM_DATABASE=ProBook 4540s @@ -53027,6 +53492,9 @@ pci:v00008086d0000015E* pci:v00008086d00000162* ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller +pci:v00008086d00000162sv00001849sd00000162* + ID_MODEL_FROM_DATABASE=Motherboard + pci:v00008086d00000166* ID_MODEL_FROM_DATABASE=3rd Gen Core processor Graphics Controller @@ -55061,6 +55529,9 @@ pci:v00008086d0000105Esv00001775sd00001100* pci:v00008086d0000105Esv00001775sd00006003* ID_MODEL_FROM_DATABASE=Telum GE-QT +pci:v00008086d0000105Esv000018DFsd00001214* + ID_MODEL_FROM_DATABASE=2x 1GbE, PCIe x1, dual Intel 82571EB chips + pci:v00008086d0000105Esv00008086sd0000005E* ID_MODEL_FROM_DATABASE=PRO/1000 PT Dual Port Server Connection @@ -55806,7 +56277,7 @@ pci:v00008086d000010F9* ID_MODEL_FROM_DATABASE=82599 10 Gigabit Dual Port Network Connection pci:v00008086d000010FB* - ID_MODEL_FROM_DATABASE=82599EB 10-Gigabit SFI/SFP+ Network Connection + ID_MODEL_FROM_DATABASE=82599ES 10-Gigabit SFI/SFP+ Network Connection pci:v00008086d000010FBsv00001028sd00001F72* ID_MODEL_FROM_DATABASE=Ethernet 10G 4P X520/I350 rNDC @@ -57578,6 +58049,9 @@ pci:v00008086d00001E02* pci:v00008086d00001E02sv00001043sd000084CA* ID_MODEL_FROM_DATABASE=P8H77-I Motherboard +pci:v00008086d00001E02sv00001849sd00001E02* + ID_MODEL_FROM_DATABASE=Motherboard + pci:v00008086d00001E03* ID_MODEL_FROM_DATABASE=7 Series Chipset Family 6-port SATA Controller [AHCI mode] @@ -57620,6 +58094,9 @@ pci:v00008086d00001E10sv00001043sd00001517* pci:v00008086d00001E10sv00001043sd000084CA* ID_MODEL_FROM_DATABASE=P8H77-I Motherboard +pci:v00008086d00001E10sv00001849sd00001E10* + ID_MODEL_FROM_DATABASE=Motherboard + pci:v00008086d00001E12* ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 2 @@ -57638,21 +58115,33 @@ pci:v00008086d00001E16* pci:v00008086d00001E16sv00001043sd00001477* ID_MODEL_FROM_DATABASE=N56VZ +pci:v00008086d00001E16sv00001849sd00001618* + ID_MODEL_FROM_DATABASE=Z77 Extreme4 motherboard + pci:v00008086d00001E18* ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 5 pci:v00008086d00001E18sv00001043sd000084CA* ID_MODEL_FROM_DATABASE=P8H77-I Motherboard +pci:v00008086d00001E18sv00001849sd00001E18* + ID_MODEL_FROM_DATABASE=Motherboard + pci:v00008086d00001E1A* ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 6 +pci:v00008086d00001E1Asv00001849sd00001E1A* + ID_MODEL_FROM_DATABASE=Motherboard + pci:v00008086d00001E1C* ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 7 pci:v00008086d00001E1E* ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 8 +pci:v00008086d00001E1Esv00001849sd00001E1E* + ID_MODEL_FROM_DATABASE=Motherboard + pci:v00008086d00001E20* ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family High Definition Audio Controller @@ -57665,6 +58154,9 @@ pci:v00008086d00001E20sv00001043sd00001517* pci:v00008086d00001E20sv00001043sd00008415* ID_MODEL_FROM_DATABASE=P8H77-I Motherboard +pci:v00008086d00001E20sv00001849sd00001898* + ID_MODEL_FROM_DATABASE=Z77 Extreme4 motherboard + pci:v00008086d00001E22* ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family SMBus Controller @@ -57677,6 +58169,9 @@ pci:v00008086d00001E22sv00001043sd00001517* pci:v00008086d00001E22sv00001043sd000084CA* ID_MODEL_FROM_DATABASE=P8H77-I Motherboard +pci:v00008086d00001E22sv00001849sd00001E22* + ID_MODEL_FROM_DATABASE=Motherboard + pci:v00008086d00001E24* ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family Thermal Management Controller @@ -57698,6 +58193,9 @@ pci:v00008086d00001E26sv00001043sd00001517* pci:v00008086d00001E26sv00001043sd000084CA* ID_MODEL_FROM_DATABASE=P8H77-I Motherboard +pci:v00008086d00001E26sv00001849sd00001E26* + ID_MODEL_FROM_DATABASE=Motherboard + pci:v00008086d00001E2D* ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family USB Enhanced Host Controller #2 @@ -57710,6 +58208,9 @@ pci:v00008086d00001E2Dsv00001043sd00001517* pci:v00008086d00001E2Dsv00001043sd000084CA* ID_MODEL_FROM_DATABASE=P8H77-I Motherboard +pci:v00008086d00001E2Dsv00001849sd00001E2D* + ID_MODEL_FROM_DATABASE=Motherboard + pci:v00008086d00001E31* ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family USB xHCI Host Controller @@ -57722,6 +58223,9 @@ pci:v00008086d00001E31sv00001043sd00001517* pci:v00008086d00001E31sv00001043sd000084CA* ID_MODEL_FROM_DATABASE=P8H77-I Motherboard +pci:v00008086d00001E31sv00001849sd00001E31* + ID_MODEL_FROM_DATABASE=Motherboard + pci:v00008086d00001E33* ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family LAN Controller @@ -57737,6 +58241,9 @@ pci:v00008086d00001E3Asv00001043sd00001517* pci:v00008086d00001E3Asv00001043sd000084CA* ID_MODEL_FROM_DATABASE=P8H77-I Motherboard +pci:v00008086d00001E3Asv00001849sd00001E3A* + ID_MODEL_FROM_DATABASE=Motherboard + pci:v00008086d00001E3B* ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family MEI Controller #2 @@ -57758,6 +58265,9 @@ pci:v00008086d00001E43* pci:v00008086d00001E44* ID_MODEL_FROM_DATABASE=Z77 Express Chipset LPC Controller +pci:v00008086d00001E44sv00001849sd00001E44* + ID_MODEL_FROM_DATABASE=Motherboard + pci:v00008086d00001E45* ID_MODEL_FROM_DATABASE=7 Series Chipset Family LPC Controller @@ -57849,172 +58359,172 @@ pci:v00008086d00001E5F* ID_MODEL_FROM_DATABASE=7 Series Chipset Family LPC Controller pci:v00008086d00001F00* - ID_MODEL_FROM_DATABASE=Avoton SSA-Cunit + ID_MODEL_FROM_DATABASE=Atom processor C2000 SoC Transaction Router pci:v00008086d00001F01* - ID_MODEL_FROM_DATABASE=Avoton SSA-Cunit + ID_MODEL_FROM_DATABASE=Atom processor C2000 SoC Transaction Router pci:v00008086d00001F02* - ID_MODEL_FROM_DATABASE=Avoton SSA-Cunit + ID_MODEL_FROM_DATABASE=Atom processor C2000 SoC Transaction Router pci:v00008086d00001F03* - ID_MODEL_FROM_DATABASE=Avoton SSA-Cunit + ID_MODEL_FROM_DATABASE=Atom processor C2000 SoC Transaction Router pci:v00008086d00001F04* - ID_MODEL_FROM_DATABASE=Avoton SSA-Cunit + ID_MODEL_FROM_DATABASE=Atom processor C2000 SoC Transaction Router pci:v00008086d00001F05* - ID_MODEL_FROM_DATABASE=Avoton SSA-Cunit + ID_MODEL_FROM_DATABASE=Atom processor C2000 SoC Transaction Router pci:v00008086d00001F06* - ID_MODEL_FROM_DATABASE=Avoton SSA-Cunit + ID_MODEL_FROM_DATABASE=Atom processor C2000 SoC Transaction Router pci:v00008086d00001F07* - ID_MODEL_FROM_DATABASE=Avoton SSA-Cunit + ID_MODEL_FROM_DATABASE=Atom processor C2000 SoC Transaction Router pci:v00008086d00001F08* - ID_MODEL_FROM_DATABASE=Avoton SSA-Cunit + ID_MODEL_FROM_DATABASE=Atom processor C2000 SoC Transaction Router pci:v00008086d00001F09* - ID_MODEL_FROM_DATABASE=Avoton SSA-Cunit + ID_MODEL_FROM_DATABASE=Atom processor C2000 SoC Transaction Router pci:v00008086d00001F0A* - ID_MODEL_FROM_DATABASE=Avoton SSA-Cunit + ID_MODEL_FROM_DATABASE=Atom processor C2000 SoC Transaction Router pci:v00008086d00001F0B* - ID_MODEL_FROM_DATABASE=Avoton SSA-Cunit + ID_MODEL_FROM_DATABASE=Atom processor C2000 SoC Transaction Router pci:v00008086d00001F0C* - ID_MODEL_FROM_DATABASE=Avoton SSA-Cunit + ID_MODEL_FROM_DATABASE=Atom processor C2000 SoC Transaction Router pci:v00008086d00001F0D* - ID_MODEL_FROM_DATABASE=Avoton SSA-Cunit + ID_MODEL_FROM_DATABASE=Atom processor C2000 SoC Transaction Router pci:v00008086d00001F0E* - ID_MODEL_FROM_DATABASE=Avoton SSA-Cunit + ID_MODEL_FROM_DATABASE=Atom processor C2000 SoC Transaction Router pci:v00008086d00001F0F* - ID_MODEL_FROM_DATABASE=Avoton SSA-Cunit + ID_MODEL_FROM_DATABASE=Atom processor C2000 SoC Transaction Router pci:v00008086d00001F10* - ID_MODEL_FROM_DATABASE=Avoton PCIe Root Port 1 + ID_MODEL_FROM_DATABASE=Atom processor C2000 PCIe Root Port 1 pci:v00008086d00001F11* - ID_MODEL_FROM_DATABASE=Avoton PCIe Root Port 2 + ID_MODEL_FROM_DATABASE=Atom processor C2000 PCIe Root Port 2 pci:v00008086d00001F12* - ID_MODEL_FROM_DATABASE=Avoton PCIe Root Port 3 + ID_MODEL_FROM_DATABASE=Atom processor C2000 PCIe Root Port 3 pci:v00008086d00001F13* - ID_MODEL_FROM_DATABASE=Avoton PCIe Root Port 4 + ID_MODEL_FROM_DATABASE=Atom processor C2000 PCIe Root Port 4 pci:v00008086d00001F14* - ID_MODEL_FROM_DATABASE=Avoton RAS + ID_MODEL_FROM_DATABASE=Atom processor C2000 RAS pci:v00008086d00001F15* - ID_MODEL_FROM_DATABASE=Avoton SMBus 2.0 + ID_MODEL_FROM_DATABASE=Atom processor C2000 SMBus 2.0 pci:v00008086d00001F16* - ID_MODEL_FROM_DATABASE=Avoton RCEC + ID_MODEL_FROM_DATABASE=Atom processor C2000 RCEC pci:v00008086d00001F18* - ID_MODEL_FROM_DATABASE=Avoton nCPM + ID_MODEL_FROM_DATABASE=Atom processor C2000 nCPM pci:v00008086d00001F19* - ID_MODEL_FROM_DATABASE=Avoton nCPM + ID_MODEL_FROM_DATABASE=Atom processor C2000 nCPM pci:v00008086d00001F20* - ID_MODEL_FROM_DATABASE=Avoton 4-Port IDE SATA2 Controller + ID_MODEL_FROM_DATABASE=Atom processor C2000 4-Port IDE SATA2 Controller pci:v00008086d00001F21* - ID_MODEL_FROM_DATABASE=Avoton 4-Port IDE SATA2 Controller + ID_MODEL_FROM_DATABASE=Atom processor C2000 4-Port IDE SATA2 Controller pci:v00008086d00001F22* - ID_MODEL_FROM_DATABASE=Avoton AHCI SATA2 Controller + ID_MODEL_FROM_DATABASE=Atom processor C2000 AHCI SATA2 Controller pci:v00008086d00001F23* - ID_MODEL_FROM_DATABASE=Avoton AHCI SATA2 Controller + ID_MODEL_FROM_DATABASE=Atom processor C2000 AHCI SATA2 Controller pci:v00008086d00001F24* - ID_MODEL_FROM_DATABASE=Avoton RAID SATA2 Controller + ID_MODEL_FROM_DATABASE=Atom processor C2000 RAID SATA2 Controller pci:v00008086d00001F25* - ID_MODEL_FROM_DATABASE=Avoton RAID SATA2 Controller + ID_MODEL_FROM_DATABASE=Atom processor C2000 RAID SATA2 Controller pci:v00008086d00001F26* - ID_MODEL_FROM_DATABASE=Avoton RAID SATA2 Controller + ID_MODEL_FROM_DATABASE=Atom processor C2000 RAID SATA2 Controller pci:v00008086d00001F27* - ID_MODEL_FROM_DATABASE=Avoton RAID SATA2 Controller + ID_MODEL_FROM_DATABASE=Atom processor C2000 RAID SATA2 Controller pci:v00008086d00001F2C* - ID_MODEL_FROM_DATABASE=Avoton USB Enhanced Host Controller + ID_MODEL_FROM_DATABASE=Atom processor C2000 USB Enhanced Host Controller pci:v00008086d00001F2E* - ID_MODEL_FROM_DATABASE=Avoton RAID SATA2 Controller + ID_MODEL_FROM_DATABASE=Atom processor C2000 RAID SATA2 Controller pci:v00008086d00001F2F* - ID_MODEL_FROM_DATABASE=Avoton RAID SATA2 Controller + ID_MODEL_FROM_DATABASE=Atom processor C2000 RAID SATA2 Controller pci:v00008086d00001F30* - ID_MODEL_FROM_DATABASE=Avoton 2-Port IDE SATA3 Controller + ID_MODEL_FROM_DATABASE=Atom processor C2000 2-Port IDE SATA3 Controller pci:v00008086d00001F31* - ID_MODEL_FROM_DATABASE=Avoton 2-Port IDE SATA3 Controller + ID_MODEL_FROM_DATABASE=Atom processor C2000 2-Port IDE SATA3 Controller pci:v00008086d00001F32* - ID_MODEL_FROM_DATABASE=Avoton AHCI SATA3 Controller + ID_MODEL_FROM_DATABASE=Atom processor C2000 AHCI SATA3 Controller pci:v00008086d00001F33* - ID_MODEL_FROM_DATABASE=Avoton AHCI SATA3 Controller + ID_MODEL_FROM_DATABASE=Atom processor C2000 AHCI SATA3 Controller pci:v00008086d00001F34* - ID_MODEL_FROM_DATABASE=Avoton RAID SATA3 Controller + ID_MODEL_FROM_DATABASE=Atom processor C2000 RAID SATA3 Controller pci:v00008086d00001F35* - ID_MODEL_FROM_DATABASE=Avoton RAID SATA3 Controller + ID_MODEL_FROM_DATABASE=Atom processor C2000 RAID SATA3 Controller pci:v00008086d00001F36* - ID_MODEL_FROM_DATABASE=Avoton RAID SATA3 Controller + ID_MODEL_FROM_DATABASE=Atom processor C2000 RAID SATA3 Controller pci:v00008086d00001F37* - ID_MODEL_FROM_DATABASE=Avoton RAID SATA3 Controller + ID_MODEL_FROM_DATABASE=Atom processor C2000 RAID SATA3 Controller pci:v00008086d00001F38* - ID_MODEL_FROM_DATABASE=Avoton PCU + ID_MODEL_FROM_DATABASE=Atom processor C2000 PCU pci:v00008086d00001F39* - ID_MODEL_FROM_DATABASE=Avoton PCU + ID_MODEL_FROM_DATABASE=Atom processor C2000 PCU pci:v00008086d00001F3A* - ID_MODEL_FROM_DATABASE=Avoton PCU + ID_MODEL_FROM_DATABASE=Atom processor C2000 PCU pci:v00008086d00001F3B* - ID_MODEL_FROM_DATABASE=Avoton PCU + ID_MODEL_FROM_DATABASE=Atom processor C2000 PCU pci:v00008086d00001F3C* - ID_MODEL_FROM_DATABASE=Avoton PCU SMBus - -pci:v00008086d00001F3D* - ID_MODEL_FROM_DATABASE=Avoton PCU SMBus + ID_MODEL_FROM_DATABASE=Atom processor C2000 PCU SMBus pci:v00008086d00001F3E* - ID_MODEL_FROM_DATABASE=Avoton RAID SATA3 Controller + ID_MODEL_FROM_DATABASE=Atom processor C2000 RAID SATA3 Controller pci:v00008086d00001F3F* - ID_MODEL_FROM_DATABASE=Avoton RAID SATA3 Controller + ID_MODEL_FROM_DATABASE=Atom processor C2000 RAID SATA3 Controller pci:v00008086d00001F40* ID_MODEL_FROM_DATABASE=Ethernet Connection I354 1.0 GbE Backplane +pci:v00008086d00001F40sv00001028sd000010F1* + ID_MODEL_FROM_DATABASE=Ethernet Connection I354 1.0 GbE Backplane + pci:v00008086d00001F41* ID_MODEL_FROM_DATABASE=Ethernet Connection I354 pci:v00008086d00001F42* - ID_MODEL_FROM_DATABASE=Avoton GbE + ID_MODEL_FROM_DATABASE=Atom processor C2000 GbE pci:v00008086d00001F44* - ID_MODEL_FROM_DATABASE=Avoton GbE Virtual Function + ID_MODEL_FROM_DATABASE=Atom processor C2000 GbE Virtual Function pci:v00008086d00001F45* ID_MODEL_FROM_DATABASE=Ethernet Connection I354 2.5 GbE Backplane @@ -58413,7 +58923,7 @@ pci:v00008086d00002448sv00001734sd00001055* ID_MODEL_FROM_DATABASE=Amilo M1420 pci:v00008086d00002448sv000017AAsd000020AE* - ID_MODEL_FROM_DATABASE=ThinkPad T61 + ID_MODEL_FROM_DATABASE=ThinkPad T61/R61 pci:v00008086d00002448sv00008086sd0000544B* ID_MODEL_FROM_DATABASE=Desktop Board D425KT @@ -62262,7 +62772,7 @@ pci:v00008086d00002811sv0000103Csd000030C1* ID_MODEL_FROM_DATABASE=Compaq 6910p pci:v00008086d00002811sv000017AAsd000020B6* - ID_MODEL_FROM_DATABASE=T61 + ID_MODEL_FROM_DATABASE=ThinkPad T61/R61 pci:v00008086d00002811sv0000E4BFsd0000CC47* ID_MODEL_FROM_DATABASE=CCG-RUMBA @@ -62376,7 +62886,7 @@ pci:v00008086d00002829sv0000104Dsd0000902D* ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E pci:v00008086d00002829sv000017AAsd000020A7* - ID_MODEL_FROM_DATABASE=ThinkPad T61 + ID_MODEL_FROM_DATABASE=ThinkPad T61/R61 pci:v00008086d00002829sv0000E4BFsd0000CC47* ID_MODEL_FROM_DATABASE=CCG-RUMBA @@ -62427,7 +62937,7 @@ pci:v00008086d00002830sv00001462sd00007235* ID_MODEL_FROM_DATABASE=P965 Neo MS-7235 mainboard pci:v00008086d00002830sv000017AAsd000020AA* - ID_MODEL_FROM_DATABASE=ThinkPad T61 + ID_MODEL_FROM_DATABASE=ThinkPad T61/R61 pci:v00008086d00002830sv0000E4BFsd0000CC47* ID_MODEL_FROM_DATABASE=CCG-RUMBA @@ -62469,7 +62979,7 @@ pci:v00008086d00002831sv00001462sd00007235* ID_MODEL_FROM_DATABASE=P965 Neo MS-7235 mainboard pci:v00008086d00002831sv000017AAsd000020AA* - ID_MODEL_FROM_DATABASE=ThinkPad T61 + ID_MODEL_FROM_DATABASE=ThinkPad T61/R61 pci:v00008086d00002831sv0000E4BFsd0000CC47* ID_MODEL_FROM_DATABASE=CCG-RUMBA @@ -62508,7 +63018,7 @@ pci:v00008086d00002832sv0000104Dsd0000902D* ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E pci:v00008086d00002832sv000017AAsd000020AA* - ID_MODEL_FROM_DATABASE=ThinkPad T61 + ID_MODEL_FROM_DATABASE=ThinkPad T61/R61 pci:v00008086d00002832sv0000E4BFsd0000CC47* ID_MODEL_FROM_DATABASE=CCG-RUMBA @@ -62553,7 +63063,7 @@ pci:v00008086d00002834sv00001462sd00007235* ID_MODEL_FROM_DATABASE=P965 Neo MS-7235 mainboard pci:v00008086d00002834sv000017AAsd000020AA* - ID_MODEL_FROM_DATABASE=ThinkPad T61 + ID_MODEL_FROM_DATABASE=ThinkPad T61/R61 pci:v00008086d00002834sv0000E4BFsd0000CC47* ID_MODEL_FROM_DATABASE=CCG-RUMBA @@ -62589,7 +63099,7 @@ pci:v00008086d00002835sv0000104Dsd0000902D* ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E pci:v00008086d00002835sv000017AAsd000020AA* - ID_MODEL_FROM_DATABASE=ThinkPad T60 + ID_MODEL_FROM_DATABASE=Thinkpad T61/R61 pci:v00008086d00002835sv0000E4BFsd0000CC47* ID_MODEL_FROM_DATABASE=CCG-RUMBA @@ -62631,7 +63141,7 @@ pci:v00008086d00002836sv00001462sd00007235* ID_MODEL_FROM_DATABASE=P965 Neo MS-7235 mainboard pci:v00008086d00002836sv000017AAsd000020AB* - ID_MODEL_FROM_DATABASE=ThinkPad T61 + ID_MODEL_FROM_DATABASE=ThinkPad T61/R61 pci:v00008086d00002836sv0000E4BFsd0000CC47* ID_MODEL_FROM_DATABASE=CCG-RUMBA @@ -62667,7 +63177,7 @@ pci:v00008086d0000283Asv0000104Dsd0000902D* ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E pci:v00008086d0000283Asv000017AAsd000020AB* - ID_MODEL_FROM_DATABASE=ThinkPad T61 + ID_MODEL_FROM_DATABASE=ThinkPad T61/R61 pci:v00008086d0000283Asv0000E4BFsd0000CC47* ID_MODEL_FROM_DATABASE=CCG-RUMBA @@ -62703,7 +63213,7 @@ pci:v00008086d0000283Esv00001462sd00007235* ID_MODEL_FROM_DATABASE=P965 Neo MS-7235 mainboard pci:v00008086d0000283Esv000017AAsd000020A9* - ID_MODEL_FROM_DATABASE=ThinkPad T61 + ID_MODEL_FROM_DATABASE=ThinkPad T61/R61 pci:v00008086d0000283Esv0000E4BFsd0000CC47* ID_MODEL_FROM_DATABASE=CCG-RUMBA @@ -62721,7 +63231,7 @@ pci:v00008086d0000283Fsv0000104Dsd0000902D* ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E pci:v00008086d0000283Fsv000017AAsd000020AD* - ID_MODEL_FROM_DATABASE=ThinkPad T61 + ID_MODEL_FROM_DATABASE=ThinkPad T61/R61 pci:v00008086d00002841* ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 2 @@ -62733,7 +63243,7 @@ pci:v00008086d00002841sv0000104Dsd0000902D* ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E pci:v00008086d00002841sv000017AAsd000020AD* - ID_MODEL_FROM_DATABASE=ThinkPad T61 + ID_MODEL_FROM_DATABASE=ThinkPad T61/R61 pci:v00008086d00002843* ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 3 @@ -62742,13 +63252,13 @@ pci:v00008086d00002843sv0000104Dsd0000902D* ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E pci:v00008086d00002843sv000017AAsd000020AD* - ID_MODEL_FROM_DATABASE=ThinkPad T61 + ID_MODEL_FROM_DATABASE=ThinkPad T61/R61 pci:v00008086d00002845* ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 4 pci:v00008086d00002845sv000017AAsd000020AD* - ID_MODEL_FROM_DATABASE=ThinkPad T61 + ID_MODEL_FROM_DATABASE=ThinkPad T61/R61 pci:v00008086d00002847* ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 5 @@ -62760,7 +63270,7 @@ pci:v00008086d00002847sv0000103Csd000030C1* ID_MODEL_FROM_DATABASE=Compaq 6910p pci:v00008086d00002847sv000017AAsd000020AD* - ID_MODEL_FROM_DATABASE=ThinkPad T61 + ID_MODEL_FROM_DATABASE=ThinkPad T61/R61 pci:v00008086d00002849* ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 6 @@ -62826,7 +63336,7 @@ pci:v00008086d0000284Bsv000014F1sd00005051* ID_MODEL_FROM_DATABASE=Presario C700 pci:v00008086d0000284Bsv000017AAsd000020AC* - ID_MODEL_FROM_DATABASE=ThinkPad T61 + ID_MODEL_FROM_DATABASE=ThinkPad T61/R61 pci:v00008086d0000284Bsv00008384sd00007616* ID_MODEL_FROM_DATABASE=Dell Vostro 1400 @@ -62865,7 +63375,7 @@ pci:v00008086d00002850sv0000104Dsd0000902D* ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E pci:v00008086d00002850sv000017AAsd000020A6* - ID_MODEL_FROM_DATABASE=ThinkPad T61 + ID_MODEL_FROM_DATABASE=ThinkPad T61/R61 pci:v00008086d00002850sv0000E4BFsd0000CC47* ID_MODEL_FROM_DATABASE=CCG-RUMBA @@ -66078,7 +66588,7 @@ pci:v00008086d00003A3Csv00001043sd000082D4* ID_MODEL_FROM_DATABASE=P5Q Deluxe Motherboard pci:v00008086d00003A3Csv00001458sd00005006* - ID_MODEL_FROM_DATABASE=GA-EP45-DS5 Motherboard + ID_MODEL_FROM_DATABASE=Motherboard pci:v00008086d00003A3E* ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) HD Audio Controller @@ -68193,7 +68703,7 @@ pci:v00008086d00008D6E* ID_MODEL_FROM_DATABASE=Wellsburg sSATA Controller [RAID mode] pci:v00008086d00008D7C* - ID_MODEL_FROM_DATABASE=Wellsburg EPSS + ID_MODEL_FROM_DATABASE=Wellsburg SPSR pci:v00008086d00008D7D* ID_MODEL_FROM_DATABASE=Wellsburg MS SMBus 0 diff --git a/hwdb/20-usb-vendor-model.hwdb b/hwdb/20-usb-vendor-model.hwdb index f4ec816c69..da8385ef91 100644 --- a/hwdb/20-usb-vendor-model.hwdb +++ b/hwdb/20-usb-vendor-model.hwdb @@ -266,6 +266,12 @@ usb:v03EBp2310* usb:v03EBp2FE4* ID_MODEL_FROM_DATABASE=ATxmega32A4U DFU bootloader +usb:v03EBp2FF0* + ID_MODEL_FROM_DATABASE=atmega32u2 DFU bootloader + +usb:v03EBp2FFA* + ID_MODEL_FROM_DATABASE=at90usb162 DFU bootloader + usb:v03EBp2FFB* ID_MODEL_FROM_DATABASE=at90usb AVR DFU bootloader @@ -599,6 +605,9 @@ usb:v03F0p0917* usb:v03F0p0924* ID_MODEL_FROM_DATABASE=Modular Smartcard Keyboard +usb:v03F0p094A* + ID_MODEL_FROM_DATABASE=Optical Mouse [672662-001] + usb:v03F0p0A01* ID_MODEL_FROM_DATABASE=ScanJet 2400c @@ -2009,6 +2018,9 @@ usb:v0403p8040* usb:v0403p8070* ID_MODEL_FROM_DATABASE=7 Port Hub +usb:v0403p8210* + ID_MODEL_FROM_DATABASE=MGTimer - MGCC (Vic) Timing System + usb:v0403p8370* ID_MODEL_FROM_DATABASE=7 Port Hub @@ -2924,9 +2936,15 @@ usb:v040Ap1001* usb:v040Ap4000* ID_MODEL_FROM_DATABASE=InkJet Color Printer +usb:v040Ap4021* + ID_MODEL_FROM_DATABASE=Photo Printer 6800 + usb:v040Ap4022* ID_MODEL_FROM_DATABASE=1400 Digital Photo Printer +usb:v040Ap4034* + ID_MODEL_FROM_DATABASE=805 Photo Printer + usb:v040Ap4056* ID_MODEL_FROM_DATABASE=ESP 7200 Series AiO @@ -4293,7 +4311,7 @@ usb:v0424p7500* ID_MODEL_FROM_DATABASE=LAN7500 Ethernet 10/100/1000 Adapter usb:v0424p9512* - ID_MODEL_FROM_DATABASE=LAN9500 Ethernet 10/100 Adapter / SMSC9512/9514 Hub + ID_MODEL_FROM_DATABASE=SMC9512/9514 USB Hub usb:v0424pA700* ID_MODEL_FROM_DATABASE=2 Port Hub @@ -4877,6 +4895,9 @@ usb:v043Dp010F* usb:v043Dp0142* ID_MODEL_FROM_DATABASE=X3650 (Printer, Scanner, Copier) +usb:v043Dp01FA* + ID_MODEL_FROM_DATABASE=S310 series + usb:v043Dp4303* ID_MODEL_FROM_DATABASE=Xerox WorkCentre Pro 412 @@ -4898,6 +4919,9 @@ usb:v043Ep7001* usb:v043Ep7013* ID_MODEL_FROM_DATABASE=MP3 Player +usb:v043Ep70F5* + ID_MODEL_FROM_DATABASE=External HDD + usb:v043Ep8484* ID_MODEL_FROM_DATABASE=LPC-U30 Webcam II @@ -5157,7 +5181,7 @@ usb:v0451pDBC0* ID_MODEL_FROM_DATABASE=Device Bay Controller usb:v0451pE001* - ID_MODEL_FROM_DATABASE=GraphLink + ID_MODEL_FROM_DATABASE=GraphLink [SilverLink] usb:v0451pE003* ID_MODEL_FROM_DATABASE=TI-84 Plus Calculator @@ -5168,6 +5192,9 @@ usb:v0451pE004* usb:v0451pE008* ID_MODEL_FROM_DATABASE=TI-84 Plus Silver Calculator +usb:v0451pE012* + ID_MODEL_FROM_DATABASE=TI-Nspire Calculator + usb:v0451pF430* ID_MODEL_FROM_DATABASE=MSP-FET430UIF JTAG Tool @@ -5894,6 +5921,9 @@ usb:v045Ep029E* usb:v045Ep02A0* ID_MODEL_FROM_DATABASE=Xbox360 Big Button IR +usb:v045Ep02A1* + ID_MODEL_FROM_DATABASE=Xbox 360 Wireless Receiver for Windows + usb:v045Ep02A8* ID_MODEL_FROM_DATABASE=Xbox360 Wireless N Networking Adapter [Atheros AR7010+AR9280] @@ -5906,6 +5936,9 @@ usb:v045Ep02AE* usb:v045Ep02B0* ID_MODEL_FROM_DATABASE=Xbox NUI Motor +usb:v045Ep02B6* + ID_MODEL_FROM_DATABASE=Xbox 360 / Bluetooth Wireless Headset + usb:v045Ep0400* ID_MODEL_FROM_DATABASE=Windows Powered Pocket PC 2002 @@ -6371,6 +6404,9 @@ usb:v045Ep0779* usb:v045Ep930A* ID_MODEL_FROM_DATABASE=ISOUSB.SYS Intel 82930 Isochronous IO Test Board +usb:v045EpFFCA* + ID_MODEL_FROM_DATABASE=Catalina + usb:v045EpFFF8* ID_MODEL_FROM_DATABASE=Keyboard @@ -6626,6 +6662,9 @@ usb:v046Ap002D* usb:v046Ap003E* ID_MODEL_FROM_DATABASE=SmartTerminal ST-2xxx +usb:v046Ap0041* + ID_MODEL_FROM_DATABASE=G86 6240 Keyboard + usb:v046Ap0080* ID_MODEL_FROM_DATABASE=eHealth Terminal ST 1503 @@ -7043,6 +7082,9 @@ usb:v046Dp0A17* usb:v046Dp0A1F* ID_MODEL_FROM_DATABASE=G930 +usb:v046Dp0A29* + ID_MODEL_FROM_DATABASE=H600 [Wireless Headset] + usb:v046Dp0B02* ID_MODEL_FROM_DATABASE=C-UV35 [Bluetooth Mini-Receiver] (HID proxy mode) @@ -7232,6 +7274,9 @@ usb:v046DpC062* usb:v046DpC063* ID_MODEL_FROM_DATABASE=DELL Laser Mouse +usb:v046DpC066* + ID_MODEL_FROM_DATABASE=G9x Laser Mouse + usb:v046DpC068* ID_MODEL_FROM_DATABASE=G500 Laser Mouse @@ -7266,7 +7311,7 @@ usb:v046DpC121* ID_MODEL_FROM_DATABASE=Harmony One Remote usb:v046DpC122* - ID_MODEL_FROM_DATABASE=Harmony 700 Remote + ID_MODEL_FROM_DATABASE=Harmony 650/700 Remote usb:v046DpC124* ID_MODEL_FROM_DATABASE=Harmony 300 Remote @@ -7274,6 +7319,9 @@ usb:v046DpC124* usb:v046DpC125* ID_MODEL_FROM_DATABASE=Harmony 200 Remote +usb:v046DpC126* + ID_MODEL_FROM_DATABASE=Harmony Link + usb:v046DpC201* ID_MODEL_FROM_DATABASE=WingMan Extreme Joystick with Throttle @@ -7592,6 +7640,9 @@ usb:v046DpC529* usb:v046DpC52B* ID_MODEL_FROM_DATABASE=Unifying Receiver +usb:v046DpC52E* + ID_MODEL_FROM_DATABASE=MK260 Wireless Combo Receiver + usb:v046DpC52F* ID_MODEL_FROM_DATABASE=Unifying Receiver @@ -7610,6 +7661,9 @@ usb:v046DpC626* usb:v046DpC627* ID_MODEL_FROM_DATABASE=3Dconnexion Space Explorer 3D Mouse +usb:v046DpC629* + ID_MODEL_FROM_DATABASE=3Dconnexion SpacePilot Pro 3D Mouse + usb:v046DpC702* ID_MODEL_FROM_DATABASE=Cordless Presenter @@ -8024,6 +8078,9 @@ usb:v0471p20D0* usb:v0471p20E3* ID_MODEL_FROM_DATABASE=GoGear Raga +usb:v0471p20E4* + ID_MODEL_FROM_DATABASE=GoGear ViBE 8GB + usb:v0471p262C* ID_MODEL_FROM_DATABASE=SPC230NC Webcam @@ -8423,6 +8480,9 @@ usb:v047FpAC01* usb:v047FpAD01* ID_MODEL_FROM_DATABASE=GameCom 777 5.1 Headset +usb:v047FpC00E* + ID_MODEL_FROM_DATABASE=Blackwire C310 headset + usb:v0480* ID_VENDOR_FROM_DATABASE=Toshiba America Info. Systems, Inc. @@ -8438,6 +8498,9 @@ usb:v0480p0011* usb:v0480p0014* ID_MODEL_FROM_DATABASE=InTouch Module +usb:v0480pA006* + ID_MODEL_FROM_DATABASE=External Disk 1.5TB + usb:v0480pA007* ID_MODEL_FROM_DATABASE=External Disk USB 3.0 @@ -8450,6 +8513,9 @@ usb:v0482* usb:v0482p000E* ID_MODEL_FROM_DATABASE=FS-1020D Printer +usb:v0482p000F* + ID_MODEL_FROM_DATABASE=FS-1920 Mono Printer + usb:v0482p0100* ID_MODEL_FROM_DATABASE=Finecam S3x @@ -9701,6 +9767,9 @@ usb:v04A9p1721* usb:v04A9p1723* ID_MODEL_FROM_DATABASE=MP470 ser +usb:v04A9p1724* + ID_MODEL_FROM_DATABASE=PIXMA MP520 series + usb:v04A9p1725* ID_MODEL_FROM_DATABASE=MP610 ser @@ -9719,6 +9788,9 @@ usb:v04A9p1729* usb:v04A9p172B* ID_MODEL_FROM_DATABASE=MP140 ser +usb:v04A9p173B* + ID_MODEL_FROM_DATABASE=PIXMA MP270 All-In-One Printer + usb:v04A9p173E* ID_MODEL_FROM_DATABASE=MP560 @@ -10442,9 +10514,15 @@ usb:v04A9p310B* usb:v04A9p310E* ID_MODEL_FROM_DATABASE=Digital IXUS 50 (PTP mode) +usb:v04A9p310F* + ID_MODEL_FROM_DATABASE=PowerShot A420 + usb:v04A9p3110* ID_MODEL_FROM_DATABASE=EOS Digital Rebel XTi +usb:v04A9p3115* + ID_MODEL_FROM_DATABASE=PowerShot SD900 / Digital IXUS 900 Ti / IXY DIGITAL 1000 + usb:v04A9p3116* ID_MODEL_FROM_DATABASE=Digital IXUS 750 / PowerShot SD550 (PTP mode) @@ -10454,9 +10532,21 @@ usb:v04A9p3117* usb:v04A9p3119* ID_MODEL_FROM_DATABASE=PowerShot SD700 IS / Digital IXUS 800 IS / IXY Digital 800 IS +usb:v04A9p311A* + ID_MODEL_FROM_DATABASE=PowerShot S3 IS + usb:v04A9p311B* ID_MODEL_FROM_DATABASE=PowerShot A540 +usb:v04A9p311C* + ID_MODEL_FROM_DATABASE=PowerShot SD600 DIGITAL ELPH / DIGITAL IXUS 60 / IXY DIGITAL 70 + +usb:v04A9p3125* + ID_MODEL_FROM_DATABASE=PowerShot G7 + +usb:v04A9p3126* + ID_MODEL_FROM_DATABASE=PowerShot A530 + usb:v04A9p3127* ID_MODEL_FROM_DATABASE=SELPHY CP710 @@ -10466,9 +10556,21 @@ usb:v04A9p3128* usb:v04A9p312D* ID_MODEL_FROM_DATABASE=Elura 100 +usb:v04A9p3136* + ID_MODEL_FROM_DATABASE=PowerShot SD800 IS / Digital IXUS 850 IS / IXY DIGITAL 900 IS + +usb:v04A9p3137* + ID_MODEL_FROM_DATABASE=PowerShot SD40 / Digital IXUS i7 IXY / DIGITAL L4 + usb:v04A9p3138* ID_MODEL_FROM_DATABASE=PowerShot A710 IS +usb:v04A9p3139* + ID_MODEL_FROM_DATABASE=PowerShot A640 + +usb:v04A9p313A* + ID_MODEL_FROM_DATABASE=PowerShot A630 + usb:v04A9p3141* ID_MODEL_FROM_DATABASE=SELPHY ES1 @@ -10481,11 +10583,35 @@ usb:v04A9p3143* usb:v04A9p3145* ID_MODEL_FROM_DATABASE=EOS 450D +usb:v04A9p3146* + ID_MODEL_FROM_DATABASE=EOS 40D + usb:v04A9p3147* ID_MODEL_FROM_DATABASE=EOS 1Ds Mark III +usb:v04A9p3148* + ID_MODEL_FROM_DATABASE=PowerShot S5 IS + +usb:v04A9p3149* + ID_MODEL_FROM_DATABASE=PowerShot A460 + +usb:v04A9p314B* + ID_MODEL_FROM_DATABASE=PowerShot SD850 IS DIGITAL ELPH / Digital IXUS 950 IS / IXY DIGITAL 810 IS + +usb:v04A9p314C* + ID_MODEL_FROM_DATABASE=PowerShot A570 IS + +usb:v04A9p314D* + ID_MODEL_FROM_DATABASE=PowerShot A560 + +usb:v04A9p314E* + ID_MODEL_FROM_DATABASE=PowerShot SD750 DIGITAL ELPH / DIGITAL IXUS 75 / IXY DIGITAL 90 + usb:v04A9p314F* - ID_MODEL_FROM_DATABASE=Powershot SD1000 + ID_MODEL_FROM_DATABASE=PowerShot SD1000 DIGITAL ELPH / DIGITAL IXUS 70 / IXY DIGITAL 10 + +usb:v04A9p3150* + ID_MODEL_FROM_DATABASE=PowerShot A550 usb:v04A9p3155* ID_MODEL_FROM_DATABASE=PowerShot A450 @@ -10493,9 +10619,18 @@ usb:v04A9p3155* usb:v04A9p315A* ID_MODEL_FROM_DATABASE=PowerShot G9 +usb:v04A9p315B* + ID_MODEL_FROM_DATABASE=PowerShot A650 IS + usb:v04A9p315D* ID_MODEL_FROM_DATABASE=PowerShot A720 +usb:v04A9p315E* + ID_MODEL_FROM_DATABASE=PowerShot SX100 IS + +usb:v04A9p315F* + ID_MODEL_FROM_DATABASE=PowerShot SD950 IS DIGITAL ELPH / DIGITAL IXUS 960 IS / IXY DIGITAL 2000 IS + usb:v04A9p3160* ID_MODEL_FROM_DATABASE=Digital IXUS 860 IS @@ -10505,12 +10640,21 @@ usb:v04A9p3170* usb:v04A9p3171* ID_MODEL_FROM_DATABASE=SELPHY CP740 +usb:v04A9p3173* + ID_MODEL_FROM_DATABASE=PowerShot SD890 IS DIGITAL ELPH / Digital IXUS 970 IS / IXY DIGITAL 820 IS + +usb:v04A9p3174* + ID_MODEL_FROM_DATABASE=PowerShot SD790 IS DIGITAL ELPH / Digital IXUS 90 IS / IXY DIGITAL 95 IS + usb:v04A9p3175* ID_MODEL_FROM_DATABASE=IXY Digital 25 IS usb:v04A9p3176* ID_MODEL_FROM_DATABASE=PowerShot A590 +usb:v04A9p3177* + ID_MODEL_FROM_DATABASE=PowerShot A580 + usb:v04A9p317A* ID_MODEL_FROM_DATABASE=PC1267 [Powershot A470] @@ -10523,9 +10667,30 @@ usb:v04A9p3185* usb:v04A9p3186* ID_MODEL_FROM_DATABASE=SELPHY ES20 +usb:v04A9p318D* + ID_MODEL_FROM_DATABASE=PowerShot SX100 IS + +usb:v04A9p318E* + ID_MODEL_FROM_DATABASE=PowerShot A1000 IS + +usb:v04A9p318F* + ID_MODEL_FROM_DATABASE=PowerShot G10 + +usb:v04A9p3191* + ID_MODEL_FROM_DATABASE=PowerShot A2000 IS + usb:v04A9p3192* ID_MODEL_FROM_DATABASE=PowerShot SX110 IS +usb:v04A9p3193* + ID_MODEL_FROM_DATABASE=PowerShot SD990 IS DIGITAL ELPH / Digital IXUS 980 IS / IXY DIGITAL 3000 IS + +usb:v04A9p3195* + ID_MODEL_FROM_DATABASE=PowerShot SX1 IS + +usb:v04A9p3196* + ID_MODEL_FROM_DATABASE=PowerShot SD880 IS DIGITAL ELPH / Digital IXUS 870 IS / IXY DIGITAL 920 IS + usb:v04A9p319A* ID_MODEL_FROM_DATABASE=EOS 7D @@ -10550,24 +10715,66 @@ usb:v04A9p31B1* usb:v04A9p31BC* ID_MODEL_FROM_DATABASE=PowerShot D10 +usb:v04A9p31BD* + ID_MODEL_FROM_DATABASE=PowerShot SD960 IS DIGITAL ELPH / Digital IXUS 110 IS / IXY DIGITAL 510 IS + +usb:v04A9p31BE* + ID_MODEL_FROM_DATABASE=PowerShot A2100 IS + usb:v04A9p31BF* ID_MODEL_FROM_DATABASE=PowerShot A480 usb:v04A9p31C0* ID_MODEL_FROM_DATABASE=PowerShot SX200 IS +usb:v04A9p31C1* + ID_MODEL_FROM_DATABASE=PowerShot SD970 IS DIGITAL ELPH / Digital IXUS 990 IS / IXY DIGITAL 830 IS + +usb:v04A9p31C2* + ID_MODEL_FROM_DATABASE=PowerShot SD780 IS DIGITAL ELPH / Digital IXUS 100 IS / IXY DIGITAL 210 IS + +usb:v04A9p31C3* + ID_MODEL_FROM_DATABASE=PowerShot A1100 IS + +usb:v04A9p31C4* + ID_MODEL_FROM_DATABASE=PowerShot SD1200 IS DIGITAL ELPH / Digital IXUS 95 IS / IXY DIGITAL 110 IS + +usb:v04A9p31CF* + ID_MODEL_FROM_DATABASE=EOS Rebel T1i / EOS 500D / EOS Kiss X3 + usb:v04A9p31DD* ID_MODEL_FROM_DATABASE=SELPHY CP780 +usb:v04A9p31DF* + ID_MODEL_FROM_DATABASE=PowerShot G11 + +usb:v04A9p31E0* + ID_MODEL_FROM_DATABASE=PowerShot SX120 IS + +usb:v04A9p31E1* + ID_MODEL_FROM_DATABASE=PowerShot S90 + +usb:v04A9p31E4* + ID_MODEL_FROM_DATABASE=PowerShot SX20 IS + usb:v04A9p31E5* ID_MODEL_FROM_DATABASE=Digital IXUS 200 IS +usb:v04A9p31E6* + ID_MODEL_FROM_DATABASE=PowerShot SD940 IS DIGITAL ELPH / Digital IXUS 120 IS / IXY DIGITAL 220 IS + +usb:v04A9p31EA* + ID_MODEL_FROM_DATABASE=EOS Rebel T2i / EOS 550D / EOS Kiss X4 + usb:v04A9p31EE* ID_MODEL_FROM_DATABASE=SELPHY ES40 usb:v04A9p31EF* ID_MODEL_FROM_DATABASE=PowerShot A495 +usb:v04A9p31F0* + ID_MODEL_FROM_DATABASE=PowerShot A490 + usb:v04A9p31F1* ID_MODEL_FROM_DATABASE=PowerShot A3100 IS / PowerShot A3150 IS @@ -10598,6 +10805,9 @@ usb:v04A9p31FF* usb:v04A9p3209* ID_MODEL_FROM_DATABASE=Vixia HF S21 A +usb:v04A9p320F* + ID_MODEL_FROM_DATABASE=PowerShot G12 + usb:v04A9p3210* ID_MODEL_FROM_DATABASE=Powershot SX30 IS @@ -10619,9 +10829,15 @@ usb:v04A9p3223* usb:v04A9p3224* ID_MODEL_FROM_DATABASE=PowerShot A3200 IS +usb:v04A9p3225* + ID_MODEL_FROM_DATABASE=PowerShot ELPH 500 HS / IXUS 310 HS + usb:v04A9p3226* ID_MODEL_FROM_DATABASE=PowerShow A800 +usb:v04A9p3227* + ID_MODEL_FROM_DATABASE=PowerShot ELPH 100 HS / IXUS 115 HS + usb:v04A9p3228* ID_MODEL_FROM_DATABASE=PowerShot SX230 HS @@ -10634,6 +10850,9 @@ usb:v04A9p322A* usb:v04A9p322B* ID_MODEL_FROM_DATABASE=Powershot A1200 +usb:v04A9p322C* + ID_MODEL_FROM_DATABASE=PowerShot SX220 HS + usb:v04A9p3233* ID_MODEL_FROM_DATABASE=PowerShot G1 X @@ -10664,6 +10883,9 @@ usb:v04A9p3240* usb:v04A9p3241* ID_MODEL_FROM_DATABASE=PowerShot ELPH 110 HS / IXUS 125 HS +usb:v04A9p3242* + ID_MODEL_FROM_DATABASE=PowerShot D20 + usb:v04A9p3243* ID_MODEL_FROM_DATABASE=PowerShot A4000 IS @@ -10706,6 +10928,18 @@ usb:v04A9p325B* usb:v04A9p325C* ID_MODEL_FROM_DATABASE=PowerShot SX500 IS +usb:v04A9p325F* + ID_MODEL_FROM_DATABASE=PowerShot SX280 HS + +usb:v04A9p3260* + ID_MODEL_FROM_DATABASE=PowerShot SX270 HS + +usb:v04A9p3264* + ID_MODEL_FROM_DATABASE=PowerShot A1400 + +usb:v04A9p3268* + ID_MODEL_FROM_DATABASE=PowerShot ELPH 330 HS / IXUS 255 HS + usb:v04AA* ID_VENDOR_FROM_DATABASE=DaeWoo Telecom, Ltd @@ -10916,12 +11150,18 @@ usb:v04B0p041E* usb:v04B0p0422* ID_MODEL_FROM_DATABASE=D700 (ptp) +usb:v04B0p0423* + ID_MODEL_FROM_DATABASE=D5000 + usb:v04B0p0424* ID_MODEL_FROM_DATABASE=D3000 usb:v04B0p0425* ID_MODEL_FROM_DATABASE=D300S +usb:v04B0p0428* + ID_MODEL_FROM_DATABASE=D7000 + usb:v04B0p042A* ID_MODEL_FROM_DATABASE=D800 (ptp) @@ -11042,6 +11282,9 @@ usb:v04B4p0002* usb:v04B4p0033* ID_MODEL_FROM_DATABASE=Mouse +usb:v04B4p0060* + ID_MODEL_FROM_DATABASE=Wireless optical mouse + usb:v04B4p0100* ID_MODEL_FROM_DATABASE=Cino FuzzyScan F760-B @@ -11996,6 +12239,9 @@ usb:v04C5p1042* usb:v04C5p105B* ID_MODEL_FROM_DATABASE=AH-F401U Air H device +usb:v04C5p1084* + ID_MODEL_FROM_DATABASE=PalmSecure Sensor V2 + usb:v04C5p1096* ID_MODEL_FROM_DATABASE=fi-5110EOX @@ -12065,6 +12311,9 @@ usb:v04CA* usb:v04CAp1766* ID_MODEL_FROM_DATABASE=HID Monitor Controls +usb:v04CAp2004* + ID_MODEL_FROM_DATABASE=Bluetooth 4.0 [Broadcom BCM20702A0] + usb:v04CAp9304* ID_MODEL_FROM_DATABASE=Hub @@ -12500,6 +12749,9 @@ usb:v04D8p8101* usb:v04D8p8107* ID_MODEL_FROM_DATABASE=Microstick II +usb:v04D8p9004* + ID_MODEL_FROM_DATABASE=Microchip REAL ICE + usb:v04D8p900A* ID_MODEL_FROM_DATABASE=PICkit3 @@ -12563,6 +12815,9 @@ usb:v04D9p2221* usb:v04D9p2323* ID_MODEL_FROM_DATABASE=Keyboard +usb:v04D9p2519* + ID_MODEL_FROM_DATABASE=Shenzhen LogoTech 2.4GHz receiver + usb:v04D9p2832* ID_MODEL_FROM_DATABASE=1channel Telephone line recorder @@ -12842,6 +13097,9 @@ usb:v04E1p0201* usb:v04E2* ID_VENDOR_FROM_DATABASE=Exar Corp. +usb:v04E2p1410* + ID_MODEL_FROM_DATABASE=XR21V1410 USB-UART IC + usb:v04E3* ID_VENDOR_FROM_DATABASE=Zilog, Inc. @@ -13098,7 +13356,7 @@ usb:v04E8p0111* ID_MODEL_FROM_DATABASE=Connect3D Flash Drive usb:v04E8p0300* - ID_MODEL_FROM_DATABASE=E2530 Phone (Mass storage mode) + ID_MODEL_FROM_DATABASE=E2530 / GT-C3350 Phones (Mass storage mode) usb:v04E8p1003* ID_MODEL_FROM_DATABASE=MP3 Player and Recorder @@ -13508,12 +13766,18 @@ usb:v04E8p5F05* usb:v04E8p6032* ID_MODEL_FROM_DATABASE=G2 Portable hard drive +usb:v04E8p6034* + ID_MODEL_FROM_DATABASE=G2 Portable hard drive + usb:v04E8p60B3* ID_MODEL_FROM_DATABASE=M2 Portable Hard Drive usb:v04E8p60C4* ID_MODEL_FROM_DATABASE=M2 Portable Hard Drive USB 3.0 +usb:v04E8p61B6* + ID_MODEL_FROM_DATABASE=M3 Portable Hard Drive 1TB + usb:v04E8p6601* ID_MODEL_FROM_DATABASE=Mobile Phone @@ -13632,7 +13896,7 @@ usb:v04E8p685D* ID_MODEL_FROM_DATABASE=GT-I9100 Phone [Galaxy S II] (Download mode) usb:v04E8p685E* - ID_MODEL_FROM_DATABASE=GT-I9100 Phone [Galaxy S II] (USB Debugging mode) + ID_MODEL_FROM_DATABASE=GT-I9100 / GT-C3350 Phones (USB Debugging mode) usb:v04E8p6860* ID_MODEL_FROM_DATABASE=GT-I9100 Phone [Galaxy S II], GT-I9300 Phone [Galaxy S III], GT-P7500 [Galaxy Tab 10.1] @@ -13910,6 +14174,9 @@ usb:v04F2pB059* usb:v04F2pB071* ID_MODEL_FROM_DATABASE=2.0M UVC Webcam / CNF7129 +usb:v04F2pB083* + ID_MODEL_FROM_DATABASE=CKF7063 Webcam (HP) + usb:v04F2pB091* ID_MODEL_FROM_DATABASE=Webcam @@ -13943,6 +14210,9 @@ usb:v04F2pB1CF* usb:v04F2pB1D6* ID_MODEL_FROM_DATABASE=CNF9055 Toshiba Webcam +usb:v04F2pB1E4* + ID_MODEL_FROM_DATABASE=Toshiba Integrated Webcam + usb:v04F2pB213* ID_MODEL_FROM_DATABASE=Fujitsu Integrated Camera @@ -13976,6 +14246,9 @@ usb:v04F2pB2EA* usb:v04F2pB330* ID_MODEL_FROM_DATABASE=Asus 720p CMOS webcam +usb:v04F2pB354* + ID_MODEL_FROM_DATABASE=UVC 1.00 device HD UVC WebCam + usb:v04F3* ID_VENDOR_FROM_DATABASE=Elan Microelectronics Corp. @@ -14624,6 +14897,9 @@ usb:v04F9p201B* usb:v04F9p2027* ID_MODEL_FROM_DATABASE=QL-560 P-Touch Label Printer +usb:v04F9p202B* + ID_MODEL_FROM_DATABASE=PT-7600 P-Touch Label Printer + usb:v04F9p2100* ID_MODEL_FROM_DATABASE=Card Reader Writer @@ -14777,6 +15053,9 @@ usb:v0502p3202* usb:v0502p3203* ID_MODEL_FROM_DATABASE=Liquid (Debug mode) +usb:v0502p3230* + ID_MODEL_FROM_DATABASE=BeTouch E120 + usb:v0502p3317* ID_MODEL_FROM_DATABASE=Liquid @@ -14987,6 +15266,9 @@ usb:v050Dp0307* usb:v050Dp0409* ID_MODEL_FROM_DATABASE=F5U409 Serial +usb:v050Dp0416* + ID_MODEL_FROM_DATABASE=Staples 12416 7 port desktop hub + usb:v050Dp0551* ID_MODEL_FROM_DATABASE=F6C550-AVR UPS @@ -15294,7 +15576,7 @@ usb:v0525pA4A4* ID_MODEL_FROM_DATABASE=Linux-USB user-mode bulk source/sink usb:v0525pA4A5* - ID_MODEL_FROM_DATABASE=Linux-USB File Storage Gadget + ID_MODEL_FROM_DATABASE=Pocketbook Pro 903 usb:v0525pA4A6* ID_MODEL_FROM_DATABASE=Linux-USB Serial Gadget @@ -15482,6 +15764,9 @@ usb:v053A* usb:v053Ap0B00* ID_MODEL_FROM_DATABASE=Hub +usb:v053Ap0B01* + ID_MODEL_FROM_DATABASE=Preh MCI 3100 + usb:v053B* ID_VENDOR_FROM_DATABASE=Global Village Communication @@ -15683,6 +15968,9 @@ usb:v0547p2750* usb:v0547p2810* ID_MODEL_FROM_DATABASE=Cypress ATAPI Bridge +usb:v0547p4D90* + ID_MODEL_FROM_DATABASE=AmScope MD1900 camera + usb:v0547p7777* ID_MODEL_FROM_DATABASE=Bluetooth Device @@ -16022,6 +16310,9 @@ usb:v054Cp01D5* usb:v054Cp01DE* ID_MODEL_FROM_DATABASE=VRD-VC10 [Video Capture] +usb:v054Cp01E8* + ID_MODEL_FROM_DATABASE=UP-DR150 Photo Printer + usb:v054Cp01E9* ID_MODEL_FROM_DATABASE=Net MD @@ -16358,6 +16649,9 @@ usb:v0557p7000* usb:v0557p7820* ID_MODEL_FROM_DATABASE=UC-2322 2xSerial Ports [mos7820] +usb:v0557p8021* + ID_MODEL_FROM_DATABASE=CS1764A [CubiQ DVI KVMP Switch] + usb:v0558* ID_VENDOR_FROM_DATABASE=Truevision, Inc. @@ -16904,6 +17198,9 @@ usb:v056Ap00DB* usb:v056Ap00DD* ID_MODEL_FROM_DATABASE=Bamboo Pen (CTL-470) +usb:v056Ap00DE* + ID_MODEL_FROM_DATABASE=CTH-470 [Bamboo Fun Pen & Touch] + usb:v056Ap00F6* ID_MODEL_FROM_DATABASE=Cintiq 24HD touch (DTH-2400) touchscreen @@ -18686,6 +18983,9 @@ usb:v059Fp0421* usb:v059Fp0641* ID_MODEL_FROM_DATABASE=Mobile Hard Drive +usb:v059Fp100C* + ID_MODEL_FROM_DATABASE=Rugged Triple Interface Mobile Hard Drive + usb:v059Fp1010* ID_MODEL_FROM_DATABASE=Desktop Hard Drive @@ -18749,6 +19049,12 @@ usb:v05A4p9731* usb:v05A4p9783* ID_MODEL_FROM_DATABASE=Wireless Keypad +usb:v05A4p9837* + ID_MODEL_FROM_DATABASE=Targus Number Keypad + +usb:v05A4p9862* + ID_MODEL_FROM_DATABASE=Targus Number Keypad (Composite Device) + usb:v05A4p9881* ID_MODEL_FROM_DATABASE=IR receiver [VRC-1100 Vista MCE Remote Control] @@ -19097,6 +19403,9 @@ usb:v05ACp1105* usb:v05ACp1107* ID_MODEL_FROM_DATABASE=Thunderbolt Display Audio +usb:v05ACp1112* + ID_MODEL_FROM_DATABASE=FaceTime HD Camera (Display) + usb:v05ACp1201* ID_MODEL_FROM_DATABASE=3G iPod @@ -19304,6 +19613,9 @@ usb:v05ACp8241* usb:v05ACp8242* ID_MODEL_FROM_DATABASE=Built-in IR Receiver +usb:v05ACp8281* + ID_MODEL_FROM_DATABASE=Bluetooth Host Controller + usb:v05ACp8286* ID_MODEL_FROM_DATABASE=Bluetooth Host Controller @@ -20672,6 +20984,9 @@ usb:v05E3p0726* usb:v05E3p0727* ID_MODEL_FROM_DATABASE=microSD Reader/Writer +usb:v05E3p0731* + ID_MODEL_FROM_DATABASE=GL3310 SATA 3Gb/s Bridge Controller + usb:v05E3p0736* ID_MODEL_FROM_DATABASE=microSD Reader/Writer @@ -20825,9 +21140,15 @@ usb:v05F9* usb:v05F9p1104* ID_MODEL_FROM_DATABASE=Magellan 2200VS +usb:v05F9p2202* + ID_MODEL_FROM_DATABASE=Point of Sale Handheld Scanner + usb:v05F9p2206* ID_MODEL_FROM_DATABASE=Datalogic Gryphon GFS4170 +usb:v05F9p2601* + ID_MODEL_FROM_DATABASE=Datalogin Magellan 1000i Barcode Scanner + usb:v05F9p2602* ID_MODEL_FROM_DATABASE=Datalogic Magellan 1100i Barcode Scanner @@ -21137,6 +21458,15 @@ usb:v0623* usb:v0624* ID_VENDOR_FROM_DATABASE=Avocent Corp. +usb:v0624p0248* + ID_MODEL_FROM_DATABASE=Virtual Hub + +usb:v0624p0249* + ID_MODEL_FROM_DATABASE=Virtual Keyboard/Mouse + +usb:v0624p0251* + ID_MODEL_FROM_DATABASE=Virtual Mass Storage + usb:v0624p0294* ID_MODEL_FROM_DATABASE=Dell 03R874 KVM dongle @@ -21311,6 +21641,9 @@ usb:v0644p800D* usb:v0644p800E* ID_MODEL_FROM_DATABASE=TASCAM US-122L +usb:v0644p801D* + ID_MODEL_FROM_DATABASE=DR-100 + usb:v0644p8021* ID_MODEL_FROM_DATABASE=TASCAM US-122mkII @@ -21407,6 +21740,9 @@ usb:v064EpC107* usb:v064EpD101* ID_MODEL_FROM_DATABASE=Acer CrystalEye Webcam +usb:v064EpD217* + ID_MODEL_FROM_DATABASE=HP TrueVision HD + usb:v064EpE201* ID_MODEL_FROM_DATABASE=Lenovo Integrated Webcam @@ -21489,7 +21825,7 @@ usb:v065A* ID_VENDOR_FROM_DATABASE=Optoelectronics Co., Ltd usb:v065Ap0001* - ID_MODEL_FROM_DATABASE=Barcode scanner / NLV-1001 (keyboard mode) + ID_MODEL_FROM_DATABASE=Opticon OPR-2001 / NLV-1001 (keyboard mode) usb:v065Ap0009* ID_MODEL_FROM_DATABASE=NLV-1001 (serial mode) / OPN-2001 [Opticon] @@ -22070,6 +22406,9 @@ usb:v067Bp2528* usb:v067Bp25A1* ID_MODEL_FROM_DATABASE=PL25A1 Host-Host Bridge +usb:v067Bp2773* + ID_MODEL_FROM_DATABASE=PL2773 SATAII bridge controller + usb:v067Bp3400* ID_MODEL_FROM_DATABASE=Hi-Speed Flash Disk with TruePrint AES3400 @@ -22862,6 +23201,21 @@ usb:v06BCp000B* usb:v06BCp0027* ID_MODEL_FROM_DATABASE=Okipage 14e +usb:v06BCp00F7* + ID_MODEL_FROM_DATABASE=OKI B4600 Mono Printer + +usb:v06BCp015E* + ID_MODEL_FROM_DATABASE=OKIPOS 411/412 POS Printer + +usb:v06BCp01C9* + ID_MODEL_FROM_DATABASE=OKI B430 Mono Printer + +usb:v06BCp020B* + ID_MODEL_FROM_DATABASE=OKI ES4140 Mono Printer + +usb:v06BCp02BB* + ID_MODEL_FROM_DATABASE=OKI PT390 POS Printer + usb:v06BCp0A91* ID_MODEL_FROM_DATABASE=B2500MFP (printer+scanner) @@ -23222,6 +23576,9 @@ usb:v06D1* usb:v06D3* ID_VENDOR_FROM_DATABASE=Mitsubishi Electric Corp. +usb:v06D3p0284* + ID_MODEL_FROM_DATABASE=FX-USB-AW/-BD RS482 Converters + usb:v06D3p0380* ID_MODEL_FROM_DATABASE=CP8000D Port @@ -23339,6 +23696,9 @@ usb:v06DE* usb:v06E0* ID_VENDOR_FROM_DATABASE=Multi-Tech Systems, Inc. +usb:v06E0p0319* + ID_MODEL_FROM_DATABASE=MT9234ZBA-USB MultiModem ZBA + usb:v06E0pF101* ID_MODEL_FROM_DATABASE=MT5634ZBA-USB MultiModemUSB (old firmware) @@ -23351,6 +23711,9 @@ usb:v06E0pF104* usb:v06E0pF107* ID_MODEL_FROM_DATABASE=MT5634ZBA-USB-V92 MultiModemUSB +usb:v06E0pF120* + ID_MODEL_FROM_DATABASE=MT9234ZBA-USB-CDC-ACM-XR MultiModem ZBA CDC-ACM-XR + usb:v06E1* ID_VENDOR_FROM_DATABASE=ADS Technologies, Inc. @@ -25154,6 +25517,12 @@ usb:v0798* usb:v0798p0001* ID_MODEL_FROM_DATABASE=Braille Voyager +usb:v0798p0640* + ID_MODEL_FROM_DATABASE=BC640 + +usb:v0798p0680* + ID_MODEL_FROM_DATABASE=BC680 + usb:v0799* ID_VENDOR_FROM_DATABASE=Altera @@ -25163,6 +25532,12 @@ usb:v0799p7651* usb:v079B* ID_VENDOR_FROM_DATABASE=Sagem +usb:v079Bp0024* + ID_MODEL_FROM_DATABASE=MSO300/MSO301 Fingerprint Sensor + +usb:v079Bp0026* + ID_MODEL_FROM_DATABASE=MSO350/MSO351 Fingerprint Sensor & SmartCard Reader + usb:v079Bp0027* ID_MODEL_FROM_DATABASE=USB-Serial Controller @@ -25175,12 +25550,18 @@ usb:v079Bp0030* usb:v079Bp0042* ID_MODEL_FROM_DATABASE=Mobile +usb:v079Bp0047* + ID_MODEL_FROM_DATABASE=CBM/MSO1300 Fingerprint Sensor + usb:v079Bp004A* ID_MODEL_FROM_DATABASE=XG-760A 802.11bg usb:v079Bp004B* ID_MODEL_FROM_DATABASE=Wi-Fi 11g adapter +usb:v079Bp0052* + ID_MODEL_FROM_DATABASE=MSO1350 Fingerprint Sensor & SmartCard Reader + usb:v079Bp0056* ID_MODEL_FROM_DATABASE=Agfa AP1100 Photo Printer @@ -25553,6 +25934,9 @@ usb:v07B4p0118* usb:v07B4p0184* ID_MODEL_FROM_DATABASE=P-S100 port +usb:v07B4p0202* + ID_MODEL_FROM_DATABASE=Foot Switch RS-26 + usb:v07B4p0203* ID_MODEL_FROM_DATABASE=Digital Voice Recorder DW-90 @@ -25565,12 +25949,24 @@ usb:v07B4p0207* usb:v07B4p0209* ID_MODEL_FROM_DATABASE=Digital Voice Recorder DM-20 +usb:v07B4p020B* + ID_MODEL_FROM_DATABASE=Digital Voice Recorder DS-4000 + usb:v07B4p020D* ID_MODEL_FROM_DATABASE=Digital Voice Recorder VN-240PC +usb:v07B4p0211* + ID_MODEL_FROM_DATABASE=Digital Voice Recorder DS-2300 + +usb:v07B4p0218* + ID_MODEL_FROM_DATABASE=Foot Switch RS-28 + usb:v07B4p0244* ID_MODEL_FROM_DATABASE=Digital Voice Recorder VN-8500PC +usb:v07B4p024F* + ID_MODEL_FROM_DATABASE=Digital Voice Recorder DS-7000 + usb:v07B4p0280* ID_MODEL_FROM_DATABASE=m:robe 100 @@ -25664,6 +26060,9 @@ usb:v07B8p5301* usb:v07B8p6001* ID_MODEL_FROM_DATABASE=802.11bg +usb:v07B8p8188* + ID_MODEL_FROM_DATABASE=AboCom Systems Inc [WN2001 Prolink Wireless-N Nano Adapter] + usb:v07B8pA001* ID_MODEL_FROM_DATABASE=WUG2200 802.11g Wireless Adapter [Envara WiND512] @@ -27071,6 +27470,9 @@ usb:v0846p1020* usb:v0846p1040* ID_MODEL_FROM_DATABASE=FA120 Fast Ethernet USB 2.0 [Asix AX88172 / AX8817x] +usb:v0846p1100* + ID_MODEL_FROM_DATABASE=Managed Switch M4100 series, M5300 series, M7100 series + usb:v0846p4110* ID_MODEL_FROM_DATABASE=MA111(v1) 802.11b Wireless [Intersil Prism 3.0] @@ -27945,7 +28347,7 @@ usb:v08E5* ID_VENDOR_FROM_DATABASE=Litronic usb:v08E6* - ID_VENDOR_FROM_DATABASE=Gemplus + ID_VENDOR_FROM_DATABASE=Gemalto (was Gemplus) usb:v08E6p0001* ID_MODEL_FROM_DATABASE=GemPC-Touch 430 @@ -27986,6 +28388,9 @@ usb:v08E6p4433* usb:v08E6p5501* ID_MODEL_FROM_DATABASE=GemProx-PU Contactless Smart Card Reader +usb:v08E6p5503* + ID_MODEL_FROM_DATABASE=Prox-DU Contactless Interface + usb:v08E6pACE0* ID_MODEL_FROM_DATABASE=UA HYBRID TOKEN @@ -28901,6 +29306,9 @@ usb:v0930p0B05* usb:v0930p0B09* ID_MODEL_FROM_DATABASE=PX1396E-3T01 External hard drive +usb:v0930p0B1A* + ID_MODEL_FROM_DATABASE=STOR.E ALU 2S + usb:v0930p1300* ID_MODEL_FROM_DATABASE=Wireless Broadband (CDMA EV-DO) SM-Bus Minicard Status Port @@ -29087,6 +29495,9 @@ usb:v0934* usb:v0936* ID_VENDOR_FROM_DATABASE=NuTesla +usb:v0936p000C* + ID_MODEL_FROM_DATABASE=Rhythmedics 6 BioData Integrator + usb:v0936p0030* ID_MODEL_FROM_DATABASE=Composite Device, Mass Storage Device (Flash Drive) amd HID @@ -29135,6 +29546,9 @@ usb:v093Ap2500* usb:v093Ap2510* ID_MODEL_FROM_DATABASE=Optical Mouse +usb:v093Ap2521* + ID_MODEL_FROM_DATABASE=Optical Mouse + usb:v093Ap2600* ID_MODEL_FROM_DATABASE=Typhoon Easycam USB 330K (newer)/Typhoon Easycam USB 2.0 VGA 1.3M/Sansun SN-508 @@ -29375,6 +29789,9 @@ usb:v0955p7030* usb:v0955p7100* ID_MODEL_FROM_DATABASE=Notion Ink Adam +usb:v0955p7820* + ID_MODEL_FROM_DATABASE=Tegra 2 AC100 developer mode + usb:v0955pB400* ID_MODEL_FROM_DATABASE=SHIELD (debug) @@ -29489,6 +29906,9 @@ usb:v0978* usb:v0979* ID_VENDOR_FROM_DATABASE=Jeilin Technology Corp., Ltd +usb:v0979p0222* + ID_MODEL_FROM_DATABASE=Keychain Display + usb:v0979p0224* ID_MODEL_FROM_DATABASE=JL2005A Toy Camera @@ -29822,8 +30242,11 @@ usb:v09DAp8090* usb:v09DAp9033* ID_MODEL_FROM_DATABASE=X-718BK Optical Mouse +usb:v09DAp9066* + ID_MODEL_FROM_DATABASE=F3 V-Track Gaming Mouse + usb:v09DAp9090* - ID_MODEL_FROM_DATABASE=XL-750BK Laser Mouse + ID_MODEL_FROM_DATABASE=XL-730K / XL-750BK / XL-755BK Mice usb:v09DB* ID_VENDOR_FROM_DATABASE=Measurement Computing Corp. @@ -30632,6 +31055,9 @@ usb:v0A5Fp0081* usb:v0A5Fp008B* ID_MODEL_FROM_DATABASE=HC100 wristbands Printer +usb:v0A5Fp00D1* + ID_MODEL_FROM_DATABASE=Zebra GC420d Label Printer + usb:v0A5Fp930A* ID_MODEL_FROM_DATABASE=Printer @@ -31163,6 +31589,9 @@ usb:v0AC8pC326* usb:v0AC8pC33F* ID_MODEL_FROM_DATABASE=Webcam +usb:v0AC8pC429* + ID_MODEL_FROM_DATABASE=Lenovo ThinkCentre Web Camera + usb:v0AC9* ID_VENDOR_FROM_DATABASE=Micro Solutions, Inc. @@ -31208,6 +31637,9 @@ usb:v0ACDp0401* usb:v0ACDp0630* ID_MODEL_FROM_DATABASE=Spectrum III Mag-Only Insert Reader (SPT3-355 Series) USB-CDC +usb:v0ACDp0810* + ID_MODEL_FROM_DATABASE=SecurePIN (IDPA-506100Y) PIN Pad + usb:v0ACE* ID_VENDOR_FROM_DATABASE=ZyDAS @@ -31610,12 +32042,18 @@ usb:v0B0Dp0000* usb:v0B0E* ID_VENDOR_FROM_DATABASE=GN Netcom +usb:v0B0Ep0420* + ID_MODEL_FROM_DATABASE=Jabra SPEAK 510 + usb:v0B0Ep1022* ID_MODEL_FROM_DATABASE=Jabra PRO 9450, Type 9400BS (DECT Headset) usb:v0B0Ep620C* ID_MODEL_FROM_DATABASE=Jabra BT620s +usb:v0B0Ep9330* + ID_MODEL_FROM_DATABASE=Jabra GN9330 Headset + usb:v0B0F* ID_VENDOR_FROM_DATABASE=AVID Technology @@ -31919,6 +32357,18 @@ usb:v0B64* usb:v0B65* ID_VENDOR_FROM_DATABASE=Expert Magnetics Corp. +usb:v0B66* + ID_VENDOR_FROM_DATABASE=Cybiko Inc. + +usb:v0B66p0041* + ID_MODEL_FROM_DATABASE=Xtreme + +usb:v0B67* + ID_VENDOR_FROM_DATABASE=Fairbanks Scales + +usb:v0B67p555E* + ID_MODEL_FROM_DATABASE=SCB-R9000 + usb:v0B69* ID_VENDOR_FROM_DATABASE=CacheVision @@ -32427,7 +32877,7 @@ usb:v0BB4p0A4F* ID_MODEL_FROM_DATABASE=PocketPC Sync usb:v0BB4p0A50* - ID_MODEL_FROM_DATABASE=HTC SmartPhone Sync + ID_MODEL_FROM_DATABASE=SmartPhone (MTP) usb:v0BB4p0A51* ID_MODEL_FROM_DATABASE=SPV C400 / T-Mobile SDA GSM/GPRS Pocket PC @@ -32795,6 +33245,9 @@ usb:v0BC2p0503* usb:v0BC2p2000* ID_MODEL_FROM_DATABASE=Storage Adapter V3 (TPP) +usb:v0BC2p2100* + ID_MODEL_FROM_DATABASE=FreeAgent Go + usb:v0BC2p2200* ID_MODEL_FROM_DATABASE=FreeAgent Go FW @@ -32804,6 +33257,9 @@ usb:v0BC2p2300* usb:v0BC2p2320* ID_MODEL_FROM_DATABASE=USB 3.0 bridge [Portable Expansion Drive] +usb:v0BC2p3008* + ID_MODEL_FROM_DATABASE=FreeAgent Desk 1TB + usb:v0BC2p3320* ID_MODEL_FROM_DATABASE=SRD00F2 [Expansion Desktop Drive] @@ -32831,6 +33287,12 @@ usb:v0BC2p5161* usb:v0BC2pA003* ID_MODEL_FROM_DATABASE=Backup Plus +usb:v0BC2pA0A1* + ID_MODEL_FROM_DATABASE=Backup Plus Desktop + +usb:v0BC2pA0A4* + ID_MODEL_FROM_DATABASE=Backup Plus Desktop Drive + usb:v0BC3* ID_VENDOR_FROM_DATABASE=IPWireless, Inc. @@ -33035,6 +33497,9 @@ usb:v0BDAp8176* usb:v0BDAp8178* ID_MODEL_FROM_DATABASE=RTL8192CU 802.11n WLAN Adapter +usb:v0BDAp8179* + ID_MODEL_FROM_DATABASE=RTL8188EUS 802.11n Wireless Network Adapter + usb:v0BDAp817F* ID_MODEL_FROM_DATABASE=RTL8188RU 802.11n WLAN Adapter @@ -33191,6 +33656,9 @@ usb:v0BF8p100C* usb:v0BF8p100F* ID_MODEL_FROM_DATABASE=miniCard D2301 802.11bg Wireless Module [SiS 163U] +usb:v0BF8p1017* + ID_MODEL_FROM_DATABASE=Keyboard KB SCR + usb:v0BFD* ID_VENDOR_FROM_DATABASE=Kvaser AB @@ -33420,7 +33888,7 @@ usb:v0C2Ep0007* ID_MODEL_FROM_DATABASE=Metrologic MS7120 Barcode Scanner (IBM SurePOS mode) usb:v0C2Ep0200* - ID_MODEL_FROM_DATABASE=Metrologic Scanner + ID_MODEL_FROM_DATABASE=MS7120 Barcode Scanner usb:v0C2Ep0204* ID_MODEL_FROM_DATABASE=Metrologic MS7120 Barcode Scanner (keyboard mode) @@ -33848,6 +34316,9 @@ usb:v0C45p62E0* usb:v0C45p6310* ID_MODEL_FROM_DATABASE=Sonix USB 2.0 Camera +usb:v0C45p6341* + ID_MODEL_FROM_DATABASE=Defender G-Lens 2577 HD720p Camera + usb:v0C45p63E0* ID_MODEL_FROM_DATABASE=Sonix Integrated Webcam @@ -33866,6 +34337,9 @@ usb:v0C45p6413* usb:v0C45p6417* ID_MODEL_FROM_DATABASE=Integrated Webcam +usb:v0C45p6419* + ID_MODEL_FROM_DATABASE=Integrated Webcam + usb:v0C45p641D* ID_MODEL_FROM_DATABASE=1.3 MPixel Integrated Webcam @@ -34559,6 +35033,9 @@ usb:v0CCDp00A9* usb:v0CCDp00B3* ID_MODEL_FROM_DATABASE=NOXON DAB/DAB+ Stick +usb:v0CCDp00E0* + ID_MODEL_FROM_DATABASE=NOXON DAB/DAB+ Stick V2 + usb:v0CCDp10A7* ID_MODEL_FROM_DATABASE=TerraTec G3 @@ -34713,7 +35190,7 @@ usb:v0CF3p1001* ID_MODEL_FROM_DATABASE=Thomson TG121N [Atheros AR9001U-(2)NG] usb:v0CF3p1002* - ID_MODEL_FROM_DATABASE=TP-Link TL-WN821N v2 802.11n [Atheros AR9170] + ID_MODEL_FROM_DATABASE=TP-Link TL-WN821N v2 / TL-WN822N v1 802.11n [Atheros AR9170] usb:v0CF3p1006* ID_MODEL_FROM_DATABASE=TP-Link TL-WN322G v3 / TL-WN422G v2 802.11g [Atheros AR9271] @@ -34737,7 +35214,7 @@ usb:v0CF3p3008* ID_MODEL_FROM_DATABASE=Bluetooth (AR3011) usb:v0CF3p7015* - ID_MODEL_FROM_DATABASE=TP-Link TL-WN821N v3 802.11n [Atheros AR7010+AR9287] + ID_MODEL_FROM_DATABASE=TP-Link TL-WN821N v3 / TL-WN822N v2 802.11n [Atheros AR7010+AR9287] usb:v0CF3p9170* ID_MODEL_FROM_DATABASE=AR9170 802.11n @@ -35030,6 +35507,9 @@ usb:v0D50* usb:v0D50p0011* ID_MODEL_FROM_DATABASE=USB-Temp2 Thermometer +usb:v0D50p0040* + ID_MODEL_FROM_DATABASE=F4 foot switch + usb:v0D51* ID_VENDOR_FROM_DATABASE=Volex (Asia) Pte., Ltd @@ -36584,6 +37064,9 @@ usb:v0E79p1416* usb:v0E79p1417* ID_MODEL_FROM_DATABASE=A43 IT +usb:v0E79p14AD* + ID_MODEL_FROM_DATABASE=97 Titanium HD + usb:v0E79p150E* ID_MODEL_FROM_DATABASE=80 G9 @@ -37139,6 +37622,9 @@ usb:v0F53* usb:v0F54* ID_VENDOR_FROM_DATABASE=Kawai Musical Instruments Mfg. Co., Ltd +usb:v0F54p0101* + ID_MODEL_FROM_DATABASE=MP6 Stage Piano + usb:v0F55* ID_VENDOR_FROM_DATABASE=AmbiCom, Inc. @@ -37433,6 +37919,9 @@ usb:v0FCEp015A* usb:v0FCEp0166* ID_MODEL_FROM_DATABASE=Xperia Mini Pro +usb:v0FCEp0167* + ID_MODEL_FROM_DATABASE=ST15i (Xperia mini) + usb:v0FCEp0169* ID_MODEL_FROM_DATABASE=Xperia S @@ -37478,15 +37967,24 @@ usb:v0FCEp3149* usb:v0FCEp5177* ID_MODEL_FROM_DATABASE=Xperia Ion [Debug Mode] +usb:v0FCEp518C* + ID_MODEL_FROM_DATABASE=C1605 [Xperia E dual] MTD mode + usb:v0FCEp614F* ID_MODEL_FROM_DATABASE=Xperia X12 (debug mode) usb:v0FCEp6166* ID_MODEL_FROM_DATABASE=Xperia Mini Pro +usb:v0FCEp618C* + ID_MODEL_FROM_DATABASE=C1605 [Xperia E dual] MSC mode + usb:v0FCEp715A* ID_MODEL_FROM_DATABASE=Xperia Pro [Tethering] +usb:v0FCEp7166* + ID_MODEL_FROM_DATABASE=Xperia Mini Pro (Tethering mode) + usb:v0FCEp7177* ID_MODEL_FROM_DATABASE=Xperia Ion [Tethering] @@ -37649,6 +38147,12 @@ usb:v0FD0* usb:v0FD1* ID_VENDOR_FROM_DATABASE=Giant Electronics Ltd. +usb:v0FD2* + ID_VENDOR_FROM_DATABASE=Seac Banche + +usb:v0FD2p0001* + ID_MODEL_FROM_DATABASE=RDS 6000 + usb:v0FD4* ID_VENDOR_FROM_DATABASE=Tenovis GmbH & Co., KG @@ -37817,9 +38321,30 @@ usb:v1004p61C6* usb:v1004p61CC* ID_MODEL_FROM_DATABASE=Optimus S +usb:v1004p61F1* + ID_MODEL_FROM_DATABASE=Optimus Android Phone [LG Software mode] + +usb:v1004p61F9* + ID_MODEL_FROM_DATABASE=V909 G-Slate + usb:v1004p61FC* ID_MODEL_FROM_DATABASE=Optimus 3 +usb:v1004p61FE* + ID_MODEL_FROM_DATABASE=Optimus Android Phone [USB tethering mode] + +usb:v1004p6300* + ID_MODEL_FROM_DATABASE=Optimus Android Phone + +usb:v1004p631C* + ID_MODEL_FROM_DATABASE=Optimus Android Phone [MTP mode] + +usb:v1004p631E* + ID_MODEL_FROM_DATABASE=Optimus Android Phone [Camera/PTP mode] + +usb:v1004p6356* + ID_MODEL_FROM_DATABASE=Optimus Android Phone [Virtual CD mode] + usb:v1004p6800* ID_MODEL_FROM_DATABASE=CDMA Modem @@ -38033,6 +38558,9 @@ usb:v1038* usb:v1038p0100* ID_MODEL_FROM_DATABASE=Zboard +usb:v1038p1361* + ID_MODEL_FROM_DATABASE=Sensei + usb:v1039* ID_VENDOR_FROM_DATABASE=devolo AG @@ -38180,6 +38708,15 @@ usb:v1050* usb:v1050p0010* ID_MODEL_FROM_DATABASE=Yubikey +usb:v1050p0110* + ID_MODEL_FROM_DATABASE=Yubikey NEO OTP + +usb:v1050p0111* + ID_MODEL_FROM_DATABASE=Yubikey NEO OTP+CCID + +usb:v1050p0211* + ID_MODEL_FROM_DATABASE=Gnubby + usb:v1053* ID_VENDOR_FROM_DATABASE=Immanuel Electronics Co., Ltd @@ -38223,7 +38760,10 @@ usb:v1058p070A* ID_MODEL_FROM_DATABASE=My Passport Essential SE usb:v1058p071A* - ID_MODEL_FROM_DATABASE=My Passport 1TB + ID_MODEL_FROM_DATABASE=My Passport + +usb:v1058p0730* + ID_MODEL_FROM_DATABASE=My Passport usb:v1058p0740* ID_MODEL_FROM_DATABASE=My Passport @@ -38579,6 +39119,9 @@ usb:v1082* usb:v1083* ID_VENDOR_FROM_DATABASE=Canon Electronics, Inc. +usb:v1083p161B* + ID_MODEL_FROM_DATABASE=DR-2010C Scanner + usb:v1083p162C* ID_MODEL_FROM_DATABASE=P-150 Scanner @@ -38792,6 +39335,9 @@ usb:v10C4p87BE* usb:v10C4p8863* ID_MODEL_FROM_DATABASE=C8051F34x Bootloader +usb:v10C4p8897* + ID_MODEL_FROM_DATABASE=C8051F38x HDMI Splitter [UHBX] + usb:v10C4pEA60* ID_MODEL_FROM_DATABASE=CP210x UART Bridge / myAVR mySmartUSB light @@ -38828,6 +39374,9 @@ usb:v10CD* usb:v10CE* ID_VENDOR_FROM_DATABASE=Silicon Labs +usb:v10CEp000E* + ID_MODEL_FROM_DATABASE=Shinko/Sinfonia CHC-S2145 + usb:v10CEpEA6A* ID_MODEL_FROM_DATABASE=MobiData EDGE USB Modem @@ -38867,6 +39416,9 @@ usb:v10D4* usb:v10D5* ID_VENDOR_FROM_DATABASE=Uni Class Technology Co., Ltd +usb:v10D5p0004* + ID_MODEL_FROM_DATABASE=PS/2 Converter + usb:v10D5p5552* ID_MODEL_FROM_DATABASE=KVM Human Interface Composite Device (Keyboard/Mouse ports) @@ -39584,6 +40136,9 @@ usb:v120Fp5260* usb:v1210* ID_VENDOR_FROM_DATABASE=DigiTech +usb:v1210p0016* + ID_MODEL_FROM_DATABASE=RP500 Guitar Multi-Effects Processor + usb:v1210p001B* ID_MODEL_FROM_DATABASE=RP155 Guitar Multi-Effects Processor @@ -39599,6 +40154,15 @@ usb:v121Ep3403* usb:v1223* ID_VENDOR_FROM_DATABASE=SKYCABLE ENTERPRISE. CO., LTD. +usb:v1228* + ID_VENDOR_FROM_DATABASE=Datapaq Limited + +usb:v1228p0012* + ID_MODEL_FROM_DATABASE=Q18 Data Logger + +usb:v1228p0015* + ID_MODEL_FROM_DATABASE=TPaq21/MPaq21 Datalogger + usb:v1230* ID_VENDOR_FROM_DATABASE=Chipidea-Microelectronica, S.A. @@ -40043,6 +40607,9 @@ usb:v12D1p14C8* usb:v12D1p14C9* ID_MODEL_FROM_DATABASE=K3770 3G Modem +usb:v12D1p14CF* + ID_MODEL_FROM_DATABASE=K3772 + usb:v12D1p14D1* ID_MODEL_FROM_DATABASE=K3770 3G Modem (Mass Storage Mode) @@ -40056,7 +40623,7 @@ usb:v12D1p1505* ID_MODEL_FROM_DATABASE=E398 LTE/UMTS/GSM Modem/Networkcard usb:v12D1p1506* - ID_MODEL_FROM_DATABASE=E398 LTE/UMTS/GSM Modem/Networkcard + ID_MODEL_FROM_DATABASE=Modem/Networkcard usb:v12D1p150A* ID_MODEL_FROM_DATABASE=E398 LTE/UMTS/GSM Modem/Networkcard @@ -40067,6 +40634,9 @@ usb:v12D1p1520* usb:v12D1p1521* ID_MODEL_FROM_DATABASE=K4505 HSPA+ +usb:v12D1p155A* + ID_MODEL_FROM_DATABASE=R205 Mobile WiFi (CD-ROM mode) + usb:v12D1p1805* ID_MODEL_FROM_DATABASE=AT&T Go Phone U2800A phone @@ -40076,6 +40646,9 @@ usb:v12D1p1C05* usb:v12D1p1C0B* ID_MODEL_FROM_DATABASE=E173s 3G broadband stick (modem off) +usb:v12D1p1C20* + ID_MODEL_FROM_DATABASE=R205 Mobile WiFi (Charging) + usb:v12D1p1D50* ID_MODEL_FROM_DATABASE=ET302s TD-SCDMA/TD-HSDPA Mobile Broadband @@ -40481,6 +41054,9 @@ usb:v138Ap0018* usb:v138Ap003C* ID_MODEL_FROM_DATABASE=VFS471 Fingerprint Reader +usb:v138Ap003D* + ID_MODEL_FROM_DATABASE=VFS491 + usb:v138E* ID_VENDOR_FROM_DATABASE=Jungo LTD @@ -40922,6 +41498,15 @@ usb:v1403* usb:v1403p0001* ID_MODEL_FROM_DATABASE=Digital Photo Frame +usb:v1409* + ID_VENDOR_FROM_DATABASE=IDS Imaging Development Systems GmbH + +usb:v1409p1000* + ID_MODEL_FROM_DATABASE=generic (firmware not loaded yet) + +usb:v1409p1485* + ID_MODEL_FROM_DATABASE=uEye UI1485 + usb:v140E* ID_VENDOR_FROM_DATABASE=Telechips, Inc. @@ -41075,6 +41660,9 @@ usb:v1446* usb:v1446p6A73* ID_MODEL_FROM_DATABASE=Stamps.com Model 510 5LB Scale +usb:v1446p6A78* + ID_MODEL_FROM_DATABASE=DYMO Endicia 75lb Digital Scale + usb:v1453* ID_VENDOR_FROM_DATABASE=Radio Shack @@ -41189,6 +41777,9 @@ usb:v147ApE03A* usb:v147ApE03C* ID_MODEL_FROM_DATABASE=eHome Infrared Receiver +usb:v147ApE03D* + ID_MODEL_FROM_DATABASE=2 Channel Audio + usb:v147ApE03E* ID_MODEL_FROM_DATABASE=Infrared Receiver [IR605A/Q] @@ -41471,6 +42062,12 @@ usb:v14DD* usb:v14DDp1007* ID_MODEL_FROM_DATABASE=D2CIM-VUSB KVM connector +usb:v14E0* + ID_VENDOR_FROM_DATABASE=WiNRADiO Communications + +usb:v14E0p0501* + ID_MODEL_FROM_DATABASE=WR-G528e 'CHEETAH' + usb:v14E1* ID_VENDOR_FROM_DATABASE=Dialogue Technology Corp. @@ -41597,6 +42194,9 @@ usb:v152D* usb:v152Dp0539* ID_MODEL_FROM_DATABASE=JMS539 SuperSpeed SATA II 3.0G Bridge +usb:v152Dp0770* + ID_MODEL_FROM_DATABASE=Alienware Integrated Webcam + usb:v152Dp2329* ID_MODEL_FROM_DATABASE=JM20329 SATA Bridge @@ -41657,6 +42257,9 @@ usb:v1532p001C* usb:v1532p0024* ID_MODEL_FROM_DATABASE=Razer Mamba +usb:v1532p002E* + ID_MODEL_FROM_DATABASE=RZ01-0058 Gaming Mouse [Naga] + usb:v1532p0036* ID_MODEL_FROM_DATABASE=RZ01-0075, Gaming Mouse [Naga Hex] @@ -41819,6 +42422,9 @@ usb:v1598* usb:v15A2* ID_VENDOR_FROM_DATABASE=Freescale Semiconductor, Inc. +usb:v15A2p0038* + ID_MODEL_FROM_DATABASE=9S08JS Bootloader + usb:v15A2p003B* ID_MODEL_FROM_DATABASE=USB2CAN Application for ColdFire DEMOJM board @@ -42044,6 +42650,9 @@ usb:v15E4* usb:v15E4p0024* ID_MODEL_FROM_DATABASE=Mixtrack +usb:v15E4p0140* + ID_MODEL_FROM_DATABASE=ION VCR 2 PC / Video 2 PC + usb:v15E8* ID_VENDOR_FROM_DATABASE=SohoWare @@ -43043,6 +43652,9 @@ usb:v16D0p054B* usb:v16D0p05BE* ID_MODEL_FROM_DATABASE=EasyLogic Board +usb:v16D0p06F9* + ID_MODEL_FROM_DATABASE=Gabotronics Xminilab + usb:v16D0p0753* ID_MODEL_FROM_DATABASE=Digistump DigiSpark @@ -43052,6 +43664,9 @@ usb:v16D0p075C* usb:v16D0p075D* ID_MODEL_FROM_DATABASE=AB-1.x UAC2 [Audio Widget] +usb:v16D0p080A* + ID_MODEL_FROM_DATABASE=S2E1 Interface + usb:v16D3* ID_VENDOR_FROM_DATABASE=Frontline Test Equipment, Inc. @@ -43367,6 +43982,12 @@ usb:v1753* usb:v1753pC901* ID_MODEL_FROM_DATABASE=PPC900 Pinpad Terminal +usb:v1756* + ID_VENDOR_FROM_DATABASE=ENENSYS Technologies + +usb:v1756p0006* + ID_MODEL_FROM_DATABASE=DiviPitch + usb:v1759* ID_VENDOR_FROM_DATABASE=LucidPort Technology, Inc. @@ -43496,12 +44117,21 @@ usb:v17A0p0200* usb:v17A0p0201* ID_MODEL_FROM_DATABASE=StudioDock monitors (audio) +usb:v17A0p0210* + ID_MODEL_FROM_DATABASE=StudioGT monitors + usb:v17A0p0301* ID_MODEL_FROM_DATABASE=Q2U handheld microphone with XLR usb:v17A0p0302* ID_MODEL_FROM_DATABASE=GoMic compact condenser microphone +usb:v17A0p0304* + ID_MODEL_FROM_DATABASE=Q2U handheld mic with XLR + +usb:v17A0p0305* + ID_MODEL_FROM_DATABASE=GoMic compact condenser mic + usb:v17A0p0310* ID_MODEL_FROM_DATABASE=Meteor condenser microphone @@ -43535,6 +44165,12 @@ usb:v17B3* usb:v17B3p0004* ID_MODEL_FROM_DATABASE=Linux-USB Midi Gadget +usb:v17B5* + ID_VENDOR_FROM_DATABASE=Lunatone + +usb:v17B5p0010* + ID_MODEL_FROM_DATABASE=MFT Sensor + usb:v17BA* ID_VENDOR_FROM_DATABASE=SAURIS GmbH @@ -43616,6 +44252,9 @@ usb:v17E9* usb:v17E9p0051* ID_MODEL_FROM_DATABASE=USB VGA Adaptor +usb:v17E9p030B* + ID_MODEL_FROM_DATABASE=HP T100 + usb:v17E9p0377* ID_MODEL_FROM_DATABASE=Plugable UD-160-A (M) @@ -43640,6 +44279,9 @@ usb:v17E9p037D* usb:v17E9p430A* ID_MODEL_FROM_DATABASE=HP Port Replicator (Composite Device) +usb:v17E9p4312* + ID_MODEL_FROM_DATABASE=S2340T + usb:v17EB* ID_VENDOR_FROM_DATABASE=Cornice, Inc. @@ -43652,6 +44294,9 @@ usb:v17EFp1003* usb:v17EFp1004* ID_MODEL_FROM_DATABASE=Integrated Webcam +usb:v17EFp1008* + ID_MODEL_FROM_DATABASE=Hub + usb:v17EFp100A* ID_MODEL_FROM_DATABASE=ThinkPad Mini Dock Plus Series 3 @@ -43694,12 +44339,18 @@ usb:v17EFp4814* usb:v17EFp4815* ID_MODEL_FROM_DATABASE=Integrated Webcam [R5U877] +usb:v17EFp4816* + ID_MODEL_FROM_DATABASE=Integrated Webcam + usb:v17EFp481C* ID_MODEL_FROM_DATABASE=Integrated Webcam usb:v17EFp481D* ID_MODEL_FROM_DATABASE=Integrated Webcam +usb:v17EFp6004* + ID_MODEL_FROM_DATABASE=ISD-V4 Tablet Pen + usb:v17EFp6007* ID_MODEL_FROM_DATABASE=Smartcard Keyboard @@ -43835,6 +44486,9 @@ usb:v1873pEE93* usb:v187C* ID_VENDOR_FROM_DATABASE=Alienware Corporation +usb:v187Cp0511* + ID_MODEL_FROM_DATABASE=AlienFX Mobile lighting + usb:v187Cp0600* ID_MODEL_FROM_DATABASE=Dual Compatible Game Pad @@ -43911,7 +44565,7 @@ usb:v18A5p0237* ID_MODEL_FROM_DATABASE=Portable Harddrive (500 GB) usb:v18A5p0302* - ID_MODEL_FROM_DATABASE=32GB Flash Drive + ID_MODEL_FROM_DATABASE=Flash Drive usb:v18B1* ID_VENDOR_FROM_DATABASE=Petalynx @@ -43998,16 +44652,16 @@ usb:v18D1p4E40* ID_MODEL_FROM_DATABASE=Nexus 7 (fastboot) usb:v18D1p4E41* - ID_MODEL_FROM_DATABASE=ASUS Nexus 7 (MTP modus) + ID_MODEL_FROM_DATABASE=Nexus 7 (MTP) usb:v18D1p4E42* ID_MODEL_FROM_DATABASE=Nexus 7 (debug) usb:v18D1p4E43* - ID_MODEL_FROM_DATABASE=ASUS Nexus 7 (PTP modus) + ID_MODEL_FROM_DATABASE=Nexus 7 (PTP) usb:v18D1p4EE1* - ID_MODEL_FROM_DATABASE=Nexus 4 + ID_MODEL_FROM_DATABASE=Nexus 4 / 10 usb:v18D1p4EE2* ID_MODEL_FROM_DATABASE=Nexus 4 (debug) @@ -44024,6 +44678,12 @@ usb:v18D1p7102* usb:v18D1pB004* ID_MODEL_FROM_DATABASE=Pandigital / B&N Novel 9" tablet +usb:v18D1pD109* + ID_MODEL_FROM_DATABASE=LG G2x MTP + +usb:v18D1pD10A* + ID_MODEL_FROM_DATABASE=LG G2x MTP (debug) + usb:v18D5* ID_VENDOR_FROM_DATABASE=Starline International Group Limited @@ -44114,6 +44774,9 @@ usb:v1914* usb:v1915* ID_VENDOR_FROM_DATABASE=Nordic Semiconductor ASA +usb:v1915p000C* + ID_MODEL_FROM_DATABASE=Wireless Desktop nRF24L01 CX-1766 + usb:v1915p2233* ID_MODEL_FROM_DATABASE=Linksys WUSB11 v2.8 802.11b Adapter [Atmel AT76C505] @@ -44126,6 +44789,12 @@ usb:v1915p2235* usb:v1915p2236* ID_MODEL_FROM_DATABASE=Linksys WUSB11 v3.0 802.11b Adapter [Intersil PRISM 3] +usb:v1923* + ID_VENDOR_FROM_DATABASE=FitLinxx + +usb:v1923p0002* + ID_MODEL_FROM_DATABASE=Personal SyncPoint + usb:v1926* ID_VENDOR_FROM_DATABASE=NextWindow @@ -44213,6 +44882,9 @@ usb:v1926p0086* usb:v1926p0087* ID_MODEL_FROM_DATABASE=1950 HID Touchscreen +usb:v1926p0DC2* + ID_MODEL_FROM_DATABASE=HID Touchscreen + usb:v192F* ID_VENDOR_FROM_DATABASE=Avago Technologies, Pte. @@ -44306,6 +44978,9 @@ usb:v1951* usb:v1953* ID_VENDOR_FROM_DATABASE=Ironkey Inc. +usb:v1953p0202* + ID_MODEL_FROM_DATABASE=S200 2GB Rev. 1 + usb:v1954* ID_VENDOR_FROM_DATABASE=Radiient Technologies @@ -44543,6 +45218,12 @@ usb:v19D2pFFF2* usb:v19D2pFFF3* ID_MODEL_FROM_DATABASE=Gobi Wireless Modem +usb:v19DB* + ID_VENDOR_FROM_DATABASE=KFI Printers + +usb:v19DBp02F1* + ID_MODEL_FROM_DATABASE=NAUT324C + usb:v19E1* ID_VENDOR_FROM_DATABASE=WeiDuan Electronic Accessory (S.Z.) Co., Ltd. @@ -44573,6 +45254,9 @@ usb:v19FFp0102* usb:v19FFp0201* ID_MODEL_FROM_DATABASE=Rocketfish Wireless 2.4G Laser Mouse +usb:v19FFp0238* + ID_MODEL_FROM_DATABASE=DX-WRM1401 Mouse + usb:v1A08* ID_VENDOR_FROM_DATABASE=Bellwood International, Inc. @@ -44625,7 +45309,7 @@ usb:v1A40* ID_VENDOR_FROM_DATABASE=Terminus Technology Inc. usb:v1A40p0101* - ID_MODEL_FROM_DATABASE=4-Port HUB + ID_MODEL_FROM_DATABASE=Hub usb:v1A40p0201* ID_MODEL_FROM_DATABASE=FE 2.1 7-port Hub @@ -44675,6 +45359,12 @@ usb:v1A72p1008* usb:v1A79* ID_VENDOR_FROM_DATABASE=Bayer Health Care LLC +usb:v1A79p6002* + ID_MODEL_FROM_DATABASE=Contour + +usb:v1A79p7410* + ID_MODEL_FROM_DATABASE=Contour Next + usb:v1A7B* ID_VENDOR_FROM_DATABASE=Lumberg Connect GmbH & Co. KG @@ -44771,6 +45461,12 @@ usb:v1AB1p0588* usb:v1ACB* ID_VENDOR_FROM_DATABASE=Salcomp Plc +usb:v1ACC* + ID_VENDOR_FROM_DATABASE=Midiplus Co, Ltd. + +usb:v1ACCp0103* + ID_MODEL_FROM_DATABASE=AudioLink plus 4x4 2.9.28 + usb:v1AD1* ID_VENDOR_FROM_DATABASE=Desay Wire Co., Ltd. @@ -45197,6 +45893,75 @@ usb:v1B47p0001* usb:v1B48* ID_VENDOR_FROM_DATABASE=Plastron Precision Co., Ltd. +usb:v1B52* + ID_VENDOR_FROM_DATABASE=ARH Inc. + +usb:v1B52p2101* + ID_MODEL_FROM_DATABASE=FXMC Neural Network Controller + +usb:v1B52p2102* + ID_MODEL_FROM_DATABASE=FXMC Neural Network Controller V2 + +usb:v1B52p2103* + ID_MODEL_FROM_DATABASE=FXMC Neural Network Controller V3 + +usb:v1B52p4101* + ID_MODEL_FROM_DATABASE=Passport Reader CLR device + +usb:v1B52p4201* + ID_MODEL_FROM_DATABASE=Passport Reader PRM device + +usb:v1B52p4202* + ID_MODEL_FROM_DATABASE=Passport Reader PRM extension device + +usb:v1B52p4203* + ID_MODEL_FROM_DATABASE=Passport Reader PRM DSP device + +usb:v1B52p4204* + ID_MODEL_FROM_DATABASE=Passport Reader PRMC device + +usb:v1B52p4205* + ID_MODEL_FROM_DATABASE=Passport Reader CSHR device + +usb:v1B52p4206* + ID_MODEL_FROM_DATABASE=Passport Reader PRMC V2 device + +usb:v1B52p4301* + ID_MODEL_FROM_DATABASE=Passport Reader MRZ device + +usb:v1B52p4302* + ID_MODEL_FROM_DATABASE=Passport Reader MRZ DSP device + +usb:v1B52p4303* + ID_MODEL_FROM_DATABASE=Passport Reader CSLR device + +usb:v1B52p4401* + ID_MODEL_FROM_DATABASE=Card Reader + +usb:v1B52p4501* + ID_MODEL_FROM_DATABASE=Passport Reader RFID device + +usb:v1B52p4502* + ID_MODEL_FROM_DATABASE=Passport Reader RFID AIG device + +usb:v1B52p6101* + ID_MODEL_FROM_DATABASE=Neural Network Controller + +usb:v1B52p6202* + ID_MODEL_FROM_DATABASE=Fingerprint Reader device + +usb:v1B52p6203* + ID_MODEL_FROM_DATABASE=Fingerprint Scanner device + +usb:v1B52p8101* + ID_MODEL_FROM_DATABASE=Camera V1 + +usb:v1B52p8102* + ID_MODEL_FROM_DATABASE=Recovery / Camera V2 + +usb:v1B52p8103* + ID_MODEL_FROM_DATABASE=Camera V3 + usb:v1B59* ID_VENDOR_FROM_DATABASE=K.S. Terminals Inc. @@ -45350,6 +46115,12 @@ usb:v1BAEp0002* usb:v1BBB* ID_VENDOR_FROM_DATABASE=T & A Mobile Phones +usb:v1BBBp011E* + ID_MODEL_FROM_DATABASE=Alcatel One Touch L100V / Telekom Speedstick LTE II + +usb:v1BBBpF017* + ID_MODEL_FROM_DATABASE=Alcatel One Touch L100V / Telekom Speedstick LTE II + usb:v1BC4* ID_VENDOR_FROM_DATABASE=Ford Motor Co. @@ -45357,7 +46128,7 @@ usb:v1BC5* ID_VENDOR_FROM_DATABASE=AVIXE Technology (China) Ltd. usb:v1BC7* - ID_VENDOR_FROM_DATABASE=Telit + ID_VENDOR_FROM_DATABASE=Telit Wireless Solutions usb:v1BC7p0020* ID_MODEL_FROM_DATABASE=HE863 @@ -45365,6 +46136,9 @@ usb:v1BC7p0020* usb:v1BC7p0021* ID_MODEL_FROM_DATABASE=HE910 +usb:v1BC7p0023* + ID_MODEL_FROM_DATABASE=HE910-D ECM + usb:v1BC7p1003* ID_MODEL_FROM_DATABASE=UC864-E @@ -45380,6 +46154,12 @@ usb:v1BC7p1006* usb:v1BC7p1010* ID_MODEL_FROM_DATABASE=DE910-DUAL +usb:v1BC7p1011* + ID_MODEL_FROM_DATABASE=CE910-DUAL + +usb:v1BC7p1200* + ID_MODEL_FROM_DATABASE=LE920 + usb:v1BCE* ID_VENDOR_FROM_DATABASE=Contac Cable Industrial Limited @@ -45407,6 +46187,9 @@ usb:v1BCFp2885* usb:v1BCFp2888* ID_MODEL_FROM_DATABASE=HP Universal Camera +usb:v1BCFp2B83* + ID_MODEL_FROM_DATABASE=Laptop Integrated Webcam FHD + usb:v1BD0* ID_VENDOR_FROM_DATABASE=Hangzhou Riyue Electronic Co., Ltd. @@ -45662,6 +46445,9 @@ usb:v1CBEp00FD* usb:v1CBEp00FF* ID_MODEL_FROM_DATABASE=Stellaris ROM DFU Bootloader +usb:v1CBEp0166* + ID_MODEL_FROM_DATABASE=CANAL USB2CAN + usb:v1CBF* ID_VENDOR_FROM_DATABASE=FORTAT SKYMARK INDUSTRIAL COMPANY @@ -45827,6 +46613,12 @@ usb:v1D34p000D* usb:v1D34p0013* ID_MODEL_FROM_DATABASE=Dream Cheeky LED Message Board +usb:v1D45* + ID_VENDOR_FROM_DATABASE=Touch + +usb:v1D45p1D45* + ID_MODEL_FROM_DATABASE=Foxlink Optical touch sensor + usb:v1D4D* ID_VENDOR_FROM_DATABASE=PEGATRON CORPORATION @@ -45848,6 +46640,9 @@ usb:v1D50p5119* usb:v1D50p602B* ID_MODEL_FROM_DATABASE=FPGALink +usb:v1D50p6053* + ID_MODEL_FROM_DATABASE=Darkgame Controller + usb:v1D57* ID_VENDOR_FROM_DATABASE=Xenta @@ -45914,6 +46709,12 @@ usb:v1D6Bp0105* usb:v1D6Bp0200* ID_MODEL_FROM_DATABASE=Qemu Audio Device +usb:v1D90* + ID_VENDOR_FROM_DATABASE=Citizen + +usb:v1D90p201E* + ID_MODEL_FROM_DATABASE=PPU-700 + usb:v1DE1* ID_VENDOR_FROM_DATABASE=Actions Microelectronics Co. @@ -46043,6 +46844,9 @@ usb:v1E68* usb:v1E68p001B* ID_MODEL_FROM_DATABASE=DataStation maxi g.u +usb:v1E68p0050* + ID_MODEL_FROM_DATABASE=DataStation maxi light + usb:v1E71* ID_VENDOR_FROM_DATABASE=NZXT @@ -46127,9 +46931,18 @@ usb:v1EE8p0014* usb:v1EF6* ID_VENDOR_FROM_DATABASE=EADS Deutschland GmbH +usb:v1EF6p2233* + ID_MODEL_FROM_DATABASE=Cassidian NH90 STTE + usb:v1EF6p5064* ID_MODEL_FROM_DATABASE=FDR Interface +usb:v1EF6p5523* + ID_MODEL_FROM_DATABASE=Cassidian SSDC Adapter II + +usb:v1EF6p5545* + ID_MODEL_FROM_DATABASE=Cassidian SSDC Adapter III + usb:v1EF6p5648* ID_MODEL_FROM_DATABASE=RIU CSMU/BSD @@ -46145,6 +46958,12 @@ usb:v1F28p0020* usb:v1F28p0021* ID_MODEL_FROM_DATABASE=CD INSTALLER USB Device +usb:v1F3A* + ID_VENDOR_FROM_DATABASE=Onda (unverified) + +usb:v1F3ApEFE8* + ID_MODEL_FROM_DATABASE=V972 tablet in flashing mode + usb:v1F44* ID_VENDOR_FROM_DATABASE=The Neat Company -- cgit v1.2.1 From 0b429ab7fca2aa139ffbeeac8bdcfbbd21cc1a60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mantas=20Mikul=C4=97nas?= Date: Thu, 12 Sep 2013 00:53:36 +0300 Subject: man: fix description of sysctl.d order systemd-sysctl gives priority to the latest occurence as of commit 04bf3c1a60d82791e0320381e9268f727708f776, but the manpage hasn't been updated for that. --- man/sysctl.d.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/sysctl.d.xml b/man/sysctl.d.xml index 69e96ee9e5..ce5c34f9a2 100644 --- a/man/sysctl.d.xml +++ b/man/sysctl.d.xml @@ -92,7 +92,7 @@ alphabetical order, regardless in which of the directories they reside, to guarantee that a specific configuration file takes precedence over another file - with an alphabetically later name, if both files + with an alphabetically earlier name, if both files contain the same variable setting. If the administrator wants to disable a -- cgit v1.2.1 From ac4c8d6da8b5ebc35f02c9c6cb7595be7b134a05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 11 Sep 2013 21:50:16 -0400 Subject: Allow tabs in environment files bash allows them, and so should we. string_has_cc is changed to allow tabs, and if they are not wanted, they must be now checked for explicitly. There are two other callers, apart from the env file loaders, and one already checked anyway, and the other is changed to check. https://bugs.freedesktop.org/show_bug.cgi?id=68592 https://bugs.gentoo.org/show_bug.cgi?id=481554 --- src/hostname/hostnamed.c | 3 ++- src/shared/util.c | 4 ++++ src/test/test-fileio.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c index 0437e33a66..6a43aeb840 100644 --- a/src/hostname/hostnamed.c +++ b/src/hostname/hostnamed.c @@ -553,7 +553,8 @@ static DBusHandlerResult hostname_message_handler( * safe than sorry */ if (k == PROP_ICON_NAME && !filename_is_safe(name)) return bus_send_error_reply(connection, message, NULL, -EINVAL); - if (k == PROP_PRETTY_HOSTNAME && string_has_cc(name)) + if (k == PROP_PRETTY_HOSTNAME && + (string_has_cc(name) || chars_intersect(name, "\t"))) return bus_send_error_reply(connection, message, NULL, -EINVAL); if (k == PROP_CHASSIS && !valid_chassis(name)) return bus_send_error_reply(connection, message, NULL, -EINVAL); diff --git a/src/shared/util.c b/src/shared/util.c index 1dde8afcad..ad463e8399 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -5311,6 +5311,10 @@ bool string_is_safe(const char *p) { return true; } +/** + * Check if a string contains control characters. + * Spaces and tabs are not considered control characters. + */ bool string_has_cc(const char *p) { const char *t; diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c index 76a43d9b69..1184e7e02f 100644 --- a/src/test/test-fileio.c +++ b/src/test/test-fileio.c @@ -142,6 +142,59 @@ static void test_parse_env_file(void) { unlink(p); } +static void test_parse_multiline_env_file(void) { + char t[] = "/tmp/test-fileio-in-XXXXXX", + p[] = "/tmp/test-fileio-out-XXXXXX"; + int fd, r; + FILE *f; + _cleanup_strv_free_ char **a = NULL, **b = NULL; + char **i; + + assert_se(mktemp(p)); + + fd = mkostemp(t, O_CLOEXEC); + assert_se(fd >= 0); + + f = fdopen(fd, "w"); + assert_se(f); + + fputs("one=BAR\\\n" + " VAR\\\n" + "\tGAR\n" + "#comment\n" + "two=\"bar\\\n" + " var\\\n" + "\tgar\"\n" + "#comment\n" + "tri=\"bar \\\n" + " var \\\n" + "\tgar \"\n", f); + + fflush(f); + fclose(f); + + r = load_env_file(t, NULL, &a); + assert_se(r >= 0); + + STRV_FOREACH(i, a) + log_info("Got: <%s>", *i); + + assert_se(streq(a[0], "one=BAR VAR\tGAR")); + assert_se(streq(a[1], "two=bar var\tgar")); + assert_se(streq(a[2], "tri=bar var \tgar ")); + assert_se(a[3] == NULL); + + r = write_env_file(p, a); + assert_se(r >= 0); + + r = load_env_file(p, NULL, &b); + assert_se(r >= 0); + + unlink(t); + unlink(p); +} + + static void test_executable_is_script(void) { char t[] = "/tmp/test-executable-XXXXXX"; int fd, r; @@ -178,6 +231,7 @@ static void test_executable_is_script(void) { int main(int argc, char *argv[]) { test_parse_env_file(); + test_parse_multiline_env_file(); test_executable_is_script(); return 0; } -- cgit v1.2.1 From 7b4977254cdc1203b44211e00cdb3a0c318cfcf2 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 12 Sep 2013 04:00:24 +0200 Subject: man: fix description of file order application --- man/binfmt.d.xml | 6 +++--- man/sysctl.d.xml | 10 ++++++---- man/systemd.preset.xml | 11 +++++------ man/tmpfiles.d.xml | 7 ++++--- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/man/binfmt.d.xml b/man/binfmt.d.xml index f4f4195b04..165a8a97b1 100644 --- a/man/binfmt.d.xml +++ b/man/binfmt.d.xml @@ -89,9 +89,9 @@ configuration files installed from vendor packages. All files are sorted by their filename in alphabetical order, regardless in which of the - directories they reside, to guarantee that a specific - configuration file takes precedence over another file - with an alphabetically later name. + directories they reside. If multiple files specify + the same binary type name, the entry in the file with + the alphabetically latest name will be applied. If the administrator wants to disable a configuration file supplied by the vendor, the diff --git a/man/sysctl.d.xml b/man/sysctl.d.xml index ce5c34f9a2..155427cecf 100644 --- a/man/sysctl.d.xml +++ b/man/sysctl.d.xml @@ -90,10 +90,12 @@ configuration files installed by vendor packages. All configuration files are sorted by their filename in alphabetical order, regardless in which of the - directories they reside, to guarantee that a specific - configuration file takes precedence over another file - with an alphabetically earlier name, if both files - contain the same variable setting. + directories they reside. If multiple files specify the + same variable name, the entry in the file with the + alphabetically latest name will be applied. It is + recommended to prefix all filenames with a two-digit + number and a dash, to simplify the ordering of the + files. If the administrator wants to disable a configuration file supplied by the vendor, the diff --git a/man/systemd.preset.xml b/man/systemd.preset.xml index 1ba9272398..8af7d4058d 100644 --- a/man/systemd.preset.xml +++ b/man/systemd.preset.xml @@ -127,12 +127,11 @@ preset files installed by vendor packages. All preset files are sorted by their filename in alphabetical order, regardless in which of the directories they - reside, to guarantee that a specific preset file takes - precedence over another file with an alphabetically - earlier name, if both files contain lines that apply - to the same unit names. It is recommended to prefix - all filenames with two-digit number, to simplify - ordering. + reside. If multiple files specify the same unit name, + the entry in the file with the alphabetically earliest + name will be applied. It is recommended to prefix all + filenames with a two-digit number and a dash, to simplify + the ordering of the files. If the administrator wants to disable a preset file supplied by the vendor, the recommended way is to diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml index 58ac995a18..2872cc0add 100644 --- a/man/tmpfiles.d.xml +++ b/man/tmpfiles.d.xml @@ -80,9 +80,10 @@ configuration files installed by vendor packages. All configuration files are sorted by their filename in alphabetical order, regardless in which of the - directories they reside, to guarantee that a specific - configuration file takes precedence over another file - with an alphabetically later name. + directories they reside. If multiple files specify the + same path, the entry in the file with the alphabetically + earliest name will be applied, all all other conflicting + entries logged as errors. If the administrator wants to disable a configuration file supplied by the vendor the -- cgit v1.2.1 From 176cceb051fd9537239e5e8a43f80a33d06fe3b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 12 Sep 2013 07:59:34 -0400 Subject: hwdb: add Toshiba Satellite P75-A Contributed by Guillermo Dominguez Duarte . --- hwdb/60-keyboard.hwdb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index 640ff54443..eca3f559a9 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -1021,6 +1021,13 @@ keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite*M30X:pvr* KEYBOARD_KEY_9e=f22 # touchpad enable KEYBOARD_KEY_9f=f23 # touchpad disable +# Satellite P75-A +keyboard:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite*P75-A:pvr* + KEYBOARD_KEY_ef=brightnessdown + KEYBOARD_KEY_ee=brightnessup + KEYBOARD_KEY_a9=switchvideomode # switch display outputs + KEYBOARD_KEY_d4=wlan # RF Switch Off + ########################################################### # VIA ########################################################### -- cgit v1.2.1 From 39f0570d6ea01476dd82bbcae60f51f97f614cec Mon Sep 17 00:00:00 2001 From: Michael Marineau Date: Fri, 16 Aug 2013 20:28:24 -0400 Subject: getty-generator: Enable getty on all active serial consoles. This enables a getty on active kernel consoles even when they are not the last one specified on the kernel command line and mapped to /dev/console. Now the order "console=ttyS0 console=tty0" works in addition to "console=tty0 console=ttyS0". --- src/getty-generator/getty-generator.c | 37 ++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/getty-generator/getty-generator.c b/src/getty-generator/getty-generator.c index 4b7a60a4ec..6c938062de 100644 --- a/src/getty-generator/getty-generator.c +++ b/src/getty-generator/getty-generator.c @@ -122,33 +122,42 @@ int main(int argc, char *argv[]) { } if (read_one_line_file("/sys/class/tty/console/active", &active) >= 0) { - const char *tty; - - tty = strrchr(active, ' '); - if (tty) - tty ++; - else - tty = active; - - /* Automatically add in a serial getty on the kernel - * console */ - if (isempty(tty) || tty_is_vc(tty)) - free(active); - else { + char *w, *state; + size_t l; + + /* Automatically add in a serial getty on all active + * kernel consoles */ + FOREACH_WORD(w, l, active, state) { + char *tty; int k; + tty = strndup(w, l); + if (!tty) { + log_oom(); + free(active); + r = EXIT_FAILURE; + goto finish; + } + + if (isempty(tty) || tty_is_vc(tty)) { + free(tty); + continue; + } + /* We assume that gettys on virtual terminals are * started via manual configuration and do this magic * only for non-VC terminals. */ k = add_serial_getty(tty); - free(active); if (k < 0) { + free(tty); + free(active); r = EXIT_FAILURE; goto finish; } } + free(active); } /* Automatically add in a serial getty on the first -- cgit v1.2.1 From f4ae69117ba47e75ff89c7d847e180af9af7436a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 12 Sep 2013 09:29:01 -0400 Subject: man: Add a note about what environment variables are available by default --- man/systemd.exec.xml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 2c673a2a96..ff8b812ef4 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -76,6 +76,27 @@ configuration options are configured in the [Service], [Socket], [Mount], or [Swap] sections, depending on the unit type. + + Processes started by the system systemd instance + are executed in a clean environment in which only the + $PATH and $LANG + variables are set by default. In order to add + additional variables, see the + Environment= and + EnvironmentFile= options below. To + specify variables globally, see + DefaultEnvironment= in + systemd-system.conf5 + or the kernel option + systemd.setenv= in + systemd1. Processes + started by the user systemd instances inherit all + environment variables from the user systemd instance, + and have $HOME, + $USER, + $XDG_RUNTIME_DIR defined, among + others. In addition, $MANAGERPID + contains the PID of the user systemd instance. -- cgit v1.2.1 From da2620a5f878ad5c8d8d51992528cb3e637c7d1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 12 Sep 2013 10:03:16 -0400 Subject: Actually allow tabs in environment files Fixup for ac4c8d6da8b5e. --- src/shared/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/util.c b/src/shared/util.c index ad463e8399..9a075fa163 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -5321,7 +5321,7 @@ bool string_has_cc(const char *p) { assert(p); for (t = p; *t; t++) - if (*t > 0 && *t < ' ') + if (*t > 0 && *t < ' ' && *t != '\t') return true; return false; -- cgit v1.2.1 From 7de778beab01a3184ee37a3e3b8cf23f40b996e4 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 12 Sep 2013 17:20:33 +0200 Subject: TODO: remove backlight tool --- TODO | 2 -- 1 file changed, 2 deletions(-) diff --git a/TODO b/TODO index 519657fa81..5824829861 100644 --- a/TODO +++ b/TODO @@ -64,8 +64,6 @@ Features: * better error message if you run systemctl without systemd running -* tiny tool that saves/restores backlight - * systemctl status output should should include list of triggering units and their status * for transient units, instead of writing out drop-ins for all properties consider serializing them in the normal serialization stream -- cgit v1.2.1 From c1e784feb4756226f09a94feeed81a3c0d9aac5e Mon Sep 17 00:00:00 2001 From: Michal Sekletar Date: Thu, 12 Sep 2013 15:42:24 +0200 Subject: systemctl: process only signals for jobs we really wait for wait_filter() callback shouldn't process JobRemove signals for arbitrary jobs. It should only deal with signals for jobs which are included in set of jobs we wait for. --- src/systemctl/systemctl.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index a305c3d87d..dc3e41bf42 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -1494,7 +1494,7 @@ static DBusHandlerResult wait_filter(DBusConnection *connection, DBusMessage *me } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Manager", "JobRemoved")) { uint32_t id; - const char *path, *result, *unit; + const char *path, *result, *unit, *r; if (dbus_message_get_args(message, &error, DBUS_TYPE_UINT32, &id, @@ -1503,7 +1503,11 @@ static DBusHandlerResult wait_filter(DBusConnection *connection, DBusMessage *me DBUS_TYPE_STRING, &result, DBUS_TYPE_INVALID)) { - free(set_remove(d->set, (char*) path)); + r = set_remove(d->set, (char*) path); + if (!r) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + free(r); if (!isempty(result)) d->result = strdup(result); @@ -1523,7 +1527,11 @@ static DBusHandlerResult wait_filter(DBusConnection *connection, DBusMessage *me /* Compatibility with older systemd versions < * 183 during upgrades. This should be dropped * one day. */ - free(set_remove(d->set, (char*) path)); + r = set_remove(d->set, (char*) path); + if (!r) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + free(r); if (*result) d->result = strdup(result); -- cgit v1.2.1 From fcba531ed4c6e6f8f21d8ca4e3a56e3162b1c578 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 12 Sep 2013 18:09:00 +0200 Subject: update TODO --- TODO | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/TODO b/TODO index 5824829861..7f6defb8e5 100644 --- a/TODO +++ b/TODO @@ -58,6 +58,19 @@ CGroup Rework Completion: Features: +* backlight: properly handle multiple backlight devices for the same + hardware: at shutdown we should only save the backlight setting for + the "best" way to access the backlight. Strategy should be: at + shutdown, ignore all backlights that are connected to a non-eDP or + non-LVDS port, and then prefer the firmware device over platform + device over raw device per-PCI card. Delete all old data. At boot + simply apply whatever data we find. Also see + http://cgit.freedesktop.org/libbacklight/tree/libbacklight.c#n194 + +* rfkill: save/restore soft rfkill status across reboots + +* refuse boot if /etc/os-release is missing or /etc/machine-id cannot be set up + * ensure scope units may be started only a single time * document that in instead of FsckPassNo= people should just add a manual dep to systemd-fsck@.service to their mount units. -- cgit v1.2.1 From 00a168618906bea43c3c57e20b9152582c324bf8 Mon Sep 17 00:00:00 2001 From: Olivier Brunel Date: Thu, 12 Sep 2013 14:37:30 +0200 Subject: journald: Log error when failed to get machine-id on start Can help since the journal requires /etc/machine-id to exists in order to start, and will simply silently exit when it does not. --- src/journal/journald-server.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 9daeb6e9e7..ba211b3724 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -897,8 +897,10 @@ static int system_journal_open(Server *s) { char ids[33]; r = sd_id128_get_machine(&machine); - if (r < 0) + if (r < 0) { + log_error("Failed to get machine id: %s", strerror(-r)); return r; + } sd_id128_to_string(machine, ids); @@ -1000,10 +1002,8 @@ int server_flush_to_var(Server *s) { log_debug("Flushing to /var..."); r = sd_id128_get_machine(&machine); - if (r < 0) { - log_error("Failed to get machine id: %s", strerror(-r)); + if (r < 0) return r; - } r = sd_journal_open(&j, SD_JOURNAL_RUNTIME_ONLY); if (r < 0) { -- cgit v1.2.1 From dc99a9764418a1974c46c55efa73b034f530a5a5 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 25 Jul 2013 14:07:59 +0200 Subject: service: Implement 'on-watchdog' restart option Services using the watchdog option might want to be restarted only if the watchdog triggers. --- man/systemd.service.xml | 5 +++++ src/core/service.c | 2 ++ src/core/service.h | 1 + 3 files changed, 8 insertions(+) diff --git a/man/systemd.service.xml b/man/systemd.service.xml index a15dfb2cb6..1eb5f39628 100644 --- a/man/systemd.service.xml +++ b/man/systemd.service.xml @@ -618,6 +618,7 @@ , , , + , , or . If set to (the default) the @@ -644,6 +645,10 @@ signal not specified as a clean exit status. If set to + the service + will be restarted only if the watchdog + timeout for the service expires. + If set to the service will be restarted regardless whether it exited cleanly or not, got diff --git a/src/core/service.c b/src/core/service.c index 34dde7963e..08b929e4fe 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -1937,6 +1937,7 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) (s->restart == SERVICE_RESTART_ALWAYS || (s->restart == SERVICE_RESTART_ON_SUCCESS && s->result == SERVICE_SUCCESS) || (s->restart == SERVICE_RESTART_ON_FAILURE && s->result != SERVICE_SUCCESS) || + (s->restart == SERVICE_RESTART_ON_WATCHDOG && s->result == SERVICE_FAILURE_WATCHDOG) || (s->restart == SERVICE_RESTART_ON_ABORT && (s->result == SERVICE_FAILURE_SIGNAL || s->result == SERVICE_FAILURE_CORE_DUMP))) && (s->result != SERVICE_FAILURE_EXIT_CODE || @@ -3791,6 +3792,7 @@ static const char* const service_restart_table[_SERVICE_RESTART_MAX] = { [SERVICE_RESTART_NO] = "no", [SERVICE_RESTART_ON_SUCCESS] = "on-success", [SERVICE_RESTART_ON_FAILURE] = "on-failure", + [SERVICE_RESTART_ON_WATCHDOG] = "on-watchdog", [SERVICE_RESTART_ON_ABORT] = "on-abort", [SERVICE_RESTART_ALWAYS] = "always" }; diff --git a/src/core/service.h b/src/core/service.h index 182cba1333..ce5b5e04ab 100644 --- a/src/core/service.h +++ b/src/core/service.h @@ -54,6 +54,7 @@ typedef enum ServiceRestart { SERVICE_RESTART_NO, SERVICE_RESTART_ON_SUCCESS, SERVICE_RESTART_ON_FAILURE, + SERVICE_RESTART_ON_WATCHDOG, SERVICE_RESTART_ON_ABORT, SERVICE_RESTART_ALWAYS, _SERVICE_RESTART_MAX, -- cgit v1.2.1 From d137a488afb59801177dc34c218f339bfbbdb044 Mon Sep 17 00:00:00 2001 From: Umut Tezduyar Date: Mon, 22 Jul 2013 10:52:53 +0200 Subject: core: notify triggered by socket of a service --- TODO | 3 --- src/core/service.c | 31 ------------------------------- src/core/socket.c | 39 ++++++++++++++++++++++++++++++++++++++- src/core/socket.h | 3 --- 4 files changed, 38 insertions(+), 38 deletions(-) diff --git a/TODO b/TODO index 7f6defb8e5..0946ffaefb 100644 --- a/TODO +++ b/TODO @@ -141,9 +141,6 @@ Features: Maybe take a BSD lock at the disk device node and teach udev to check for that and suppress event handling. -* when a service changes state make reflect that in the - RUNNING/LISTENING states of its socket - * when recursively showing the cgroup hierarchy, optionally also show the hierarchies of child processes diff --git a/src/core/service.c b/src/core/service.c index 08b929e4fe..246a86e23f 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -1489,24 +1489,6 @@ static int service_search_main_pid(Service *s) { return 0; } -static void service_notify_sockets_dead(Service *s, bool failed_permanent) { - Iterator i; - Unit *u; - - assert(s); - - /* Notifies all our sockets when we die */ - - if (s->socket_fd >= 0) - return; - - SET_FOREACH(u, UNIT(s)->dependencies[UNIT_TRIGGERED_BY], i) - if (u->type == UNIT_SOCKET) - socket_notify_service_dead(SOCKET(u), failed_permanent); - - return; -} - static void service_set_state(Service *s, ServiceState state) { ServiceState old_state; const UnitActiveState *table; @@ -1558,19 +1540,6 @@ static void service_set_state(Service *s, ServiceState state) { s->control_command_id = _SERVICE_EXEC_COMMAND_INVALID; } - if (state == SERVICE_FAILED) - service_notify_sockets_dead(s, s->result == SERVICE_FAILURE_START_LIMIT); - - if (state == SERVICE_DEAD || - state == SERVICE_STOP || - state == SERVICE_STOP_SIGTERM || - state == SERVICE_STOP_SIGKILL || - state == SERVICE_STOP_POST || - state == SERVICE_FINAL_SIGTERM || - state == SERVICE_FINAL_SIGKILL || - state == SERVICE_AUTO_RESTART) - service_notify_sockets_dead(s, false); - if (state != SERVICE_START_PRE && state != SERVICE_START && state != SERVICE_START_POST && diff --git a/src/core/socket.c b/src/core/socket.c index cf88bae9da..2130e48686 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -2277,7 +2277,7 @@ int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds) { return 0; } -void socket_notify_service_dead(Socket *s, bool failed_permanent) { +static void socket_notify_service_dead(Socket *s, bool failed_permanent) { assert(s); /* The service is dead. Dang! @@ -2322,6 +2322,41 @@ static void socket_reset_failed(Unit *u) { s->result = SOCKET_SUCCESS; } +static void socket_trigger_notify(Unit *u, Unit *other) { + Socket *s = SOCKET(u); + Service *se = SERVICE(other); + + assert(u); + assert(other); + + /* Don't propagate state changes from the service if we are + already down or accepting connections */ + if ((s->state != SOCKET_RUNNING && + s->state != SOCKET_LISTENING) || + s->accept) + return; + + if (other->load_state != UNIT_LOADED || + other->type != UNIT_SERVICE) + return; + + if (se->state == SERVICE_FAILED) + socket_notify_service_dead(s, se->result == SERVICE_FAILURE_START_LIMIT); + + if (se->state == SERVICE_DEAD || + se->state == SERVICE_STOP || + se->state == SERVICE_STOP_SIGTERM || + se->state == SERVICE_STOP_SIGKILL || + se->state == SERVICE_STOP_POST || + se->state == SERVICE_FINAL_SIGTERM || + se->state == SERVICE_FINAL_SIGKILL || + se->state == SERVICE_AUTO_RESTART) + socket_notify_service_dead(s, false); + + if (se->state == SERVICE_RUNNING) + socket_set_state(s, SOCKET_RUNNING); +} + static int socket_kill(Unit *u, KillWho who, int signo, DBusError *error) { return unit_kill_common(u, who, signo, -1, SOCKET(u)->control_pid, error); } @@ -2402,6 +2437,8 @@ const UnitVTable socket_vtable = { .sigchld_event = socket_sigchld_event, .timer_event = socket_timer_event, + .trigger_notify = socket_trigger_notify, + .reset_failed = socket_reset_failed, .bus_interface = "org.freedesktop.systemd1.Socket", diff --git a/src/core/socket.h b/src/core/socket.h index 8f9dfdbfb0..57333226f5 100644 --- a/src/core/socket.h +++ b/src/core/socket.h @@ -156,9 +156,6 @@ struct Socket { /* Called from the service code when collecting fds */ int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds); -/* Called from the service when it shut down */ -void socket_notify_service_dead(Socket *s, bool failed_permanent); - /* Called from the mount code figure out if a mount is a dependency of * any of the sockets of this socket */ int socket_add_one_mount_link(Socket *s, Mount *m); -- cgit v1.2.1 From 982e44dbc3e70c97e83464a30354b80973d52b41 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 12 Sep 2013 18:52:41 +0200 Subject: update TODO --- TODO | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/TODO b/TODO index 0946ffaefb..8701a936e5 100644 --- a/TODO +++ b/TODO @@ -58,6 +58,10 @@ CGroup Rework Completion: Features: +* When a Type=forking service fails and needed another service that + service is not cleaned up again when it has StopWhenUnneeded=yes + http://lists.freedesktop.org/archives/systemd-devel/2013-July/012141.html + * backlight: properly handle multiple backlight devices for the same hardware: at shutdown we should only save the backlight setting for the "best" way to access the backlight. Strategy should be: at -- cgit v1.2.1 From 79640424059328268b9fb6c5fa8eb777b27a177e Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Thu, 12 Sep 2013 21:12:49 +0200 Subject: man: wording and grammar updates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a recurring submission and includes corrections to various issue spotted. I guess I can just skip over reporting ubiquitous comma placement fixes… Highligts in this particular commit: - the "unsigned" type qualifier is completed to form a full type "unsigned int" - alphabetic -> lexicographic (that way we automatically define how numbers get sorted) --- man/binfmt.d.xml | 4 +-- man/localectl.xml | 2 +- man/machine-info.xml | 8 ++--- man/modules-load.d.xml | 2 +- man/os-release.xml | 24 ++++++------- man/runlevel.xml | 2 +- man/sd-daemon.xml | 2 +- man/sd_booted.xml | 2 +- man/sd_is_fifo.xml | 2 +- man/sd_journal_add_match.xml | 12 +++---- man/sd_journal_get_catalog.xml | 6 ++-- man/sd_journal_get_data.xml | 4 +-- man/sd_journal_get_fd.xml | 4 +-- man/sd_journal_get_usage.xml | 2 +- man/sd_journal_open.xml | 2 +- man/sd_journal_print.xml | 4 +-- man/sd_journal_seek_head.xml | 12 +++---- man/sd_listen_fds.xml | 18 +++++----- man/sd_login_monitor_new.xml | 4 +-- man/sd_notify.xml | 8 ++--- man/sd_pid_get_session.xml | 4 +-- man/sd_readahead.xml | 2 +- man/sd_seat_get_active.xml | 6 ++-- man/sd_session_is_active.xml | 6 ++-- man/sd_uid_get_state.xml | 6 ++-- man/sysctl.d.xml | 4 +-- man/systemctl.xml | 16 ++++----- man/systemd-activate.xml | 4 +-- man/systemd-analyze.xml | 4 +-- man/systemd-ask-password.xml | 4 +-- man/systemd-cat.xml | 8 ++--- man/systemd-cgls.xml | 8 ++--- man/systemd-cgtop.xml | 6 ++-- man/systemd-cryptsetup-generator.xml | 4 +-- man/systemd-delta.xml | 2 +- man/systemd-detect-virt.xml | 6 ++-- man/systemd-fsck@.service.xml | 2 +- man/systemd-fstab-generator.xml | 2 +- man/systemd-journald.service.xml | 2 +- man/systemd-machine-id-setup.xml | 4 +-- man/systemd-notify.xml | 6 ++-- man/systemd-nspawn.xml | 8 ++--- man/systemd-suspend.service.xml | 2 +- man/systemd-system.conf.xml | 8 ++--- man/systemd-tmpfiles.xml | 6 ++-- man/systemd.automount.xml | 10 +++--- man/systemd.device.xml | 4 +-- man/systemd.exec.xml | 70 ++++++++++++++++++------------------ man/systemd.kill.xml | 6 ++-- man/systemd.mount.xml | 6 ++-- man/systemd.path.xml | 8 ++--- man/systemd.preset.xml | 6 ++-- man/systemd.service.xml | 62 ++++++++++++++++---------------- man/systemd.socket.xml | 16 ++++----- man/systemd.special.xml | 4 +-- man/systemd.swap.xml | 4 +-- man/systemd.time.xml | 4 +-- man/systemd.timer.xml | 2 +- man/systemd.unit.xml | 64 ++++++++++++++++----------------- man/systemd.xml | 18 +++++----- man/timedatectl.xml | 16 ++++----- man/tmpfiles.d.xml | 24 ++++++------- 62 files changed, 289 insertions(+), 289 deletions(-) diff --git a/man/binfmt.d.xml b/man/binfmt.d.xml index 165a8a97b1..94f97e0ed4 100644 --- a/man/binfmt.d.xml +++ b/man/binfmt.d.xml @@ -88,10 +88,10 @@ administrator, who may use this logic to override the configuration files installed from vendor packages. All files are sorted by their filename in - alphabetical order, regardless in which of the + lexicographic order, regardless in which of the directories they reside. If multiple files specify the same binary type name, the entry in the file with - the alphabetically latest name will be applied. + the lexicographically latest name will be applied. If the administrator wants to disable a configuration file supplied by the vendor, the diff --git a/man/localectl.xml b/man/localectl.xml index a3e07f6508..ad4f3d41f0 100644 --- a/man/localectl.xml +++ b/man/localectl.xml @@ -136,7 +136,7 @@ If set-keymap or set-x11-keymap is - invoked and this option is passed then + invoked and this option is passed, then the keymap will not be converted from the console to X11, or X11 to console, respectively. diff --git a/man/machine-info.xml b/man/machine-info.xml index 7f396aafde..ddf8f8b3d0 100644 --- a/man/machine-info.xml +++ b/man/machine-info.xml @@ -94,13 +94,13 @@ PRETTY_HOSTNAME= A pretty - human-readable UTF8 machine identifier + human-readable UTF-8 machine identifier string. This should contain a name like Lennart's Laptop which is useful to present to the user and does not suffer by the syntax limitations of - internet domain names. If possible the + internet domain names. If possible, the internet hostname as configured in /etc/hostname should be kept similar to this @@ -109,7 +109,7 @@ an Internet hostname of lennarts-computer might be a good choice. If this - parameter is not set an application + parameter is not set, an application should fall back to the Internet host name for presentation purposes. @@ -122,7 +122,7 @@ this machine according to the XDG Icon Naming Specification. If - this parameter is not set an + this parameter is not set, an application should fall back to computer or a similar icon name. diff --git a/man/modules-load.d.xml b/man/modules-load.d.xml index 0d104c563d..33c466f926 100644 --- a/man/modules-load.d.xml +++ b/man/modules-load.d.xml @@ -90,7 +90,7 @@ packages. If the administrator wants to disable a - configuration file supplied by the vendor the + configuration file supplied by the vendor, the recommended way is to place a symlink to /dev/null in /etc/modules-load.d/ bearing the diff --git a/man/os-release.xml b/man/os-release.xml index 045dd08f1f..c1dd62f715 100644 --- a/man/os-release.xml +++ b/man/os-release.xml @@ -62,7 +62,7 @@ list of environment-like shell-compatible variable assignments. It is possible to source the configuration from shell scripts, however, beyond mere - variable assignments no shell features are supported + variable assignments, no shell features are supported (this means variable expansion is explicitly not supported), allowing applications to read the file without implementing a shell compatible execution @@ -72,7 +72,7 @@ a-z, 0-9. All strings should be in UTF-8 format, and non-printable characters should not be used. If double or single quotes or backslashes are to be used within - variable assignments they should be escaped with + variable assignments, they should be escaped with backslashes, following shell style. It is not supported to concatenate multiple individually quoted strings. Lines beginning with "#" shall be ignored as @@ -110,7 +110,7 @@ A string identifying the operating system, without a version component, and suitable for - presentation to the user. If not set + presentation to the user. If not set, defaults to NAME=Linux. Example: NAME=Fedora or @@ -143,7 +143,7 @@ excluding any version information and suitable for processing by scripts or usage in generated filenames. If not - set defaults to + set, defaults to ID=linux. Example: ID=fedora or ID=debian. @@ -155,7 +155,7 @@ A space-separated list of operating system identifiers in the same syntax as the - ID= setting. Should + ID= setting. It should list identifiers of operating systems that are closely related to the local operating system in regards to @@ -165,8 +165,8 @@ OS is a derivative from. An OS should generally only list other OS identifiers it itself is a derivative - from, and not any OSes that - are derived from it, but symmetric + of, and not any OSes that + are derived from it, though symmetric relationships are possible. Build scripts and similar should check this variable if they need to identify the @@ -179,11 +179,11 @@ closest. This field is optional. Example: for an operating system with - ID=centos an + ID=centos, an assignment of ID_LIKE="rhel fedora" would be appropriate. For an operating system - with ID=ubuntu an + with ID=ubuntu, an assignment of ID_LIKE=debian is appropriate. @@ -213,7 +213,7 @@ presentation to the user. May or may not contain a release code name or OS version of some kind, as suitable. If - not set defaults to + not set, defaults to PRETTY_NAME="Linux". Example: PRETTY_NAME="Fedora 17 (Beefy Miracle)". @@ -290,7 +290,7 @@ tel:. Only one URL shall be listed in each setting. If multiple resources need to be - referenced it is recommended to + referenced, it is recommended to provide an online landing page linking all available resources. Examples: HOME_URL="https://fedoraproject.org/" @@ -332,7 +332,7 @@ Note that operating system vendors may choose not to provide version information, for example to - accommodate for rolling releases. In this case VERSION + accommodate for rolling releases. In this case, VERSION and VERSION_ID may be unset. Applications should not rely on these fields to be set. diff --git a/man/runlevel.xml b/man/runlevel.xml index 6d9fe85726..5efb340df5 100644 --- a/man/runlevel.xml +++ b/man/runlevel.xml @@ -111,7 +111,7 @@ $PREVLEVEL If - $PREVLEVEL is set + $PREVLEVEL is set, runlevel will print this value as previous runlevel and ignore utmp. diff --git a/man/sd-daemon.xml b/man/sd-daemon.xml index 136415f0a1..6e804e1a6c 100644 --- a/man/sd-daemon.xml +++ b/man/sd-daemon.xml @@ -99,7 +99,7 @@ conjunction with STDERR-based logging as implemented by systemd. If a systemd service definition file is configured with StandardError=syslog - or StandardError=kmsg these + or StandardError=kmsg, these prefixes can be used to encode a log level in lines printed. This is similar to the kernel printk()-style logging. See diff --git a/man/sd_booted.xml b/man/sd_booted.xml index 84af8fbd95..64c0cd9d3d 100644 --- a/man/sd_booted.xml +++ b/man/sd_booted.xml @@ -111,7 +111,7 @@ If the reference implementation is used as drop-in files and -DDISABLE_SYSTEMD is set during - compilation this function will always return 0 and + compilation, this function will always return 0 and otherwise become a NOP. diff --git a/man/sd_is_fifo.xml b/man/sd_is_fifo.xml index a790c370e1..2bc860c373 100644 --- a/man/sd_is_fifo.xml +++ b/man/sd_is_fifo.xml @@ -160,7 +160,7 @@ On failure, these calls return a negative errno-style error code. If the file descriptor is of - the specified type and bound to the specified address + the specified type and bound to the specified address, a positive return value is returned, otherwise zero. diff --git a/man/sd_journal_add_match.xml b/man/sd_journal_add_match.xml index d02285f205..b6c7b06f2e 100644 --- a/man/sd_journal_add_match.xml +++ b/man/sd_journal_add_match.xml @@ -94,11 +94,11 @@ only of 0-9, A-Z and the underscore. It may not begin with two underscores or be the empty string. The value part may be any value, including binary. If a match is - applied only entries with this field set will be + applied, only entries with this field set will be iterated. Multiple matches may be active at the same - time: if they apply to different fields only entries - with both fields set like this will be iterated, if - they apply to the same fields only entries where the + time: If they apply to different fields, only entries + with both fields set like this will be iterated. If + they apply to the same fields, only entries where the field takes one of the specified values will be iterated. Well known fields are documented in systemd.journal-fields7. Whenever @@ -110,7 +110,7 @@ sd_journal_add_disjunction() may be used to insert a disjunction (i.e. logical OR) - in the match list. If this call is invoked all + in the match list. If this call is invoked, all previously added matches since the last invocation of sd_journal_add_disjunction() or sd_journal_add_conjunction() are @@ -123,7 +123,7 @@ sd_journal_add_conjunction() may be used to insert a conjunction (i.e. logical AND) - in the match list. If this call is invoked all + in the match list. If this call is invoked, all previously added matches since the last invocation of sd_journal_add_conjunction() are combined in an AND with all matches added afterwards, diff --git a/man/sd_journal_get_catalog.xml b/man/sd_journal_get_catalog.xml index 53ca3083b1..4a7e0a1f8c 100644 --- a/man/sd_journal_get_catalog.xml +++ b/man/sd_journal_get_catalog.xml @@ -80,8 +80,8 @@ field names in the catalog entry text enclosed in "@" will be replaced by the respective field values of the current entry. If a field name referenced in the - message catalog entry does not exist it the current - journal entry the "@" will be removed but the field + message catalog entry does not exist, in the current + journal entry, the "@" will be removed, but the field name otherwise left untouched. sd_journal_get_catalog_for_message_id() @@ -104,7 +104,7 @@ and sd_journal_get_catalog_for_message_id() return 0 on success or a negative errno-style error - code. If no matching message catalog entry is found + code. If no matching message catalog entry is found, -ENOENT is returned. On successful return, ret diff --git a/man/sd_journal_get_data.xml b/man/sd_journal_get_data.xml index 460b709dbf..0e1111e05d 100644 --- a/man/sd_journal_get_data.xml +++ b/man/sd_journal_get_data.xml @@ -179,9 +179,9 @@ sd_journal_get_data() returns 0 on success or a negative errno-style error code. If the current entry does not include the - specified field -ENOENT is returned. If + specified field, -ENOENT is returned. If sd_journal_next3 - has not been called at least once -EADDRNOTAVAIL is + has not been called at least once, -EADDRNOTAVAIL is returned. sd_journal_enumerate_data() returns a positive integer if the next field has been read, 0 when no more fields are known, or a negative diff --git a/man/sd_journal_get_fd.xml b/man/sd_journal_get_fd.xml index c4387b0856..764f716a17 100644 --- a/man/sd_journal_get_fd.xml +++ b/man/sd_journal_get_fd.xml @@ -137,8 +137,8 @@ timeout_usec. See clock_gettime2 for details about - CLOCK_MONOTONIC. If there's no - timeout to wait for this will fill in + CLOCK_MONOTONIC. If there is no + timeout to wait for, this will fill in (uint64_t) -1 instead. Note that poll() takes a relative timeout in milliseconds rather than an absolute timeout in diff --git a/man/sd_journal_get_usage.xml b/man/sd_journal_get_usage.xml index 50953f5065..180d8b2ffd 100644 --- a/man/sd_journal_get_usage.xml +++ b/man/sd_journal_get_usage.xml @@ -67,7 +67,7 @@ determines the total disk space currently used by journal files (in bytes). If SD_JOURNAL_LOCAL_ONLY was passed - when opening the journal this value will only reflect + when opening the journal, this value will only reflect the size of journal files of the local host, otherwise of all hosts. diff --git a/man/sd_journal_open.xml b/man/sd_journal_open.xml index 28d164add7..bb3703d015 100644 --- a/man/sd_journal_open.xml +++ b/man/sd_journal_open.xml @@ -146,7 +146,7 @@ When opening the journal only journal files accessible to the calling user will be opened. If - journal files are not accessible to the caller this + journal files are not accessible to the caller, this will be silently ignored. See diff --git a/man/sd_journal_print.xml b/man/sd_journal_print.xml index 1437342a55..e61a648703 100644 --- a/man/sd_journal_print.xml +++ b/man/sd_journal_print.xml @@ -166,7 +166,7 @@ readable representation of the current error code stored in errno3. If - the message string is passed as NULL or empty string + the message string is passed as NULL or empty string, only the error string representation will be written, prefixed with nothing. An additional journal field ERRNO= is included in the entry containing the numeric @@ -189,7 +189,7 @@ sd_journal_send("MESSAGE=Hello World, this is PID %lu!", (unsigned long) getpid( Note that these calls implicitly add fields for the source file, function name and code line where invoked. This is implemented with macros. If this is - not desired it can be turned off by defining + not desired, it can be turned off by defining SD_JOURNAL_SUPPRESS_LOCATION before including sd-journal.h. diff --git a/man/sd_journal_seek_head.xml b/man/sd_journal_seek_head.xml index c4e64096e1..03de30a383 100644 --- a/man/sd_journal_seek_head.xml +++ b/man/sd_journal_seek_head.xml @@ -111,30 +111,30 @@ (wallclock) timestamp, i.e. CLOCK_REALTIME. Note that the realtime clock is not necessarily monotonic. If a - realtime timestamp is ambiguous it is not defined + realtime timestamp is ambiguous, it is not defined which position is sought to. sd_journal_seek_cursor() seeks to the entry located at the specified cursor - string. For details on cursors see + string. For details on cursors, see sd_journal_get_cursor3. If no entry matching the specified cursor is found the call will seek to the next closest entry (in terms of time) instead. To verify whether the newly selected - entry actually matches the cursor use + entry actually matches the cursor, use sd_journal_test_cursor3. Note that these calls do not actually make any entry the new current entry, this needs to be done in a separate step with a subsequent sd_journal_next3 - invocation (or a similar call). Only then entry data + invocation (or a similar call). Only then, entry data may be retrieved via sd_journal_get_data3. If no entry exists that matches exactly the specified - seek address the next closest is sought to. If + seek address, the next closest is sought to. If sd_journal_next3 - is used the closest following entry will be sought to, + is used, the closest following entry will be sought to, if sd_journal_previous3 is used the closest preceding entry is sought diff --git a/man/sd_listen_fds.xml b/man/sd_listen_fds.xml index c9b3997015..240300dcb0 100644 --- a/man/sd_listen_fds.xml +++ b/man/sd_listen_fds.xml @@ -70,7 +70,7 @@ activation logic. If the unset_environment - parameter is non-zero + parameter is non-zero, sd_listen_fds() will unset the $LISTEN_FDS/$LISTEN_PID environment variables before returning (regardless @@ -83,16 +83,16 @@ If a daemon receives more than one file descriptor, they will be passed in the same order as configured in the systemd socket definition - file. Nonetheless it is recommended to verify the + file. Nonetheless, it is recommended to verify the correct socket types before using them. To simplify - this checking the functions + this checking, the functions sd_is_fifo3, sd_is_socket3, sd_is_socket_inet3, sd_is_socket_unix3 - are provided. In order to maximize flexibility it is + are provided. In order to maximize flexibility, it is recommended to make these checks as loose as possible - without allowing incorrect setups. i.e. often the + without allowing incorrect setups. i.e. often, the actual port number a socket is bound to matters little for the service to work, hence it should not be verified. On the other hand, whether a socket is a @@ -112,7 +112,7 @@ $LISTEN_FDS/$LISTEN_PID was not set or was not correctly set for this daemon and hence no file descriptors were received, 0 is - returned. Otherwise the number of file descriptors + returned. Otherwise, the number of file descriptors passed is returned. The application may find them starting with file descriptor SD_LISTEN_FDS_START, i.e. file descriptor 3. @@ -132,11 +132,11 @@ Internally, this function checks whether the $LISTEN_PID environment variable equals the daemon PID. If not, it returns - immediately. Otherwise it parses the number passed in + immediately. Otherwise, it parses the number passed in the $LISTEN_FDS environment variable, then sets the FD_CLOEXEC flag for the parsed number of file descriptors starting from - SD_LISTEN_FDS_START. Finally it returns the parsed + SD_LISTEN_FDS_START. Finally, it returns the parsed number. For details about the algorithm check the @@ -160,7 +160,7 @@ If the reference implementation is used as drop-in files and -DDISABLE_SYSTEMD is set during - compilation this function will always return 0 and + compilation, this function will always return 0 and otherwise become a NOP. diff --git a/man/sd_login_monitor_new.xml b/man/sd_login_monitor_new.xml index e93f93f9ce..909a3d9bfd 100644 --- a/man/sd_login_monitor_new.xml +++ b/man/sd_login_monitor_new.xml @@ -129,7 +129,7 @@ object. Whenever an event causes the monitor to wake up the event loop via the file descriptor this function needs to be called to reset the wake-up - state. If this call is not invoked the file descriptor + state. If this call is not invoked, the file descriptor will immediately wake up the event loop again. sd_login_monitor_get_fd() @@ -167,7 +167,7 @@ timeout_usec. See clock_gettime2 for details about - CLOCK_MONOTONIC. If there's no + CLOCK_MONOTONIC. If there is no timeout to wait for this will fill in (uint64_t) -1 instead. Note that poll() takes a relative timeout diff --git a/man/sd_notify.xml b/man/sd_notify.xml index fc0f2f6927..55965ffce4 100644 --- a/man/sd_notify.xml +++ b/man/sd_notify.xml @@ -77,7 +77,7 @@ notification. If the unset_environment - parameter is non-zero sd_notify() + parameter is non-zero, sd_notify() will unset the $NOTIFY_SOCKET environment variable before returning (regardless whether the function call itself succeeded or @@ -197,7 +197,7 @@ errno-style error code. If $NOTIFY_SOCKET was not set and hence no status data could be sent, 0 is returned. If - the status was sent these functions return with a + the status was sent, these functions return with a positive return value. In order to support both, init systems that implement this scheme and those which do not, it is generally recommended to ignore the return @@ -220,7 +220,7 @@ AF_UNIX socket referenced in the $NOTIFY_SOCKET environment variable. If the first character of - $NOTIFY_SOCKET is @ the string is + $NOTIFY_SOCKET is @, the string is understood as Linux abstract namespace socket. The datagram is accompanied by the process credentials of the sending daemon, using SCM_CREDENTIALS. @@ -246,7 +246,7 @@ If the reference implementation is used as drop-in files and -DDISABLE_SYSTEMD is set during - compilation these functions will always return 0 and + compilation, these functions will always return 0 and otherwise become a NOP. diff --git a/man/sd_pid_get_session.xml b/man/sd_pid_get_session.xml index ecd22f7bfe..e5c77090dd 100644 --- a/man/sd_pid_get_session.xml +++ b/man/sd_pid_get_session.xml @@ -165,14 +165,14 @@ call after use. If the pid parameter of any - of these functions is passed as 0 the operation is + of these functions is passed as 0, the operation is executed for the calling process. Return Value - On success these calls return 0 or a positive + On success, these calls return 0 or a positive integer. On failure, these calls return a negative errno-style error code. diff --git a/man/sd_readahead.xml b/man/sd_readahead.xml index c26d5c63e3..bb01bcfd89 100644 --- a/man/sd_readahead.xml +++ b/man/sd_readahead.xml @@ -142,7 +142,7 @@ details about the reference implementation see sd-readahead3 - If -DDISABLE_SYSTEMD is set during compilation + If -DDISABLE_SYSTEMD is set during compilation, this function will always return 0 and otherwise become a NOP. diff --git a/man/sd_seat_get_active.xml b/man/sd_seat_get_active.xml index 3c26fb1e29..1610d3efe8 100644 --- a/man/sd_seat_get_active.xml +++ b/man/sd_seat_get_active.xml @@ -65,7 +65,7 @@ const char* seat char*** sessions uid_t** uid - unsigned* n_uids + unsigned int* n_uids @@ -133,7 +133,7 @@ If the seat parameter of any of these functions is passed as - NULL the operation is executed + NULL, the operation is executed for the seat of the session of the calling process, if there is any. @@ -146,7 +146,7 @@ returns 0 or a positive integer. On success sd_seat_get_sessions() returns the number of entries in the session identifier - array. If the test succeeds + array. If the test succeeds, sd_seat_can_multi_session, sd_seat_can_tty and sd_seat_can_graphical return a diff --git a/man/sd_session_is_active.xml b/man/sd_session_is_active.xml index 9362fbcc55..293ce71642 100644 --- a/man/sd_session_is_active.xml +++ b/man/sd_session_is_active.xml @@ -116,7 +116,7 @@ int sd_session_get_vt const char* session - unsigned* vt + unsigned int* vt @@ -217,7 +217,7 @@ If the session parameter of any of these functions is passed as - NULL the operation is executed + NULL, the operation is executed for the session the calling process is a member of, if there is any. @@ -225,7 +225,7 @@ Return Value - If the test succeeds + If the test succeeds, sd_session_is_active() returns a positive integer, if it fails 0. On success sd_session_get_state(), diff --git a/man/sd_uid_get_state.xml b/man/sd_uid_get_state.xml index ba614f932b..d4d23f4f1d 100644 --- a/man/sd_uid_get_state.xml +++ b/man/sd_uid_get_state.xml @@ -111,7 +111,7 @@ or active on a specific seat. Accepts a Unix user identifier and a seat identifier string as parameters. The require_active - parameter is a boolean value. If non-zero (true) this + parameter is a boolean value. If non-zero (true), this function will test if the user is active (i.e. has a session that is in the foreground and accepting user input) on the specified seat, otherwise (false) only @@ -133,7 +133,7 @@ free3 call after use, including all the strings referenced. If the string array parameter is passed as - NULL the array will not be filled in, but the return + NULL, the array will not be filled in, but the return code still indicates the number of current sessions. Note that instead of an empty array NULL may be returned and should be considered equivalent to an @@ -154,7 +154,7 @@ On success sd_uid_get_state() returns 0 or a - positive integer. If the test succeeds + positive integer. If the test succeeds, sd_uid_is_on_seat() returns a positive integer, if it fails 0. sd_uid_get_sessions() and diff --git a/man/sysctl.d.xml b/man/sysctl.d.xml index 155427cecf..854864cffc 100644 --- a/man/sysctl.d.xml +++ b/man/sysctl.d.xml @@ -89,10 +89,10 @@ administrator, who may use this logic to override the configuration files installed by vendor packages. All configuration files are sorted by their filename in - alphabetical order, regardless in which of the + lexicographic order, regardless in which of the directories they reside. If multiple files specify the same variable name, the entry in the file with the - alphabetically latest name will be applied. It is + lexicographically latest name will be applied. It is recommended to prefix all filenames with a two-digit number and a dash, to simplify the ordering of the files. diff --git a/man/systemctl.xml b/man/systemctl.xml index 1642a47273..b043581be0 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -566,7 +566,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service their configuration. Note that this will reload the service-specific configuration, not the unit configuration file of systemd. If you want systemd to reload the - configuration file of a unit use the + configuration file of a unit, use the daemon-reload command. In other words: for the example case of Apache, this will reload Apache's httpd.conf in the web server, not the @@ -692,12 +692,12 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service Show properties of one or more units, jobs, or the - manager itself. If no argument is specified properties of - the manager will be shown. If a unit name is specified + manager itself. If no argument is specified, properties of + the manager will be shown. If a unit name is specified, properties of the unit is shown, and if a job id is - specified properties of the job is shown. By default, empty + specified, properties of the job is shown. By default, empty properties are suppressed. Use to - show those too. To select specific properties to show use + show those too. To select specific properties to show, use . This command is intended to be used whenever computer-parsable output is required. Use status if you are looking for formatted @@ -1075,7 +1075,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service Reload systemd manager configuration. This will reload all unit files and recreate the entire dependency - tree. While the daemon is reloaded, all sockets systemd + tree. While the daemon is being reloaded, all sockets systemd listens on on behalf of user configuration will stay accessible. This command should not be confused with the load or @@ -1089,9 +1089,9 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service Reexecute the systemd manager. This will serialize the manager state, reexecute the process and deserialize the state again. This command is of little use except for - debugging and package upgrades. Sometimes it might be + debugging and package upgrades. Sometimes, it might be helpful as a heavy-weight daemon-reload. - While the daemon is reexecuted, all sockets systemd listening + While the daemon is being reexecuted, all sockets systemd listening on behalf of user configuration will stay accessible. diff --git a/man/systemd-activate.xml b/man/systemd-activate.xml index b62cf44ec4..d48774d9d6 100644 --- a/man/systemd-activate.xml +++ b/man/systemd-activate.xml @@ -123,8 +123,8 @@ along with systemd; If not, see . Add this variable to the environment of the launched process. If VAR is - followed by = assume that it is a - variable–value pair. Otherwise obtain the value from the + followed by =, assume that it is a + variable–value pair. Otherwise, obtain the value from the environment of systemd-activate itself. diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml index 60377093d0..aefbfc8af7 100644 --- a/man/systemd-analyze.xml +++ b/man/systemd-analyze.xml @@ -206,12 +206,12 @@ dot command (see above), selects which dependencies are shown in the dependency graph. If - is passed + is passed, only dependencies of type After= or Before= are shown. If - is passed only dependencies of type + is passed, only dependencies of type Requires=, RequiresOverridable=, Requisite=, diff --git a/man/systemd-ask-password.xml b/man/systemd-ask-password.xml index 563f9d5d61..8af328dcfa 100644 --- a/man/systemd-ask-password.xml +++ b/man/systemd-ask-password.xml @@ -90,7 +90,7 @@ url="http://www.freedesktop.org/wiki/Software/systemd/PasswordAgents">systemd Password Agent Specification. - If a password is queried on a TTY the user may + If a password is queried on a TTY, the user may press TAB to hide the asterisks normally shown for each character typed. Pressing Backspace as first key achieves the same effect. @@ -145,7 +145,7 @@ - If passed accept + If passed, accept cached passwords, i.e. passwords previously typed in. diff --git a/man/systemd-cat.xml b/man/systemd-cat.xml index 876ebfa3cc..ffb1dfd50b 100644 --- a/man/systemd-cat.xml +++ b/man/systemd-cat.xml @@ -65,11 +65,11 @@ pass the output the previous pipeline element generates to the journal. - If no parameter is passed + If no parameter is passed, systemd-cat will write everything it reads from standard input (STDIN) to the journal. - If parameters are passed they are executed as + If parameters are passed, they are executed as command line with standard output (STDOUT) and standard error output (STDERR) connected to the journal, so that all it writes is stored in the journal. @@ -102,7 +102,7 @@ Specify a short string that is used to identify the logging - tool. If not specified no identifying + tool. If not specified, no identification string is written to the journal. @@ -141,7 +141,7 @@ Controls whether lines read are parsed for syslog priority level prefixes. If enabled (the - default) a line prefixed with a + default), a line prefixed with a priority prefix such as <5> is logged at priority 5 diff --git a/man/systemd-cgls.xml b/man/systemd-cgls.xml index 2877f22126..fcaf89413e 100644 --- a/man/systemd-cgls.xml +++ b/man/systemd-cgls.xml @@ -60,19 +60,19 @@ systemd-cgls recursively shows the contents of the selected Linux control group - hierarchy in a tree. If arguments are specified shows + hierarchy in a tree. If arguments are specified, shows all member processes of the specified control groups plus all their subgroups and their members. The control groups may either be specified by their full file paths or are assumed in the systemd control group hierarchy. If no argument is specified and the current working directory is beneath the control group mount - point /sys/fs/cgroup shows the contents + point /sys/fs/cgroup, shows the contents of the control group the working directory refers - to. Otherwise the full systemd control group hierarchy + to. Otherwise, the full systemd control group hierarchy is shown. - By default empty control groups are not + By default, empty control groups are not shown. diff --git a/man/systemd-cgtop.xml b/man/systemd-cgtop.xml index e765172234..0e9e5e611a 100644 --- a/man/systemd-cgtop.xml +++ b/man/systemd-cgtop.xml @@ -79,7 +79,7 @@ group in the cpuacct hierarchy, but not in memory nor blkio. If resource monitoring for - these resources is required it is recommended to add + these resources is required, it is recommended to add blkio and memory to the DefaultControllers= setting in /etc/systemd/system.conf (see @@ -197,8 +197,8 @@ tree traversal depth. Specifies how deep systemd-cgtop shall traverse the control group - hierarchies. If 0 is specified only - the root group is monitored, for 1 + hierarchies. If 0 is specified, only + the root group is monitored. For 1, only the first level of control groups is monitored, and so on. Defaults to 3. diff --git a/man/systemd-cryptsetup-generator.xml b/man/systemd-cryptsetup-generator.xml index 7950032941..215ac2d125 100644 --- a/man/systemd-cryptsetup-generator.xml +++ b/man/systemd-cryptsetup-generator.xml @@ -80,7 +80,7 @@ Takes a boolean argument. Defaults to yes. If - no disables the + no, disables the generator entirely. rd.luks= is honored only by initial RAM disk @@ -97,7 +97,7 @@ Takes a boolean argument. Defaults to yes. If - no causes the + no, causes the generator to ignore any devices configured in /etc/crypttab diff --git a/man/systemd-delta.xml b/man/systemd-delta.xml index 0c7a54a09b..413ebd8de8 100644 --- a/man/systemd-delta.xml +++ b/man/systemd-delta.xml @@ -163,7 +163,7 @@ When showing modified files, when a file is overridden show a diff as well. This option takes a - boolean argument. If omitted it defaults + boolean argument. If omitted, it defaults to . diff --git a/man/systemd-detect-virt.xml b/man/systemd-detect-virt.xml index f21493df64..69785ceffa 100644 --- a/man/systemd-detect-virt.xml +++ b/man/systemd-detect-virt.xml @@ -75,10 +75,10 @@ lxc-libvirt, systemd-nspawn. - If multiple virtualization solutions are used + If multiple virtualization solutions are used, only the "innermost" is detected and identified. That means if both VM virtualization and container - virtualization are used in conjunction only the latter + virtualization are used in conjunction, only the latter will be identified (unless is passed). @@ -138,7 +138,7 @@ Exit status - If a virtualization technology is detected 0 is + If a virtualization technology is detected, 0 is returned, a non-zero code otherwise. diff --git a/man/systemd-fsck@.service.xml b/man/systemd-fsck@.service.xml index 4d6464c2b8..e934352f19 100644 --- a/man/systemd-fsck@.service.xml +++ b/man/systemd-fsck@.service.xml @@ -66,7 +66,7 @@ systemd-fsck will forward file system checking progress to the - console. If a file system check fails emergency mode + console. If a file system check fails, emergency mode is activated, by isolating to emergency.target. diff --git a/man/systemd-fstab-generator.xml b/man/systemd-fstab-generator.xml index 4bd25bfa8f..9ca16c7ea1 100644 --- a/man/systemd-fstab-generator.xml +++ b/man/systemd-fstab-generator.xml @@ -90,7 +90,7 @@ Takes a boolean argument. Defaults to yes. If - no causes the + no, causes the generator to ignore any mounts or swaps configured in /etc/fstab. rd.fstab= diff --git a/man/systemd-journald.service.xml b/man/systemd-journald.service.xml index 5634dd0a21..2f877f565c 100644 --- a/man/systemd-journald.service.xml +++ b/man/systemd-journald.service.xml @@ -77,7 +77,7 @@ necessary. All objects stored in the journal can be up to 2^64-1 bytes in size. - By default the journal stores log data in + By default, the journal stores log data in /run/log/journal/. Since /run/ is volatile, log data is lost at reboot. To make the data persistent, it diff --git a/man/systemd-machine-id-setup.xml b/man/systemd-machine-id-setup.xml index 25fb63af2d..fef76bcfc7 100644 --- a/man/systemd-machine-id-setup.xml +++ b/man/systemd-machine-id-setup.xml @@ -69,12 +69,12 @@ initialized. If a valid D-Bus machine ID is already - configured for the system the D-Bus machine ID is + configured for the system, the D-Bus machine ID is copied and used to initialize the machine ID in /etc/machine-id. If run inside a KVM virtual machine and a UUID - is passed via the option this + is passed via the option, this UUID is used to initialize the machine ID instead of a randomly generated one. The caller must ensure that the UUID passed is sufficiently unique and is different diff --git a/man/systemd-notify.xml b/man/systemd-notify.xml index b03492c5c1..a76934649a 100644 --- a/man/systemd-notify.xml +++ b/man/systemd-notify.xml @@ -119,7 +119,7 @@ Inform the init system about the main PID of the daemon. Takes a PID as argument. If - the argument is omitted the PID of the + the argument is omitted, the PID of the process that invoked systemd-notify is used. This is equivalent to @@ -148,10 +148,10 @@ Returns 0 if the system was booted up with systemd, non-zero otherwise. If this option is - passed no message is sent. This option + passed, no message is sent. This option is hence unrelated to the other options. For details about the - semantics of this option see + semantics of this option, see sd_booted3. diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml index 6264e48dbc..7d450f912c 100644 --- a/man/systemd-nspawn.xml +++ b/man/systemd-nspawn.xml @@ -151,7 +151,7 @@ containers. We hence recommend turning it off entirely by booting with audit=0 on the kernel command line, or by turning it off at kernel - build time. If auditing is enabled in the kernel + build time. If auditing is enabled in the kernel, operating systems booted in an nspawn container might refuse log-in attempts. @@ -192,7 +192,7 @@ Directory to use as file system root for the namespace - container. If omitted the current + container. If omitted, the current directory will be used. @@ -233,7 +233,7 @@ host, and is used to initialize the container's hostname (which the container can choose to override, - however). If not specified the last + however). If not specified, the last component of the root directory of the container is used. @@ -308,7 +308,7 @@ Control whether the container's journal shall be made - visible to the host system. If enabled + visible to the host system. If enabled, allows viewing the container's journal files from the host (but not vice versa). Takes one of diff --git a/man/systemd-suspend.service.xml b/man/systemd-suspend.service.xml index 9b08f04939..4abc278191 100644 --- a/man/systemd-suspend.service.xml +++ b/man/systemd-suspend.service.xml @@ -96,7 +96,7 @@ /usr/lib/systemd/system-sleep/ are intended for local use only and should be considered hacks. If applications want to be notified - of system suspend/hibernation and resume there are + of system suspend/hibernation and resume, there are much nicer interfaces available. Note that diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml index a67b158996..c52e59096a 100644 --- a/man/systemd-system.conf.xml +++ b/man/systemd-system.conf.xml @@ -133,7 +133,7 @@ Configures controllers that shall be mounted in a single - hierarchy. By default systemd will + hierarchy. By default, systemd will mount all controllers which are enabled in the kernel in individual hierarchies, with the exception of @@ -154,7 +154,7 @@ necessary to rebuild the initrd if this option is changed, and make sure the new configuration file is included - in it. Otherwise the initrd might + in it. Otherwise, the initrd might mount the controller hierarchies in a different configuration than intended, and the main system cannot remount @@ -175,7 +175,7 @@ d, w). If RuntimeWatchdogSec= - is set to a non-zero value the + is set to a non-zero value, the watchdog hardware (/dev/watchdog) will be programmed to automatically @@ -220,7 +220,7 @@ Capabilities listed will be included in the bounding set, all others are removed. If the list of capabilities - is prefixed with ~ all but the listed + is prefixed with ~, all but the listed capabilities will be included, the effect of the assignment inverted. Note that this option also diff --git a/man/systemd-tmpfiles.xml b/man/systemd-tmpfiles.xml index 403592dd71..281ab3ca25 100644 --- a/man/systemd-tmpfiles.xml +++ b/man/systemd-tmpfiles.xml @@ -94,7 +94,7 @@ - If this option is passed all + If this option is passed, all files and directories marked with f, F, d, D in the configuration files are created. Files and directories marked with z, @@ -105,7 +105,7 @@ If this option is - passed all files and directories with + passed, all files and directories with an age parameter configured will be cleaned up. @@ -113,7 +113,7 @@ If this option is - passed all files and directories marked + passed, all files and directories marked with r, R in the configuration files are removed. diff --git a/man/systemd.automount.xml b/man/systemd.automount.xml index adba75a71a..34105126cd 100644 --- a/man/systemd.automount.xml +++ b/man/systemd.automount.xml @@ -93,7 +93,7 @@ file systems. If an automount point is beneath another mount - point in the file system hierarchy a dependency + point in the file system hierarchy, a dependency between both units is created automatically. @@ -110,7 +110,7 @@ systemd.mount5. If an automount point is configured in both - /etc/fstab and a unit file the + /etc/fstab and a unit file, the configuration in the latter takes precedence. @@ -129,9 +129,9 @@ Where= Takes an absolute path of a directory of the automount - point. If the automount point is not - existing at time that the automount - point is installed it is created. This + point. If the automount point does not + exist at time that the automount + point is installed, it is created. This string must be reflected in the unit filename. (See above.) This option is mandatory. diff --git a/man/systemd.device.xml b/man/systemd.device.xml index e3cf071bcb..96ebe89095 100644 --- a/man/systemd.device.xml +++ b/man/systemd.device.xml @@ -124,11 +124,11 @@ SYSTEMD_READY= - If set to 0 systemd + If set to 0, systemd will consider this device unplugged even if it shows up in the udev tree. If this property is unset or set - to 1 the device will be considered + to 1, the device will be considered plugged the moment it shows up in the udev tree. This property has no influence on the behavior when a diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index ff8b812ef4..5721dc1553 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -110,7 +110,7 @@ Takes an absolute directory path. Sets the working directory for executed processes. If - not set defaults to the root directory + not set, defaults to the root directory when systemd is running as a system instance and the respective user's home directory if run as @@ -125,7 +125,7 @@ directory for executed processes, with the chroot2 - system call. If this is used it must + system call. If this is used, it must be ensured that the process and all its auxiliary files are available in the chroot() @@ -254,7 +254,7 @@ CPUSchedulingResetOnFork= Takes a boolean - argument. If true elevated CPU + argument. If true, elevated CPU scheduling priorities and policies will be reset when the executed processes fork, and can hence not leak @@ -273,7 +273,7 @@ be specified more than once in which case the specificed CPU affinity masks are merged. If the empty string is - assigned the mask is reset, all + assigned, the mask is reset, all assignments prior to this will have no effect. See sched_setaffinity2 @@ -301,15 +301,15 @@ option may be specified more than once in which case all listed variables will be set. If the same variable is - set twice the later setting will + set twice, the later setting will override the earlier setting. If the empty string is assigned to this - option the list of environment + option, the list of environment variables is reset, all prior assignments have no effect. Variable expansion is not performed inside the strings, however, specifier - expansion is possible. $ character has + expansion is possible. The $ character has no special meaning. If you need to assign a value containing spaces to a variable, use double quotes (") @@ -353,7 +353,7 @@ specified more than once in which case all specified files are read. If the empty string is assigned to this - option the list of file to read is + option, the list of file to read is reset, all prior assignments have no effect. @@ -364,7 +364,7 @@ with Environment=. If the same variable is set twice from - these files the files will be read in + these files, the files will be read in the order they are specified and the later setting will override the earlier setting. @@ -380,19 +380,19 @@ , or . If - is selected + is selected, standard input will be connected to /dev/null, i.e. all read attempts by the process will result in immediate EOF. If - is selected + is selected, standard input is connected to a TTY (as configured by TTYPath=, see below) and the executed process becomes the controlling process of the terminal. If the terminal is already - being controlled by another process the + being controlled by another process, the executed process waits until the current controlling process releases the terminal. @@ -414,7 +414,7 @@ file (see systemd.socket5 for details) specifies a single socket - only. If this option is set standard + only. If this option is set, standard input will be connected to the socket the service was activated from, which is primarily useful for compatibility @@ -439,19 +439,19 @@ , or . If set to - the file + , the file descriptor of standard input is duplicated for standard output. If set - to standard + to , standard output will be connected to /dev/null, i.e. everything written to it will be - lost. If set to + lost. If set to , standard output will be connected to a tty (as configured via TTYPath=, see below). If the TTY is used for output - only the executed process will not + only, the executed process will not become the controlling process of the terminal, and will not fail or wait for other processes to release the @@ -538,7 +538,7 @@ If the terminal device specified with TTYPath= is a - virtual console terminal try to + virtual console terminal, try to deallocate the TTY before and after execution. This ensures that the screen and scrollback buffer is @@ -549,7 +549,7 @@ SyslogIdentifier= Sets the process name to prefix log lines sent to syslog or - the kernel log buffer with. If not set + the kernel log buffer with. If not set, defaults to the process name of the executed process. This option is only useful when @@ -693,13 +693,13 @@ PAMName= Sets the PAM service - name to set up a session as. If set + name to set up a session as. If set, the executed process will be registered as a PAM session under the specified service name. This is only useful in conjunction with the User= setting. If - not set no PAM session will be opened + not set, no PAM session will be opened for the executed processes. See pam8 for details. @@ -708,7 +708,7 @@ TCPWrapName= If this is a - socket-activated service this sets the + socket-activated service, this sets the tcpwrap service name to check the permission for the current connection with. This is only useful in @@ -718,7 +718,7 @@ socket types (e.g. datagram/UDP) and on processes unrelated to socket-based activation. If the tcpwrap - verification fails daemon start-up + verification fails, daemon start-up will fail and the connection is terminated. See tcpd8 @@ -747,7 +747,7 @@ Capabilities listed will be included in the bounding set, all others are removed. If the list of capabilities - is prefixed with ~ + is prefixed with ~, all but the listed capabilities will be included, the effect of the assignment inverted. Note that this @@ -756,7 +756,7 @@ permitted and inheritable capability sets, on top of what Capabilities= - does. If this option is not used the + does. If this option is not used, the capability bounding set is not modified on process execution, hence no limits on the capabilities of the @@ -764,11 +764,11 @@ appear more than once in which case the bounding sets are merged. If the empty string is assigned to this - option the bounding set is reset to + option, the bounding set is reset to the empty capability set, and all prior settings have no effect. If set to ~ (without any - further argument) the bounding set is + further argument), the bounding set is reset to the full set of available capabilities, also undoing any previous settings. @@ -789,7 +789,7 @@ option may appear more than once in which case the secure bits are ORed. If the empty string is assigned - to this option the bits are reset to + to this option, the bits are reset to 0. @@ -846,7 +846,7 @@ directories listed will have limited access from within the namespace. If the empty string is assigned to this - option the specific list is reset, and + option, the specific list is reset, and all prior assignments have no effect. Paths in @@ -863,7 +863,7 @@ PrivateTmp= Takes a boolean - argument. If true sets up a new file + argument. If true, sets up a new file system namespace for the executed processes and mounts private /tmp and @@ -886,7 +886,7 @@ PrivateNetwork= Takes a boolean - argument. If true sets up a new + argument. If true, sets up a new network namespace for the executed processes and configures only the loopback network device @@ -928,7 +928,7 @@ entries must be created and cleared before and after execution. If the configured string is longer than four - characters it is truncated and the + characters, it is truncated and the terminal four characters are used. This setting interprets %I style string replacements. This setting is @@ -976,11 +976,11 @@ termination with the SIGSYS signal (whitelisting). If the first character - of the list is ~ + of the list is ~, the effect is inverted: only the listed system calls will result in immediate process termination - (blacklisting). If this option is used + (blacklisting). If this option is used, NoNewPrivileges=yes is implied. This feature makes use of the Secure Computing Mode 2 interfaces @@ -997,7 +997,7 @@ option may be specified more than once in which case the filter masks are merged. If the empty string is - assigned the filter is reset, all + assigned, the filter is reset, all prior assignments will have no effect. diff --git a/man/systemd.kill.xml b/man/systemd.kill.xml index ab3d28f23a..1b10fba9d5 100644 --- a/man/systemd.kill.xml +++ b/man/systemd.kill.xml @@ -94,16 +94,16 @@ . If set to - all + , all remaining processes in the control group of this unit will be terminated on unit stop (for services: after the stop command is executed, as configured with ExecStop=). If set - to only the + to , only the main process itself is killed. If set - to no process is + to , no process is killed. In this case only the stop command will be executed on unit stop, but no process be killed diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml index 9aac94e1a1..e5b5c3c7c3 100644 --- a/man/systemd.mount.xml +++ b/man/systemd.mount.xml @@ -151,7 +151,7 @@ systemd.automount5 for details. If is - specified it may be used to configure how long systemd + specified, it may be used to configure how long systemd should wait for a device to show up before giving up on an entry from /etc/fstab. Specify a time in @@ -161,9 +161,9 @@ If a mount point is configured in both /etc/fstab and a unit file that - is stored below /usr the former + is stored below /usr, the former will take precedence. If the unit file is stored below - /etc it will take + /etc, it will take precedence. This means: native unit files take precedence over traditional configuration files, but this is superseded by the rule that configuration in diff --git a/man/systemd.path.xml b/man/systemd.path.xml index 8c782b8531..8d86fca5d6 100644 --- a/man/systemd.path.xml +++ b/man/systemd.path.xml @@ -120,7 +120,7 @@ PathExists= may be used to watch the mere existence of a file or directory. If the file - specified exists the configured unit + specified exists, the configured unit is activated. PathExistsGlob= works similar, but checks for the @@ -151,7 +151,7 @@ combined, of the same and of different types, to watch multiple paths. If the empty string is assigned to any of - these options the list of paths to + these options, the list of paths to watch is reset, and any prior assignments of these options will not have any effect. @@ -199,7 +199,7 @@ MakeDirectory= Takes a boolean - argument. If true the directories to + argument. If true, the directories to watch are created before watching. This option is ignored for PathExists= @@ -211,7 +211,7 @@ If MakeDirectory= is - enabled use the mode specified here to + enabled, use the mode specified here to create the directories in question. Takes an access mode in octal notation. Defaults to diff --git a/man/systemd.preset.xml b/man/systemd.preset.xml index 8af7d4058d..16db8cd85b 100644 --- a/man/systemd.preset.xml +++ b/man/systemd.preset.xml @@ -86,7 +86,7 @@ If no preset files exist, systemctl preset will enable all units that are installed by default. If this is not desired and all - units shall rather be disabled it is necessary to ship + units shall rather be disabled, it is necessary to ship a preset file with a single, catchall "disable *" line. (See example 1, below.) @@ -125,10 +125,10 @@ /etc/ are reserved for the local administrator, who may use this logic to override the preset files installed by vendor packages. All preset - files are sorted by their filename in alphabetical + files are sorted by their filename in lexicographic order, regardless in which of the directories they reside. If multiple files specify the same unit name, - the entry in the file with the alphabetically earliest + the entry in the file with the lexicographically earliest name will be applied. It is recommended to prefix all filenames with a two-digit number and a dash, to simplify the ordering of the files. diff --git a/man/systemd.service.xml b/man/systemd.service.xml index 1eb5f39628..8eda85f62d 100644 --- a/man/systemd.service.xml +++ b/man/systemd.service.xml @@ -140,13 +140,13 @@ If set to (the default value if BusName= - is not specified) it is expected that + is not specified), it is expected that the process configured with ExecStart= is the main process of the service. In this mode, if the process offers functionality to other processes on - the system its communication channels + the system, its communication channels should be installed before the daemon is started up (e.g. sockets set up by systemd, via socket activation), as @@ -154,14 +154,14 @@ starting follow-up units. If set to - it is + , it is expected that the process configured with ExecStart= will call fork() as part of its start-up. The parent process is expected to exit when start-up is complete and all communication - channels set up. The child continues + channels are set up. The child continues to run as the main daemon process. This is the behavior of traditional UNIX daemons. If this @@ -210,7 +210,7 @@ starting up. systemd will proceed starting follow-up units after this notification message has been sent. If - this option is used + this option is used, NotifyAccess= (see below) should be set to open access to the notification socket provided by @@ -220,7 +220,7 @@ . Note that currently Type= - won't work if used in combination with + will not work if used in combination with PrivateNetwork=. Behavior of @@ -262,7 +262,7 @@ guessing algorithm might come to incorrect conclusions if a daemon consists of more than one process. If - the main PID cannot be determined + the main PID cannot be determined, failure detection and automatic restarting of a service will not work reliably. Defaults to @@ -327,7 +327,7 @@ .desktop files. Lone semicolons may be escaped as \;. If the empty - string is assigned to this option the + string is assigned to this option, the list of commands to start is reset, prior assignments of this option will have no effect. @@ -383,19 +383,19 @@ executed process, followed by the further arguments specified. If the absolute filename is prefixed with - - an exit code of + -, an exit code of the command normally considered a failure (i.e. non-zero exit status or abnormal exit due to signal) is ignored and considered success. If both - and - @ are used they + @ are used, they can appear in either order. Note that this setting does not directly support shell command lines. If shell command lines are to - be used they need to be passed + be used, they need to be passed explicitly to a shell implementation of some kind. Example: ExecStart=/bin/sh -c 'dmesg | tac' @@ -471,7 +471,7 @@ KillMode= setting (see systemd.kill5). If - this option is not specified the + this option is not specified, the process is terminated right-away when service stop is requested. Specifier and environment variable substitution @@ -567,11 +567,11 @@ regularly with "WATCHDOG=1" (i.e. the "keep-alive ping"). If the time between two such calls is larger than - the configured time then the service + the configured time, then the service is placed in a failure state. By setting Restart= to or - the service + , the service will be automatically restarted. The time configured here will be passed to the executed service process in the @@ -580,7 +580,7 @@ daemons to automatically enable the keep-alive pinging logic if watchdog support is enabled for the service. If - this option is used + this option is used, NotifyAccess= (see below) should be set to open access to the notification socket provided by @@ -621,9 +621,9 @@ , , or . If set to - (the default) the + (the default), the service will not be restarted. If set to - it will be + , it will be restarted only when the service process exits cleanly. In this context, a clean exit means @@ -631,7 +631,7 @@ SIGHUP, SIGINT, SIGTERM, or SIGPIPE, and additionally, exit statuses and signals specified in SuccessExitStatus=. - If set to + If set to , the service will be restarted when the process exits with an nonzero exit code, is terminated by a signal (including on @@ -639,17 +639,17 @@ service reload) times out, and when the configured watchdog timeout is triggered. If set to - the service + , the service will be restarted only if the service process exits due to an uncaught signal not specified as a clean exit status. If set to - the service + , the service will be restarted only if the watchdog timeout for the service expires. If set to - the service + , the service will be restarted regardless whether it exited cleanly or not, got terminated abnormally by a signal or @@ -682,7 +682,7 @@ appear more than once in which case the list of successful exit statuses is merged. If the empty string is - assigned to this option the list is + assigned to this option, the list is reset, all prior assignments of this option will have no effect. @@ -712,7 +712,7 @@ option may appear more than once in which case the list of restart preventing statuses is merged. If the empty - string is assigned to this option the + string is assigned to this option, the list is reset, all prior assignments of this option will have no effect. @@ -790,13 +790,13 @@ (the default), or . If - no daemon status + , no daemon status updates are accepted from the service processes, all status update messages - are ignored. If + are ignored. If , only service updates sent from the main process of the service are - accepted. If all + accepted. If , all services updates from all members of the service's control group are accepted. This option should be set to @@ -805,8 +805,8 @@ Type=notify or WatchdogSec= (see above). If those options are used but - NotifyAccess= not - configured it will be implicitly set + NotifyAccess= is not + configured, it will be implicitly set to . @@ -841,7 +841,7 @@ This option may appear more than once, in which case the list of socket units is merged. If the empty string - is assigned to this option the list of + is assigned to this option, the list of sockets is reset, all prior uses of this setting will have no effect. @@ -852,12 +852,12 @@ StartLimitBurst= Configure service - start rate limiting. By default + start rate limiting. By default, services which are started more often than 5 times within 10s are not permitted to start any more times until the 10s interval ends. With - these two options this rate limiting + these two options, this rate limiting may be modified. Use StartLimitInterval= to configure the checking interval diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml index 1fc28c54e4..419a38caa7 100644 --- a/man/systemd.socket.xml +++ b/man/systemd.socket.xml @@ -96,7 +96,7 @@ foo.socket needs a matching service foo.service if is set. If - is set a service template + is set, a service template file foo@.service must exist from which services are instantiated for each incoming connection. @@ -164,17 +164,17 @@ family. If the address starts with an at - symbol (@) it is read as abstract + symbol (@), it is read as abstract namespace socket in the AF_UNIX family. The @ is replaced with a NUL character - before binding. For details see + before binding. For details, see unix7. If the address string is a - single number it is read as port + single number, it is read as port number to listen on via IPv6. Depending on the value of BindIPv6Only= (see below) this @@ -184,13 +184,13 @@ If the address string is a - string in the format v.w.x.y:z it is + string in the format v.w.x.y:z, it is read as IPv4 specifier for listening on an address v.w.x.y on a port z. If the address string is a - string in the format [x]:y it is read + string in the format [x]:y, it is read as IPv6 address x on a port y. Note that this might make the service available via IPv4, too, depending on @@ -303,7 +303,7 @@ , they will be accessible via IPv6 only. If (which is the - default, surprise!) the system wide + default, surprise!), the system wide default setting is used, as controlled by /proc/sys/net/ipv6/bindv6only, @@ -330,7 +330,7 @@ BindToDevice= Specifies a network interface name to bind this socket - to. If set traffic will only be + to. If set, traffic will only be accepted from the specified network interfaces. This controls the SO_BINDTODEVICE socket option (see diff --git a/man/systemd.special.xml b/man/systemd.special.xml index 4d06607145..863a029fe3 100644 --- a/man/systemd.special.xml +++ b/man/systemd.special.xml @@ -939,7 +939,7 @@ Wants= type dependency. If the unit wants to be pulled in by the first - remote mount showing up it + remote mount showing up, it should use network-online.target (see above). @@ -1012,7 +1012,7 @@ manager should start this unit. If systemd receives SIGTERM or SIGINT when running - as user service daemon it will + as user service daemon, it will start this unit. Normally, this pulls in diff --git a/man/systemd.swap.xml b/man/systemd.swap.xml index 5e339ea18c..18ef5b0f53 100644 --- a/man/systemd.swap.xml +++ b/man/systemd.swap.xml @@ -114,7 +114,7 @@ for details about the conversion. If a swap device or file is configured in both - /etc/fstab and a unit file the + /etc/fstab and a unit file, the configuration in the latter takes precedence. Unless the option is set @@ -175,7 +175,7 @@ Configures the time to wait for the swapon command to finish. If a command does not exit - within the configured time the swap + within the configured time, the swap will be considered failed and be shut down again. All commands still running will be terminated forcibly via diff --git a/man/systemd.time.xml b/man/systemd.time.xml index 3d13b573fa..f438fa5bb9 100644 --- a/man/systemd.time.xml +++ b/man/systemd.time.xml @@ -157,7 +157,7 @@ time span. Correspondingly, a time span that is prefixed with - is evaluated to the current time minus the specified time span. Instead of - prefixing the time span with - it + prefixing the time span with -, it may also be suffixed with a space and the word ago. @@ -231,7 +231,7 @@ Either time or date specification may be omitted, in which case the current day and 00:00:00 is implied, respectively. If the second component is not - specified :00 is assumed. + specified, :00 is assumed. Timezone names may not be specified. diff --git a/man/systemd.timer.xml b/man/systemd.timer.xml index fa67d59a22..659bc81ccd 100644 --- a/man/systemd.timer.xml +++ b/man/systemd.timer.xml @@ -128,7 +128,7 @@ combined of the same and of different types. For example, by combining OnBootSec= and - OnUnitActiveSec= it is + OnUnitActiveSec=, it is possible to define a timer that elapses in regular intervals and activates a specific service each diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index 17141576d0..d61426a845 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -126,9 +126,9 @@ Unit files may contain additional options on top of those listed here. If systemd encounters an unknown - option it will write a warning log message but + option, it will write a warning log message but continue loading the unit. If an option is prefixed - with it is ignored completely by + with , it is ignored completely by systemd. Applications may use this to include additional information in the unit files. @@ -136,7 +136,7 @@ written in various formats. For positive settings the strings , , and are - equivalent. For negative settings the strings + equivalent. For negative settings, the strings , , and are equivalent. @@ -160,14 +160,14 @@ space character. This may be used to wrap long lines. Along with a unit file - foo.service the directory + foo.service, the directory foo.service.wants/ may exist. All unit files symlinked from such a directory are implicitly added as dependencies of type Wanted= to the unit. This is useful to hook units into the start-up of other units, without having to modify their unit files. For details - about the semantics of Wanted= see + about the semantics of Wanted=, see below. The preferred way to create symlinks in the .wants/ directory of a unit file is with the enable command of the @@ -179,7 +179,7 @@ .requires/ in this case. Along with a unit file - foo.service a directory + foo.service, a directory foo.service.d/ may exist. All files with the suffix .conf from this directory will be parsed after the file itself is @@ -206,7 +206,7 @@ file system namespace. Example: a device unit dev-sda.device refers to a device with the device node /dev/sda in - the file system namespace. If this applies a special + the file system namespace. If this applies, a special way to escape the path name is used, so that the result is usable as part of a filename. Basically, given a path, "/" is replaced by "-", and all @@ -219,7 +219,7 @@ Optionally, units may be instantiated from a template file at runtime. This allows creation of multiple units from a single configuration file. If - systemd looks for a unit configuration file it will + systemd looks for a unit configuration file, it will first search for the literal unit name in the filesystem. If that yields no success and the unit name contains an @ character, systemd will look for a @@ -238,7 +238,7 @@ configuration options. See below for details. If a unit file is empty (i.e. has the file size - 0) or is symlinked to /dev/null + 0) or is symlinked to /dev/null, its configuration will not be loaded and it appears with a load state of masked, and cannot be activated. Use this as an effective way to @@ -461,7 +461,7 @@ the start-up was pulled in indirectly by some dependency or automatic start-up of units that is not - requested by the user this dependency + requested by the user, this dependency must be fulfilled and otherwise the transaction fails. Hence, this option may be used to configure dependencies @@ -624,7 +624,7 @@ type After= or Before=. If two units have no ordering dependencies - between them they are shut down + between them, they are shut down or started up simultaneously, and no ordering takes place. @@ -672,12 +672,12 @@ OnFailureIsolate= Takes a boolean - argument. If the + argument. If , the unit listed in OnFailure= will be enqueued in isolation mode, i.e. all units that are not its dependency will - be stopped. If this is set only a + be stopped. If this is set, only a single unit may be listed in OnFailure=. Defaults to @@ -688,7 +688,7 @@ IgnoreOnIsolate= Takes a boolean - argument. If + argument. If , this unit will not be stopped when isolating another unit. Defaults to . @@ -698,7 +698,7 @@ IgnoreOnSnapshot= Takes a boolean - argument. If + argument. If , this unit will not be included in snapshots. Defaults to for device and @@ -710,7 +710,7 @@ StopWhenUnneeded= Takes a boolean - argument. If + argument. If , this unit will be stopped when it is no longer used. Note that in order to minimize the work to be executed, @@ -729,10 +729,10 @@ RefuseManualStop= Takes a boolean - argument. If + argument. If , this unit can only be activated or deactivated indirectly. In - this case explicit start-up + this case, explicit start-up or termination requested by the user is denied, however if it is started or stopped as a @@ -752,10 +752,10 @@ AllowIsolate= Takes a boolean - argument. If + argument. If , this unit may be used with the systemctl isolate - command. Otherwise this will be + command. Otherwise, this will be refused. It probably is a good idea to leave this disabled except for target units that shall be used similar to @@ -769,7 +769,7 @@ DefaultDependencies= Takes a boolean - argument. If + argument. If , (the default), a few default dependencies will implicitly be created for the unit. The actual @@ -799,7 +799,7 @@ When clients are waiting for a job of this unit to complete, time out after the specified - time. If this time limit is reached + time. If this time limit is reached, the job will be cancelled, the unit however will not change state or even enter the failed @@ -841,7 +841,7 @@ Before starting a unit verify that the specified condition is - true. If it is not true the starting + true. If it is not true, the starting of the unit will be skipped, however all ordering dependencies of it are still respected. A failing condition @@ -856,7 +856,7 @@ a file existence condition is checked before a unit is started. If the specified absolute path name does - not exist the condition will + not exist, the condition will fail. If the absolute path name passed to ConditionPathExists= @@ -966,7 +966,7 @@ systemd-nspawn to test against a specific implementation. If multiple - virtualization technologies are nested + virtualization technologies are nested, only the innermost is considered. The test may be negated by prepending an exclamation mark. @@ -1016,12 +1016,12 @@ battery powered at the time of activation of the unit. This takes a boolean argument. If set to - true the condition + true, the condition will hold only if at least one AC connector of the system is connected to a power source, or if no AC connectors are known. Conversely, if - set to false the + set to false, the condition will hold only if there is at least one AC connector known and all AC connectors are disconnected @@ -1032,30 +1032,30 @@ be used to add a constant condition check value to the unit. It takes a boolean argument. If set to - false the condition + false, the condition will always fail, otherwise succeed. If multiple conditions are - specified the unit will be executed if + specified, the unit will be executed if all of them apply (i.e. a logical AND is applied). Condition checks can be prefixed with a pipe symbol (|) in which case a condition becomes a triggering condition. If at least one triggering condition is defined for a - unit then the unit will be executed if + unit, then the unit will be executed if at least one of the triggering conditions apply and all of the non-triggering conditions. If you prefix an argument with the pipe - symbol and an exclamation mark the + symbol and an exclamation mark, the pipe symbol must be passed first, the exclamation second. Except for ConditionPathIsSymbolicLink=, all path checks follow symlinks. If any of these options is assigned the - empty string the list of conditions is + empty string, the list of conditions is reset completely, all previous condition settings (of any kind) will have no effect. diff --git a/man/systemd.xml b/man/systemd.xml index 47d6438939..97ef768608 100644 --- a/man/systemd.xml +++ b/man/systemd.xml @@ -136,7 +136,7 @@ Set default unit to - activate on startup. If not specified + activate on startup. If not specified, defaults to default.target. @@ -233,7 +233,7 @@ Highlight important log messages. Argument is a boolean - value. If the argument is omitted it + value. If the argument is omitted, it defaults to . @@ -429,7 +429,7 @@ multi-user.target (for limited console-only boots for use in embedded or server environments, or similar; a subset of - graphical.target). However it is at the discretion of + graphical.target). However, it is at the discretion of the administrator to configure it as an alias to any other target unit. See systemd.special7 @@ -1030,9 +1030,9 @@ systemd.dump_core= Takes a boolean - argument. If + argument. If , systemd dumps core when it - crashes. Otherwise no core dump is + crashes. Otherwise, no core dump is created. Defaults to . @@ -1041,9 +1041,9 @@ systemd.crash_shell= Takes a boolean - argument. If + argument. If , systemd spawns a shell when it - crashes. Otherwise no shell is + crashes. Otherwise, no shell is spawned. Defaults to , for security reasons, as the shell is not protected @@ -1065,7 +1065,7 @@ systemd.confirm_spawn= Takes a boolean - argument. If + argument. If , asks for confirmation when spawning processes. Defaults to . @@ -1075,7 +1075,7 @@ systemd.show_status= Takes a boolean - argument. If + argument. If , shows terse service status updates on the console during bootup. Defaults to , unless diff --git a/man/timedatectl.xml b/man/timedatectl.xml index 9aade29a78..be0ad3f012 100644 --- a/man/timedatectl.xml +++ b/man/timedatectl.xml @@ -122,10 +122,10 @@ If set-local-rtc is - invoked and this option is passed the + invoked and this option is passed, the system clock is synchronized from the RTC again, taking the new setting into - account. Otherwise the RTC is + account. Otherwise, the RTC is synchronized from the system clock. @@ -161,7 +161,7 @@ timezones can be listed with list-timezones. If the RTC is configured to be in the - local time this will also update the + local time, this will also update the RTC time. This call will alter the /etc/localtime symlink. See @@ -184,17 +184,17 @@ set-local-rtc [BOOL] Takes a boolean - argument. If 0 the + argument. If 0, the system is configured to maintain the - RTC in universal time, if - 1 it will maintain + RTC in universal time. If + 1, it will maintain the RTC in local time instead. Note that maintaining the RTC in the local timezone is not fully supported and will create various problems with time zone changes and daylight saving - adjustments. If at all possible use - RTC in UTC. Note that invoking this + adjustments. If at all possible, keep the + RTC in UTC mode. Note that invoking this will also synchronize the RTC from the system clock, unless is diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml index 2872cc0add..cdc87c9192 100644 --- a/man/tmpfiles.d.xml +++ b/man/tmpfiles.d.xml @@ -79,14 +79,14 @@ administrator, who may use this logic to override the configuration files installed by vendor packages. All configuration files are sorted by their filename in - alphabetical order, regardless in which of the + lexicographic order, regardless in which of the directories they reside. If multiple files specify the - same path, the entry in the file with the alphabetically + same path, the entry in the file with the lexicographically earliest name will be applied, all all other conflicting entries logged as errors. If the administrator wants to disable a - configuration file supplied by the vendor the + configuration file supplied by the vendor, the recommended way is to place a symlink to /dev/null in /etc/tmpfiles.d/ bearing the @@ -238,10 +238,10 @@ L /tmp/foobar - - - - /dev/null The file access mode to use when creating this file or directory. If omitted or - when set to - the default is used: 0755 for + when set to -, the default is used: 0755 for directories, 0644 for all other file - objects. For z, Z lines if omitted or when set - to - the file access mode will not be + objects. For z, Z lines, if omitted or when set + to -, the file access mode will not be modified. This parameter is ignored for x, r, R, L lines. @@ -252,8 +252,8 @@ L /tmp/foobar - - - - /dev/null The user and group to use for this file or directory. This may either be a numeric user/group ID or a user or group name. If - omitted or when set to - the default 0 (root) - is used. For z, Z lines when omitted or when set to - + omitted or when set to -, the default 0 (root) + is used. For z, Z lines, when omitted or when set to -, the file ownership will not be modified. These parameters are ignored for x, r, R, L lines. @@ -263,7 +263,7 @@ L /tmp/foobar - - - - /dev/null The date field, when set, is used to decide what files to delete when cleaning. If a file or directory is older than the current - time minus the age field it is deleted. The + time minus the age field, it is deleted. The field format is a series of integers each followed by one of the following postfixes for the respective time units: @@ -280,7 +280,7 @@ L /tmp/foobar - - - - /dev/null us - If multiple integers and units are specified the time + If multiple integers and units are specified, the time values are summed up. If an integer is given without a unit, s is assumed. @@ -289,11 +289,11 @@ L /tmp/foobar - - - - /dev/null unconditionally. The age field only applies to lines starting with - d, D and x. If omitted or set to - no automatic clean-up + d, D and x. If omitted or set to -, no automatic clean-up is done. If the age field starts with a tilde - character (~) the clean-up is only applied to + character (~), the clean-up is only applied to files and directories one level inside the directory specified, but not the files and directories immediately inside it. -- cgit v1.2.1 From 6e869e18c07f4251390cbf215532635a85712a6a Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 12 Sep 2013 23:37:23 +0200 Subject: shut up gcc complaining about freeing a const variable --- src/systemctl/systemctl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index dc3e41bf42..57e5bb941b 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -1494,7 +1494,8 @@ static DBusHandlerResult wait_filter(DBusConnection *connection, DBusMessage *me } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Manager", "JobRemoved")) { uint32_t id; - const char *path, *result, *unit, *r; + const char *path, *result, *unit; + char *r; if (dbus_message_get_args(message, &error, DBUS_TYPE_UINT32, &id, -- cgit v1.2.1 From 64eed40c07efb4e2b316ebb4e7481b7a891b7934 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 12 Sep 2013 19:35:59 -0400 Subject: bash-completion: add systemd-run --- Makefile.am | 1 + TODO | 2 +- shell-completion/bash/systemd-run | 63 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 shell-completion/bash/systemd-run diff --git a/Makefile.am b/Makefile.am index 3cb6c494c1..ea223e98cd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -341,6 +341,7 @@ dist_bashcompletion_DATA = \ shell-completion/bash/journalctl \ shell-completion/bash/systemctl \ shell-completion/bash/systemd-analyze \ + shell-completion/bash/systemd-run \ shell-completion/bash/udevadm \ shell-completion/bash/kernel-install diff --git a/TODO b/TODO index 8701a936e5..08d4914256 100644 --- a/TODO +++ b/TODO @@ -727,7 +727,7 @@ Features: - document initcall_debug - kernel cmdline "bootchart" option for simplicity? -* systemd-run is missing completion scripts +* systemd-run is missing zsh completion scripts External: diff --git a/shell-completion/bash/systemd-run b/shell-completion/bash/systemd-run new file mode 100644 index 0000000000..ab55274233 --- /dev/null +++ b/shell-completion/bash/systemd-run @@ -0,0 +1,63 @@ +# systemd-run(1) completion -*- shell-script -*- +# +# This file is part of systemd. +# +# Copyright 2013 Zbigniew Jędrzejewski-Szmek +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 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 Lesser General Public License +# along with systemd; If not, see . + +__systemctl() { + local mode=$1; shift 1 + systemctl $mode --full --no-legend "$@" +} + +__get_slice_units () { __systemctl $1 list-units --all -t slice \ + | { while read -r a b c d; do echo " $a"; done; }; } + +_systemd_run() { + local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} + local OPTS='-h --help --version --user --scope --unit --description --slice -r --remain-after-exit --send-sighup' + + local mode=--system + local i + for (( i=1; i <= COMP_CWORD; i++ )); do + if [[ ${COMP_WORDS[i]} != -* ]]; then + local root_command=${COMP_WORDS[i]} + _command_offset $i + return + fi + + [[ ${COMP_WORDS[i]} == "--user" ]] && mode=--user + + [[ $i -lt $COMP_CWORD && ${COMP_WORDS[i]} == @(--unit|--description|--slice) ]] && ((i++)) + done + + case "$prev" in + --unit|--description) + # argument required but no completions available + return + ;; + --slice) + local comps=$(__get_slice_units $mode) + + COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) + return 0 + ;; + esac + + COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") ) + return 0 +} + +complete -F _systemd_run systemd-run -- cgit v1.2.1 From 4f0be680b5323e037314cfbd3dba34f03e637c8f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 13 Sep 2013 02:11:19 +0200 Subject: build-sys: prepare 207 --- Makefile.am | 12 ++++---- NEWS | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- configure.ac | 2 +- 3 files changed, 102 insertions(+), 10 deletions(-) diff --git a/Makefile.am b/Makefile.am index ea223e98cd..7b7539a3a3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -35,27 +35,27 @@ SUBDIRS = . po .PRECIOUS: $(TEST_SUITE_LOG) Makefile LIBUDEV_CURRENT=4 -LIBUDEV_REVISION=7 +LIBUDEV_REVISION=8 LIBUDEV_AGE=3 LIBGUDEV_CURRENT=1 LIBGUDEV_REVISION=3 LIBGUDEV_AGE=1 -LIBSYSTEMD_LOGIN_CURRENT=8 -LIBSYSTEMD_LOGIN_REVISION=1 -LIBSYSTEMD_LOGIN_AGE=8 +LIBSYSTEMD_LOGIN_CURRENT=9 +LIBSYSTEMD_LOGIN_REVISION=0 +LIBSYSTEMD_LOGIN_AGE=9 LIBSYSTEMD_DAEMON_CURRENT=0 LIBSYSTEMD_DAEMON_REVISION=10 LIBSYSTEMD_DAEMON_AGE=0 LIBSYSTEMD_ID128_CURRENT=0 -LIBSYSTEMD_ID128_REVISION=24 +LIBSYSTEMD_ID128_REVISION=25 LIBSYSTEMD_ID128_AGE=0 LIBSYSTEMD_JOURNAL_CURRENT=11 -LIBSYSTEMD_JOURNAL_REVISION=1 +LIBSYSTEMD_JOURNAL_REVISION=2 LIBSYSTEMD_JOURNAL_AGE=11 # Dirs of external packages diff --git a/NEWS b/NEWS index 9d989d33f5..c9e836f7af 100644 --- a/NEWS +++ b/NEWS @@ -1,14 +1,104 @@ systemd System and Service Manager -CHANGES WITH 206: - - * The systemd-sysctl tool does no longer natively read the +CHANGES WITH 207: + + * The Restart= option for services now understands a new + on-watchdog setting which will restart the service + automatically if the service stops sending out watchdog keep + alive messages (as configured with WatchdogSec=). + + * The getty generator (which is responsible for bringing up a + getty on configured serial consoles) will no longer only + start a getty on the primary kernel console but on all + others, too. This makes the order in which console= is + specified on the kernel command line less important. + + * libsystemd-logind gained a new sd_session_get_vt() call to + retrieve the VT number of a session. + + * If the option "tries=0" is set for an entry of /etc/crypttab + its passphrase is queried indefinitely instead of any + maximum number of tries. + + * If a service with a configure PID file terminates its PID + file will now be removed automatically if it still exists + afterwards. This should put an end to stale PID files. + + * systemd-run will now also take relative binary path names + for execution and no longer insists on absolute paths. + + * InaccessibleDirectories= and ReadOnlyDirectories= now take + paths that are optionally prefixed with "-" to indicate that + it should not be considered a failure if they don't exist. + + * journalctl -o (and similar commands) now understand a new + output mode "short-precise" that is similar to "short" but + shows timestamps with usec accuracy. + + * The option "discard" (as known from Debian) is now + synonymous to "allow-discards" in /etc/crypttab. In fact, + the latter is preferred now (since it is easier to remember + and type). + + * Some licensing clean-ups were made so that more code is now + LGPL-2.1 licensed than before. + + * A minimal tool to save/restore the display backlight + brightness across reboots has been added. It will store the + backlight setting as late as possible at shutdown and + restore it as early as possible during reboot. + + * A logic to automatically discover and enable home and swap + partitions on GPT disks has been added. With this in place + /etc/fstab becomes optional for many setups as systemd can + discover certain partitions located on the root disk + automatically. Home partitions are recognized under their + GPT type ID 933ac7e12eb44f13b8440e14e2aef915. Swap + partitions are recognized under their GPT type ID + 0657fd6da4ab43c484e50933c84b4f4f. + + * systemd will no longer pass any environment from the kernel + or initrd to system services. If you want to set an + environment for all services, do so via the kernel command + line systemd.setenv= assignment. + + * The systemd-sysctl tool no longer natively reads the file /etc/sysctl.conf. If desired, the file should be symlinked from /etc/sysctl.d/99-sysctl.conf. Apart from providing legacy support by a symlink rather than built-in code, it also makes the otherwise hidden order of application of the different files visible. + * The "systemctl set-log-level" and "systemctl dump" commands + have been moved to systemd-analyze. + + * systemd-run learned the new --remain-after-exit switch, + which causes the scope unit not to be cleaned up + automatically after the process terminated. + + * tmpfiles learned a new --exclude-prefix= switch to exclude + certain paths from operation. + + * journald will now automatically flush all messages to disk + as soon as a message of the log priorities CRIT, ALERT or + EMERG is received. + + Contributions from: Andrew Cook, Brandon Philips, Christian + Hesse, Christoph Junghans, Colin Walters, Daniel Schaal, + Daniel Wallace, Dave Reisner, David Herrmann, Gao feng, George + McCollister, Giovanni Campagna, Hannes Reinecke, Harald Hoyer, + Herczeg Zsolt, Holger Hans Peter Freyther, Jan Engelhardt, + Jesper Larsen, Kay Sievers, Khem Raj, Lennart Poettering, + Lukas Nykryn, Maciej Wereski, Mantas Mikulėnas, Marcel + Holtmann, Martin Pitt, Michael Biebl, Michael Marineau, + Michael Scherer, Michael Stapelberg, Michal Sekletar, Michał + Górny, Olivier Brunel, Ondrej Balaz, Ronny Chevalier, Shawn + Landden, Steven Hiscocks, Thomas Bächler, Thomas Hindoe + Paaboel Andersen, Tom Gundersen, Umut Tezduyar, WANG Chao, + William Giokas, Zbigniew Jędrzejewski-Szmek + + -- Berlin, 2013-09-13 + CHANGES WITH 206: * The documentation has been updated to cover the various new @@ -106,6 +196,8 @@ CHANGES WITH 206: Thomas H.P. Andersen, Tom Gundersen, Tomasz Torcz, William Giokas, Zbigniew Jędrzejewski-Szmek + -- Berlin, 2013-07-23 + CHANGES WITH 205: * Two new unit types have been introduced: diff --git a/configure.ac b/configure.ac index c6978c72a5..d3f853f30c 100644 --- a/configure.ac +++ b/configure.ac @@ -20,7 +20,7 @@ AC_PREREQ([2.64]) AC_INIT([systemd], - [206], + [207], [http://bugs.freedesktop.org/enter_bug.cgi?product=systemd], [systemd], [http://www.freedesktop.org/wiki/Software/systemd]) -- cgit v1.2.1 From f3a165b05d117b9a9657076fed6b265eb40d5ba3 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 13 Sep 2013 02:24:57 +0200 Subject: NEWS: update --- NEWS | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index c9e836f7af..7e2a441a50 100644 --- a/NEWS +++ b/NEWS @@ -3,7 +3,7 @@ systemd System and Service Manager CHANGES WITH 207: * The Restart= option for services now understands a new - on-watchdog setting which will restart the service + on-watchdog setting, which will restart the service automatically if the service stops sending out watchdog keep alive messages (as configured with WatchdogSec=). @@ -31,8 +31,8 @@ CHANGES WITH 207: paths that are optionally prefixed with "-" to indicate that it should not be considered a failure if they don't exist. - * journalctl -o (and similar commands) now understand a new - output mode "short-precise" that is similar to "short" but + * journalctl -o (and similar commands) now understands a new + output mode "short-precise", it is similar to "short" but shows timestamps with usec accuracy. * The option "discard" (as known from Debian) is now @@ -40,12 +40,12 @@ CHANGES WITH 207: the latter is preferred now (since it is easier to remember and type). - * Some licensing clean-ups were made so that more code is now + * Some licensing clean-ups were made, so that more code is now LGPL-2.1 licensed than before. * A minimal tool to save/restore the display backlight brightness across reboots has been added. It will store the - backlight setting as late as possible at shutdown and + backlight setting as late as possible at shutdown, and restore it as early as possible during reboot. * A logic to automatically discover and enable home and swap -- cgit v1.2.1 From 719e4e368b8bbe4e2f2ce49ec6f864a90bd6c619 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 13 Sep 2013 04:13:47 +0200 Subject: update TODO --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index 08d4914256..5354692928 100644 --- a/TODO +++ b/TODO @@ -58,6 +58,8 @@ CGroup Rework Completion: Features: +* Move backlight and random-seed into /var/lib/systemd + * When a Type=forking service fails and needed another service that service is not cleaned up again when it has StopWhenUnneeded=yes http://lists.freedesktop.org/archives/systemd-devel/2013-July/012141.html -- cgit v1.2.1 From 8c11d3c1b5851f05d63198a92833be80616750e9 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Thu, 15 Aug 2013 08:47:59 +0800 Subject: cryptsetup-generator: don't create tmp+swap units --- src/cryptsetup/cryptsetup-generator.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c index 81b770890a..967c5e6e0b 100644 --- a/src/cryptsetup/cryptsetup-generator.c +++ b/src/cryptsetup/cryptsetup-generator.c @@ -72,13 +72,20 @@ static int create_disk( _cleanup_free_ char *p = NULL, *n = NULL, *d = NULL, *u = NULL, *from = NULL, *to = NULL, *e = NULL; _cleanup_fclose_ FILE *f = NULL; - bool noauto, nofail; + bool noauto, nofail, tmp, swap; assert(name); assert(device); noauto = has_option(options, "noauto"); nofail = has_option(options, "nofail"); + tmp = has_option(options, "tmp"); + swap = has_option(options, "swap"); + + if (tmp && swap) { + log_error("Device '%s' cannot be both 'tmp' and 'swap'. Ignoring.", name); + return -EINVAL; + } n = unit_name_from_path_instance("systemd-cryptsetup", name, ".service"); if (!n) @@ -151,12 +158,12 @@ static int create_disk( name, u, strempty(password), strempty(options), name); - if (has_option(options, "tmp")) + if (tmp) fprintf(f, "ExecStartPost=/sbin/mke2fs '/dev/mapper/%s'\n", name); - if (has_option(options, "swap")) + if (swap) fprintf(f, "ExecStartPost=/sbin/mkswap '/dev/mapper/%s'\n", name); -- cgit v1.2.1 From 7ab064a6d60cf805765077b67d56c123f9cf3c58 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Sun, 18 Aug 2013 14:59:00 +0800 Subject: cryptsetup-generator: allow specifying options in /proc/cmdline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The main usecase for this is to make it possible to use cryptsetup in the initrd without it having to include a host-specific /etc/crypttab. Tested-by: Thomas Bächler --- man/systemd-cryptsetup-generator.xml | 23 ++++++++++ src/cryptsetup/cryptsetup-generator.c | 79 +++++++++++++++++++++++++++++++++-- 2 files changed, 98 insertions(+), 4 deletions(-) diff --git a/man/systemd-cryptsetup-generator.xml b/man/systemd-cryptsetup-generator.xml index 215ac2d125..d6b7e49f13 100644 --- a/man/systemd-cryptsetup-generator.xml +++ b/man/systemd-cryptsetup-generator.xml @@ -137,6 +137,29 @@ will be activated in the initrd or the real root. + + + luks.options= + rd.luks.options= + + Takes a LUKS super + block UUID followed by an '=' and a string + of options separated by commas as argument. + This will override the options for the given + UUID. + If only a list of options, without an + UUID, is specified, they apply to any UUIDs not + specified elsewhere, and without an entry in + /etc/crypttab. + rd.luks.options= + is honored only by initial RAM disk + (initrd) while + luks.options= is + honored by both the main system and + the initrd. + + + luks.key= rd.luks.key= diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c index 967c5e6e0b..ba6efa6fc3 100644 --- a/src/cryptsetup/cryptsetup-generator.c +++ b/src/cryptsetup/cryptsetup-generator.c @@ -240,7 +240,7 @@ static int create_disk( return 0; } -static int parse_proc_cmdline(char ***arg_proc_cmdline_disks, char **arg_proc_cmdline_keyfile) { +static int parse_proc_cmdline(char ***arg_proc_cmdline_disks, char ***arg_proc_cmdline_options, char **arg_proc_cmdline_keyfile) { _cleanup_free_ char *line = NULL; char *w = NULL, *state = NULL; int r; @@ -307,7 +307,20 @@ static int parse_proc_cmdline(char ***arg_proc_cmdline_disks, char **arg_proc_cm return log_oom(); } + } else if (startswith(word, "luks.options=")) { + if (strv_extend(arg_proc_cmdline_options, word + 13) < 0) + return log_oom(); + + } else if (startswith(word, "rd.luks.options=")) { + + if (in_initrd()) { + if (strv_extend(arg_proc_cmdline_options, word + 16) < 0) + return log_oom(); + } + } else if (startswith(word, "luks.key=")) { + if (*arg_proc_cmdline_keyfile) + free(*arg_proc_cmdline_keyfile); *arg_proc_cmdline_keyfile = strdup(word + 9); if (!*arg_proc_cmdline_keyfile) return log_oom(); @@ -337,6 +350,7 @@ static int parse_proc_cmdline(char ***arg_proc_cmdline_disks, char **arg_proc_cm int main(int argc, char *argv[]) { _cleanup_strv_free_ char **arg_proc_cmdline_disks_done = NULL; _cleanup_strv_free_ char **arg_proc_cmdline_disks = NULL; + _cleanup_strv_free_ char **arg_proc_cmdline_options = NULL; _cleanup_free_ char *arg_proc_cmdline_keyfile = NULL; _cleanup_fclose_ FILE *f = NULL; unsigned n = 0; @@ -357,7 +371,7 @@ int main(int argc, char *argv[]) { umask(0022); - if (parse_proc_cmdline(&arg_proc_cmdline_disks, &arg_proc_cmdline_keyfile) < 0) + if (parse_proc_cmdline(&arg_proc_cmdline_disks, &arg_proc_cmdline_options, &arg_proc_cmdline_keyfile) < 0) return EXIT_FAILURE; if (!arg_enabled) @@ -412,6 +426,26 @@ int main(int argc, char *argv[]) { continue; } + if (arg_proc_cmdline_options) { + /* + If options are specified on the kernel commandline, let them override + the ones from crypttab. + */ + STRV_FOREACH(i, arg_proc_cmdline_options) { + _cleanup_free_ char *proc_uuid = NULL, *proc_options = NULL; + const char *p = *i; + + k = sscanf(p, "%m[0-9a-fA-F-]=%ms", &proc_uuid, &proc_options); + if (k == 2 && streq(proc_uuid, device + 5)) { + if (options) + free(options); + options = strdup(p); + if (!proc_options) + return log_oom(); + } + } + } + if (arg_proc_cmdline_disks) { /* If luks UUIDs are specified on the kernel command line, use them as a filter @@ -452,7 +486,7 @@ next: on the kernel command line and not yet written. */ - _cleanup_free_ char *name = NULL, *device = NULL; + _cleanup_free_ char *name = NULL, *device = NULL, *options = NULL; const char *p = *i; if (startswith(p, "luks-")) @@ -467,7 +501,44 @@ next: if (!name || !device) return log_oom(); - if (create_disk(name, device, arg_proc_cmdline_keyfile, "timeout=0") < 0) + if (arg_proc_cmdline_options) { + /* + If options are specified on the kernel commandline, use them. + */ + char **j; + + STRV_FOREACH(j, arg_proc_cmdline_options) { + _cleanup_free_ char *proc_uuid = NULL, *proc_options = NULL; + const char *s = *j; + int k; + + k = sscanf(s, "%m[0-9a-fA-F-]=%ms", &proc_uuid, &proc_options); + if (k == 2) { + if (streq(proc_uuid, device + 5)) { + if (options) + free(options); + options = strdup(proc_options); + if (!options) + return log_oom(); + } + } else if (!options) { + /* + Fall back to options without a specified UUID + */ + options = strdup(s); + if (!options) + return log_oom(); + } + } + } + + if (!options) { + options = strdup("timeout=0"); + if (!options) + return log_oom(); + } + + if (create_disk(name, device, arg_proc_cmdline_keyfile, options) < 0) r = EXIT_FAILURE; } -- cgit v1.2.1 From a5e41bdb72a15c34971469535b4c3da16f0cce55 Mon Sep 17 00:00:00 2001 From: David Mackey Date: Thu, 12 Sep 2013 19:45:49 -0700 Subject: automount: rename repeat_unmont to repeat_unmount Trivial cleanup of repeat_unmount() spelling. --- src/core/automount.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/automount.c b/src/core/automount.c index a20d5340f2..67623929c9 100644 --- a/src/core/automount.c +++ b/src/core/automount.c @@ -66,7 +66,7 @@ static void automount_init(Unit *u) { UNIT(a)->ignore_on_isolate = true; } -static void repeat_unmout(const char *path) { +static void repeat_unmount(const char *path) { assert(path); for (;;) { @@ -100,7 +100,7 @@ static void unmount_autofs(Automount *a) { if (a->where && (UNIT(a)->manager->exit_code != MANAGER_RELOAD && UNIT(a)->manager->exit_code != MANAGER_REEXECUTE)) - repeat_unmout(a->where); + repeat_unmount(a->where); } static void automount_done(Unit *u) { @@ -575,7 +575,7 @@ fail: close_nointr_nofail(ioctl_fd); if (mounted) - repeat_unmout(a->where); + repeat_unmount(a->where); log_error_unit(UNIT(a)->id, "Failed to initialize automounter: %s", strerror(-r)); -- cgit v1.2.1 From 15b4a7548f2e8f4e5dc0504b1c549edb0c7e0956 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Fri, 13 Sep 2013 11:17:05 +0800 Subject: cgroup: add the missing setting of variable's value set the value of variable "r" to the return value of cg_set_attribute. --- src/core/cgroup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 3eeb475754..fba0b2f9de 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -264,7 +264,7 @@ void cgroup_context_apply(CGroupContext *c, CGroupControllerMask mask, const cha log_error("Failed to set memory.limit_in_bytes on %s: %s", path, strerror(-r)); sprintf(buf, "%" PRIu64 "\n", c->memory_soft_limit); - cg_set_attribute("memory", path, "memory.soft_limit_in_bytes", buf); + r = cg_set_attribute("memory", path, "memory.soft_limit_in_bytes", buf); if (r < 0) log_error("Failed to set memory.limit_in_bytes on %s: %s", path, strerror(-r)); } -- cgit v1.2.1 From 84121bc2ee2b1af811a50bc6974115aba603c806 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Fri, 13 Sep 2013 11:17:06 +0800 Subject: cgroup: correct the log information it should be memory.soft_limit_in_bytes. --- src/core/cgroup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/cgroup.c b/src/core/cgroup.c index fba0b2f9de..aee93ba0a8 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -266,7 +266,7 @@ void cgroup_context_apply(CGroupContext *c, CGroupControllerMask mask, const cha sprintf(buf, "%" PRIu64 "\n", c->memory_soft_limit); r = cg_set_attribute("memory", path, "memory.soft_limit_in_bytes", buf); if (r < 0) - log_error("Failed to set memory.limit_in_bytes on %s: %s", path, strerror(-r)); + log_error("Failed to set memory.soft_limit_in_bytes on %s: %s", path, strerror(-r)); } if (mask & CGROUP_DEVICE) { -- cgit v1.2.1 From 6a94f2e938c6535917b29a9611d6ad815125ed1b Mon Sep 17 00:00:00 2001 From: Gao feng Date: Fri, 13 Sep 2013 14:43:04 +0800 Subject: cgroup: fix incorrectly setting memory cgroup If the memory_limit of unit is -1, we should write "-1" to the file memory.limit_in_bytes. not the (unit64_t) -1. otherwise the memory.limit_in_bytes will be set to zero. --- src/core/cgroup.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/core/cgroup.c b/src/core/cgroup.c index aee93ba0a8..244baff3da 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -257,14 +257,21 @@ void cgroup_context_apply(CGroupContext *c, CGroupControllerMask mask, const cha if (mask & CGROUP_MEMORY) { char buf[DECIMAL_STR_MAX(uint64_t) + 1]; + if (c->memory_limit != (uint64_t) -1) { + sprintf(buf, "%" PRIu64 "\n", c->memory_limit); + r = cg_set_attribute("memory", path, "memory.limit_in_bytes", buf); + } else + r = cg_set_attribute("memory", path, "memory.limit_in_bytes", "-1"); - sprintf(buf, "%" PRIu64 "\n", c->memory_limit); - r = cg_set_attribute("memory", path, "memory.limit_in_bytes", buf); if (r < 0) log_error("Failed to set memory.limit_in_bytes on %s: %s", path, strerror(-r)); - sprintf(buf, "%" PRIu64 "\n", c->memory_soft_limit); - r = cg_set_attribute("memory", path, "memory.soft_limit_in_bytes", buf); + if (c->memory_soft_limit != (uint64_t) -1) { + sprintf(buf, "%" PRIu64 "\n", c->memory_soft_limit); + r = cg_set_attribute("memory", path, "memory.soft_limit_in_bytes", buf); + } else + r = cg_set_attribute("memory", path, "memory.soft_limit_in_bytes", "-1"); + if (r < 0) log_error("Failed to set memory.soft_limit_in_bytes on %s: %s", path, strerror(-r)); } -- cgit v1.2.1 From 2dba165c63cc1b687bb9f035a8f01f40595a708a Mon Sep 17 00:00:00 2001 From: Lukas Nykryn Date: Fri, 13 Sep 2013 14:12:55 +0200 Subject: random-seed: we should return errno of failed loop_write --- src/random-seed/random-seed.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/random-seed/random-seed.c b/src/random-seed/random-seed.c index 4776c071ca..afbd5002dd 100644 --- a/src/random-seed/random-seed.c +++ b/src/random-seed/random-seed.c @@ -157,7 +157,7 @@ int main(int argc, char *argv[]) { r = loop_write(seed_fd, buf, (size_t) k, false); if (r <= 0) { log_error("Failed to write new random seed file: %s", r < 0 ? strerror(-r) : "short write"); - r = k == 0 ? -EIO : (int) k; + r = r == 0 ? -EIO : r; } } -- cgit v1.2.1 From df5f6971e6e15b4632884916c71daa076c8bae96 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 13 Sep 2013 14:28:17 +0200 Subject: update TODO --- TODO | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/TODO b/TODO index 5354692928..9943b3e50d 100644 --- a/TODO +++ b/TODO @@ -60,6 +60,10 @@ Features: * Move backlight and random-seed into /var/lib/systemd +* If we try to find a unit via a danglign symlink generate a clean + error. Currently we just ignore it and read the unit from the search + path anyway. + * When a Type=forking service fails and needed another service that service is not cleaned up again when it has StopWhenUnneeded=yes http://lists.freedesktop.org/archives/systemd-devel/2013-July/012141.html -- cgit v1.2.1 From 81c68af03f4ea9a1adc0767f7a3993a1cbe2ab3d Mon Sep 17 00:00:00 2001 From: Lukas Nykryn Date: Fri, 13 Sep 2013 14:31:17 +0200 Subject: core/cgroup: first print then free --- src/core/cgroup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 244baff3da..1f41efc63f 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -402,8 +402,8 @@ static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) { is_in_hash = true; if (r < 0) { - free(path); log_error("cgroup %s exists already: %s", path, strerror(-r)); + free(path); return r; } -- cgit v1.2.1 From 90060fa6605446bef7078867423b691e4effa575 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Fri, 13 Sep 2013 14:46:18 +0200 Subject: swap: fix reverse dependencies Make sure swap.target correctly requires/wants the swap units. This fixes https://bugs.freedesktop.org/show_bug.cgi?id=69291. Reported-by: Hussam Al-Tayeb --- src/core/swap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/swap.c b/src/core/swap.c index 57d15eb34b..3950860757 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -220,7 +220,7 @@ static int swap_add_default_dependencies(Swap *s) { } if (!noauto) { - r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, (nofail ? UNIT_WANTED_BY : UNIT_REQUIRED_BY), + r = unit_add_two_dependencies_by_name_inverse(UNIT(s), UNIT_AFTER, (nofail ? UNIT_WANTS : UNIT_REQUIRES), SPECIAL_SWAP_TARGET, NULL, true); if (r < 0) return r; -- cgit v1.2.1 From 6faa3dcbb8c2c9d89b23a39ca9be258c453255d9 Mon Sep 17 00:00:00 2001 From: Lukas Nykryn Date: Fri, 13 Sep 2013 14:12:54 +0200 Subject: libudev: fix move_later comparison At the beginning move_later is set to -1, but it is set to different value only if expression !move_later is true. --- src/libudev/libudev-enumerate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libudev/libudev-enumerate.c b/src/libudev/libudev-enumerate.c index bc1e37d341..8146f27e4f 100644 --- a/src/libudev/libudev-enumerate.c +++ b/src/libudev/libudev-enumerate.c @@ -300,7 +300,7 @@ _public_ struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enume /* skip to be delayed devices, and move the to * the point where the prefix changes. We can * only move one item at a time. */ - if (!move_later) { + if (move_later == -1) { move_later_prefix = devices_delay_later(udev_enumerate->udev, entry->syspath); if (move_later_prefix > 0) { -- cgit v1.2.1 From ecd1e54ca6bf18a6da5f171b1ae24deac0fa7c87 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Fri, 13 Sep 2013 21:03:55 +0200 Subject: man: document luks.options kernel commandline This should have been part of commit 7ab064a6d --- man/kernel-command-line.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml index a4b7d13c8d..cc267a3ecc 100644 --- a/man/kernel-command-line.xml +++ b/man/kernel-command-line.xml @@ -250,6 +250,8 @@ rd.luks.crypttab= luks.uuid= rd.luks.uuid= + luks.options= + rd.luks.options= luks.key= rd.luks.key= -- cgit v1.2.1 From e39ff1f48d7ffcf7c20f9178ec64efbd7e244cab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 28 Aug 2013 17:23:59 -0400 Subject: keymap: remove some commented out lines --- hwdb/60-keyboard.hwdb | 6 ------ 1 file changed, 6 deletions(-) diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index eca3f559a9..53e83ad426 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -894,11 +894,6 @@ keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*200E[45]*:pvr* # Series 5 keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700Z*:pvr* KEYBOARD_KEY_ce=!prog1 # Fn+F1 launch settings -#KEYBOARD_KEY_89=!brightnessdown # Fn+F2 -#KEYBOARD_KEY_88=!brightnessup # Fn+F3 -#KEYBOARD_KEY_82=!switchvideomode # Fn+F4 video output -#KEYBOARD_KEY_f9=!f23 # Fn+F5 touchpad turn OFF -#KEYBOARD_KEY_f7=!f22 # Fn+F5 touchpad turn ON KEYBOARD_KEY_a0=!mute # Fn+F6 mute KEYBOARD_KEY_ae=!volumedown # Fn+F7 KEYBOARD_KEY_b0=!volumeup # Fn+F8 @@ -906,7 +901,6 @@ keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700Z*:pvr* KEYBOARD_KEY_96=!kbdillumup # Fn+F10 keyboard backlight up KEYBOARD_KEY_b3=!prog3 # Fn+F11 fan/cooling mode changer KEYBOARD_KEY_d5=!wlan # Fn+F12 wlan/airplane switch -# KEYBOARD_KEY_ba=!ejectcd # Fn+DEL eject cd # Series 9 keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*90X3A*:pvr* -- cgit v1.2.1 From 69ab80881552d5f79ca95f6b3be48ad122ab1ec2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 13 Sep 2013 19:41:52 -0400 Subject: Advertise hibernation only if there's enough free swap Condition that is checked is taken from upower: active(anon) < free swap * 0.98 This is really stupid, because the kernel knows the situation better, e.g. there could be two swap files, and then hibernation would be impossible despite passing this check, or the kernel could start supporting compressed swap and/or compressed hibernation images, and then this this check would be too stringent. Nevertheless, until we have something better, this should at least return a true negative if there's no swap. Logging of capabilities in the journal is changed to not strip leading zeros. I consider this more readable anyway. http://cgit.freedesktop.org/upower/tree/src/up-daemon.c#n613 https://bugzilla.redhat.com/show_bug.cgi?id=1007059 --- src/shared/fileio.c | 34 ++++++++++++++++++++++++++++++++++ src/shared/fileio.h | 2 ++ src/shared/logs-show.c | 2 +- src/shared/sleep-config.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- src/shared/util.c | 23 +---------------------- src/test/test-fileio.c | 20 ++++++++++++++++++++ src/test/test-sleep.c | 16 ++++++++-------- 7 files changed, 110 insertions(+), 32 deletions(-) diff --git a/src/shared/fileio.c b/src/shared/fileio.c index 77fd05955a..4e2b4442db 100644 --- a/src/shared/fileio.c +++ b/src/shared/fileio.c @@ -648,3 +648,37 @@ int executable_is_script(const char *path, char **interpreter) { *interpreter = ans; return 1; } + +/** + * Retrieve one field from a file like /proc/self/status. + * pattern should start with '\n' and end with ':'. Whitespace + * after ':' will be skipped. field must be freed afterwards. + */ +int get_status_field(const char *filename, const char *pattern, char **field) { + _cleanup_free_ char *status = NULL; + char *t; + size_t len; + int r; + + assert(filename); + assert(field); + + r = read_full_file(filename, &status, NULL); + if (r < 0) + return r; + + t = strstr(status, pattern); + if (!t) + return -ENOENT; + + t += strlen(pattern); + t += strspn(t, WHITESPACE); + + len = strcspn(t, WHITESPACE); + + *field = strndup(t, len); + if (!*field) + return -ENOMEM; + + return 0; +} diff --git a/src/shared/fileio.h b/src/shared/fileio.h index a0aae28bae..59e41502b1 100644 --- a/src/shared/fileio.h +++ b/src/shared/fileio.h @@ -37,3 +37,5 @@ int load_env_file(const char *fname, const char *separator, char ***l); int write_env_file(const char *fname, char **l); int executable_is_script(const char *path, char **interpreter); + +int get_status_field(const char *filename, const char *pattern, char **field); diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index 87633e7816..f50777c58d 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -201,7 +201,7 @@ static int output_short( assert(j); /* Set the threshold to one bigger than the actual print - * treshold, so that if the line is actually longer than what + * threshold, so that if the line is actually longer than what * we're willing to print, ellipsization will occur. This way * we won't output a misleading line without any indication of * truncation. diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c index cd3238b405..5ec7cce458 100644 --- a/src/shared/sleep-config.c +++ b/src/shared/sleep-config.c @@ -163,6 +163,46 @@ int can_sleep_disk(char **types) { return false; } +#define HIBERNATION_SWAP_THRESHOLD 0.98 + +static bool enough_memory_for_hibernation(void) { + _cleanup_free_ char *active = NULL, *swapfree = NULL; + unsigned long long act, swap; + int r; + + r = get_status_field("/proc/meminfo", "\nSwapFree:", &swapfree); + if (r < 0) { + log_error("Failed to retrieve SwapFree from /proc/meminfo: %s", strerror(-r)); + return false; + } + + r = safe_atollu(swapfree, &swap); + if (r < 0) { + log_error("Failed to parse SwapFree from /proc/meminfo: %s: %s", + swapfree, strerror(-r)); + return false; + } + + r = get_status_field("/proc/meminfo", "\nActive(anon):", &active); + if (r < 0) { + log_error("Failed to retrieve Active(anon) from /proc/meminfo: %s", strerror(-r)); + return false; + } + + r = safe_atollu(active, &act); + if (r < 0) { + log_error("Failed to parse Active(anon) from /proc/meminfo: %s: %s", + active, strerror(-r)); + return false; + } + + r = act <= swap * HIBERNATION_SWAP_THRESHOLD; + log_debug("Hibernation is %spossible, Active(anon)=%llu kB, SwapFree=%llu kB, threshold=%.2g%%", + r ? "" : "im", act, swap, 100*HIBERNATION_SWAP_THRESHOLD); + + return r; +} + int can_sleep(const char *verb) { _cleanup_strv_free_ char **modes = NULL, **states = NULL; int r; @@ -175,5 +215,8 @@ int can_sleep(const char *verb) { if (r < 0) return false; - return can_sleep_state(states) && can_sleep_disk(modes); + if (!can_sleep_state(states) || !can_sleep_disk(modes)) + return false; + + return streq(verb, "suspend") || enough_memory_for_hibernation(); } diff --git a/src/shared/util.c b/src/shared/util.c index 9a075fa163..f6f3b18bfc 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -694,9 +694,6 @@ int is_kernel_thread(pid_t pid) { int get_process_capeff(pid_t pid, char **capeff) { const char *p; - _cleanup_free_ char *status = NULL; - char *t = NULL; - int r; assert(capeff); assert(pid >= 0); @@ -706,25 +703,7 @@ int get_process_capeff(pid_t pid, char **capeff) { else p = procfs_file_alloca(pid, "status"); - r = read_full_file(p, &status, NULL); - if (r < 0) - return r; - - t = strstr(status, "\nCapEff:\t"); - if (!t) - return -ENOENT; - - for (t += strlen("\nCapEff:\t"); t[0] == '0'; t++) - continue; - - if (t[0] == '\n') - t--; - - *capeff = strndup(t, strchr(t, '\n') - t); - if (!*capeff) - return -ENOMEM; - - return 0; + return get_status_field(p, "\nCapEff:", capeff); } int get_process_exe(pid_t pid, char **name) { diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c index 1184e7e02f..4a4ed79c11 100644 --- a/src/test/test-fileio.c +++ b/src/test/test-fileio.c @@ -229,9 +229,29 @@ static void test_executable_is_script(void) { unlink(t); } +static void test_status_field(void) { + _cleanup_free_ char *t = NULL, *p = NULL, *s = NULL; + unsigned long long total, buffers; + + assert_se(get_status_field("/proc/self/status", "\nThreads:", &t) == 0); + puts(t); + assert_se(streq(t, "1")); + + assert_se(get_status_field("/proc/meminfo", "MemTotal:", &p) == 0); + puts(p); + assert_se(safe_atollu(p, &total) == 0); + + assert_se(get_status_field("/proc/meminfo", "\nBuffers:", &s) == 0); + puts(s); + assert_se(safe_atollu(s, &buffers) == 0); + + assert(buffers < total); +} + int main(int argc, char *argv[]) { test_parse_env_file(); test_parse_multiline_env_file(); test_executable_is_script(); + test_status_field(); return 0; } diff --git a/src/test/test-sleep.c b/src/test/test-sleep.c index c3cb9c531d..545dfab92c 100644 --- a/src/test/test-sleep.c +++ b/src/test/test-sleep.c @@ -40,14 +40,14 @@ int main(int argc, char* argv[]) { **shutdown = strv_new("shutdown", NULL), **freez = strv_new("freeze", NULL); - log_info("Can Standby: %s", yes_no(can_sleep_state(standby) > 0)); - log_info("Can Suspend: %s", yes_no(can_sleep_state(mem) > 0)); - log_info("Can Hibernate: %s", yes_no(can_sleep_state(disk) > 0)); - log_info("Can Hibernate+Suspend (Hybrid-Sleep): %s", yes_no(can_sleep_disk(suspend) > 0)); - log_info("Can Hibernate+Reboot: %s", yes_no(can_sleep_disk(reboot) > 0)); - log_info("Can Hibernate+Platform: %s", yes_no(can_sleep_disk(platform) > 0)); - log_info("Can Hibernate+Shutdown: %s", yes_no(can_sleep_disk(shutdown) > 0)); - log_info("Can Freeze: %s", yes_no(can_sleep_disk(freez) > 0)); + log_info("Standby configured: %s", yes_no(can_sleep_state(standby) > 0)); + log_info("Suspend configured: %s", yes_no(can_sleep_state(mem) > 0)); + log_info("Hibernate configured: %s", yes_no(can_sleep_state(disk) > 0)); + log_info("Hibernate+Suspend (Hybrid-Sleep) configured: %s", yes_no(can_sleep_disk(suspend) > 0)); + log_info("Hibernate+Reboot configured: %s", yes_no(can_sleep_disk(reboot) > 0)); + log_info("Hibernate+Platform configured: %s", yes_no(can_sleep_disk(platform) > 0)); + log_info("Hibernate+Shutdown configured: %s", yes_no(can_sleep_disk(shutdown) > 0)); + log_info("Freeze configured: %s", yes_no(can_sleep_state(freez) > 0)); log_info("Suspend configured and possible: %s", yes_no(can_sleep("suspend") > 0)); log_info("Hibernation configured and possible: %s", yes_no(can_sleep("hibernate") > 0)); -- cgit v1.2.1 From a5c724b25b2930ecb4a64bb4d9b8619a1354afed Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 15 Sep 2013 07:29:25 +0200 Subject: README: add SCSI BSG option --- README | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README b/README index a16f342ecf..b39cd377df 100644 --- a/README +++ b/README @@ -64,6 +64,10 @@ REQUIREMENTS: Mount and bind mount handling might require it: CONFIG_FHANDLE + Support for some SCSI devices serial number retrieval, to + create additional symlinks in /dev/disk/ and /dev/tape: + CONFIG_BLK_DEV_BSG + Optional but strongly recommended: CONFIG_IPV6 CONFIG_AUTOFS4_FS -- cgit v1.2.1 From 4e82fe5213bedcb70e25c0270e516d5f2706d8c8 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Mon, 16 Sep 2013 01:08:32 +0200 Subject: swap: create .wants symlink to 'auto' swap devices As we load unit files lazily, we need to make sure something pulls in swap units that should be started automatically, otherwise the default dependencies will never be applied. This partially reinstates code removed in commit 64347fc2b983f33e7efb0fd2bb44e133fb9f30f4. Also don't order swap devices after swap.target when they are 'nofail'. --- src/core/swap.c | 8 ++++++-- src/fstab-generator/fstab-generator.c | 18 ++++++++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/core/swap.c b/src/core/swap.c index 3950860757..76c7d45006 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -220,8 +220,12 @@ static int swap_add_default_dependencies(Swap *s) { } if (!noauto) { - r = unit_add_two_dependencies_by_name_inverse(UNIT(s), UNIT_AFTER, (nofail ? UNIT_WANTS : UNIT_REQUIRES), - SPECIAL_SWAP_TARGET, NULL, true); + if (nofail) + r = unit_add_dependency_by_name_inverse(UNIT(s), + UNIT_WANTS, SPECIAL_SWAP_TARGET, NULL, true); + else + r = unit_add_two_dependencies_by_name_inverse(UNIT(s), + UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SWAP_TARGET, NULL, true); if (r < 0) return r; } diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index 6ebe8aa673..b73dfa4899 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -66,6 +66,7 @@ static int mount_find_pri(struct mntent *me, int *ret) { static int add_swap(const char *what, struct mntent *me) { _cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL, *device = NULL; _cleanup_fclose_ FILE *f = NULL; + bool noauto; int r, pri = -1; assert(what); @@ -77,6 +78,8 @@ static int add_swap(const char *what, struct mntent *me) { return pri; } + noauto = !!hasmntopt(me, "noauto"); + name = unit_name_from_path(what, ".swap"); if (!name) return log_oom(); @@ -97,8 +100,7 @@ static int add_swap(const char *what, struct mntent *me) { fprintf(f, "# Automatically generated by systemd-fstab-generator\n\n" "[Unit]\n" - "SourcePath=/etc/fstab\n" - "\n" + "SourcePath=/etc/fstab\n\n" "[Swap]\n" "What=%s\n", what); @@ -114,6 +116,18 @@ static int add_swap(const char *what, struct mntent *me) { return -errno; } + if (!noauto) { + lnk = strjoin(arg_dest, "/" SPECIAL_SWAP_TARGET ".wants/", name, NULL); + if (!lnk) + return log_oom(); + + mkdir_parents_label(lnk, 0755); + if (symlink(unit, lnk) < 0) { + log_error("Failed to create symlink %s: %m", lnk); + return -errno; + } + } + return 0; } -- cgit v1.2.1 From 112a7f4696ebb96abdb42df62e1e794e903f66b3 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Mon, 16 Sep 2013 09:57:33 +0800 Subject: cgroup: add missing equals for BlockIOWeight --- src/core/cgroup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 1f41efc63f..9277dd69f6 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -92,7 +92,7 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) { "%sBlockIOAccounting=%s\n" "%sMemoryAccounting=%s\n" "%sCPUShares=%lu\n" - "%sBlockIOWeight%lu\n" + "%sBlockIOWeight=%lu\n" "%sMemoryLimit=%" PRIu64 "\n" "%sMemorySoftLimit=%" PRIu64 "\n" "%sDevicePolicy=%s\n", -- cgit v1.2.1 From 442e00839e4fc3c11506f5c8a9477b465865aecc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 15 Sep 2013 08:40:16 -0400 Subject: Assume that /proc/meminfo can be missing Travis tests are failing, probably because /proc/meminfo is not available in the test environment. The same might be true in some virtualized systems, so just treat missing /proc/meminfo as a sign that hibernation is not possible. --- src/shared/sleep-config.c | 3 ++- src/test/test-fileio.c | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c index 5ec7cce458..148c4dc617 100644 --- a/src/shared/sleep-config.c +++ b/src/shared/sleep-config.c @@ -172,7 +172,8 @@ static bool enough_memory_for_hibernation(void) { r = get_status_field("/proc/meminfo", "\nSwapFree:", &swapfree); if (r < 0) { - log_error("Failed to retrieve SwapFree from /proc/meminfo: %s", strerror(-r)); + log_full(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, + "Failed to retrieve SwapFree from /proc/meminfo: %s", strerror(-r)); return false; } diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c index 4a4ed79c11..3511f3a3a4 100644 --- a/src/test/test-fileio.c +++ b/src/test/test-fileio.c @@ -232,12 +232,16 @@ static void test_executable_is_script(void) { static void test_status_field(void) { _cleanup_free_ char *t = NULL, *p = NULL, *s = NULL; unsigned long long total, buffers; + int r; assert_se(get_status_field("/proc/self/status", "\nThreads:", &t) == 0); puts(t); assert_se(streq(t, "1")); - assert_se(get_status_field("/proc/meminfo", "MemTotal:", &p) == 0); + r = get_status_field("/proc/meminfo", "MemTotal:", &p); + if (r == -ENOENT) + return; + assert(r == 0); puts(p); assert_se(safe_atollu(p, &total) == 0); -- cgit v1.2.1 From c32fc72f371535d29e0fce8c92694054c15427db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 15 Sep 2013 10:35:51 -0400 Subject: Remove duplicate entries from syscall list ARM syscall list includes SYS_OABI_SYSCALL_BASE and SYS_SYSCALL_BASE which were obsuring real syscall names. --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 7b7539a3a3..7318913d9a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1027,7 +1027,7 @@ BUILT_SOURCES += \ src/core/syscall-list.txt: Makefile $(AM_V_at)$(MKDIR_P) $(dir $@) - $(AM_V_GEN)$(CPP) $(CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) -dM -include sys/syscall.h - < /dev/null | $(AWK) '/^#define[ \t]+__NR_[^ ]+[ \t]+[0-9(]/ { sub(/__NR_/, "", $$2); print $$2; }' > $@ + $(AM_V_GEN)$(CPP) $(CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) -dM -include sys/syscall.h - < /dev/null | $(AWK) '/^#define[ \t]+__NR_[^ ]+[ \t]+[0-9(]/ { sub(/__NR_/, "", $$2); if ($$2 !~ /SYSCALL_BASE/) print $$2; }' > $@ src/core/syscall-from-name.gperf: src/core/syscall-list.txt Makefile $(AM_V_at)$(MKDIR_P) $(dir $@) -- cgit v1.2.1 From 1244d8d640a2644aa8dc8e588cd9c414b3d39163 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 15 Sep 2013 12:15:38 -0400 Subject: transaction.c: do not point users to logs when unit not found The logs are unlikely to contain any useful information in this case. Also, change "walked on cycle path" to "found dependency on", which is less technical and indicates the direction. With the old message, I was never sure if prior units depended on later ones, or vice versa. https://bugzilla.redhat.com/show_bug.cgi?id=996133 https://bugzilla.redhat.com/show_bug.cgi?id=997082 --- src/core/transaction.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/core/transaction.c b/src/core/transaction.c index 27efef7cc6..203070fa26 100644 --- a/src/core/transaction.c +++ b/src/core/transaction.c @@ -344,7 +344,7 @@ static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsi assert(!j->transaction_prev); /* Does a recursive sweep through the ordering graph, looking - * for a cycle. If we find cycle we try to break it. */ + * for a cycle. If we find a cycle we try to break it. */ /* Have we seen this before? */ if (j->generation == generation) { @@ -371,7 +371,7 @@ static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsi /* logging for j not k here here to provide consistent narrative */ log_info_unit(j->unit->id, - "Walked on cycle path to %s/%s", + "Found dependency on %s/%s", k->unit->id, job_type_to_string(k->type)); if (!delete && @@ -860,7 +860,7 @@ int transaction_add_job_and_dependencies( return -EINVAL; } - if (type != JOB_STOP && (unit->load_state == UNIT_ERROR || unit->load_state == UNIT_NOT_FOUND)) { + if (type != JOB_STOP && unit->load_state == UNIT_ERROR) { dbus_set_error(e, BUS_ERROR_LOAD_FAILED, "Unit %s failed to load: %s. " "See system logs and 'systemctl status %s' for details.", @@ -870,6 +870,14 @@ int transaction_add_job_and_dependencies( return -EINVAL; } + if (type != JOB_STOP && unit->load_state == UNIT_NOT_FOUND) { + dbus_set_error(e, BUS_ERROR_LOAD_FAILED, + "Unit %s failed to load: %s.", + unit->id, + strerror(-unit->load_error)); + return -EINVAL; + } + if (type != JOB_STOP && unit->load_state == UNIT_MASKED) { dbus_set_error(e, BUS_ERROR_MASKED, "Unit %s is masked.", unit->id); return -EADDRNOTAVAIL; -- cgit v1.2.1 From 4b549144d82ea0f368321d149215f577049fffa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 15 Sep 2013 22:26:56 -0400 Subject: Verify validity of session name when received from outside Only ASCII letters and digits are allowed. --- Makefile.am | 14 +++++++++++--- TODO | 3 --- src/login/login-shared.c | 8 ++++++++ src/login/login-shared.h | 3 +++ src/login/logind-dbus.c | 1 + src/login/logind-session.c | 1 + src/login/logind-session.h | 1 + src/login/logind.c | 6 ++++++ src/login/sd-login.c | 12 +++++++----- src/shared/cgroup-util.c | 4 +--- src/shared/def.h | 5 +++++ src/shared/env-util.c | 5 ++--- src/shared/replace-var.c | 3 ++- src/shared/unit-name.c | 5 ++--- 14 files changed, 50 insertions(+), 21 deletions(-) create mode 100644 src/login/login-shared.c create mode 100644 src/login/login-shared.h diff --git a/Makefile.am b/Makefile.am index 7318913d9a..f7bc5f36cc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2324,7 +2324,10 @@ if HAVE_ACL libudev_core_la_SOURCES += \ src/udev/udev-builtin-uaccess.c \ src/login/logind-acl.c \ - src/login/sd-login.c + src/login/sd-login.c \ + src/systemd/sd-login.h \ + src/login/login-shared.c \ + src/login/login-shared.h libudev_core_la_LIBADD += \ libsystemd-acl.la @@ -3759,7 +3762,9 @@ libsystemd_logind_core_la_SOURCES = \ src/login/logind-session-dbus.c \ src/login/logind-seat-dbus.c \ src/login/logind-user-dbus.c \ - src/login/logind-acl.h + src/login/logind-acl.h \ + src/login/login-shared.c \ + src/login/login-shared.h libsystemd_logind_core_la_CFLAGS = \ $(AM_CFLAGS) \ @@ -3860,7 +3865,10 @@ tests += \ test-login-tables libsystemd_login_la_SOURCES = \ - src/login/sd-login.c + src/login/sd-login.c \ + src/systemd/sd-login.h \ + src/login/login-shared.c \ + src/login/login-shared.h libsystemd_login_la_CFLAGS = \ $(AM_CFLAGS) \ diff --git a/TODO b/TODO index 9943b3e50d..bfeaa818ee 100644 --- a/TODO +++ b/TODO @@ -142,9 +142,6 @@ Features: * journald: make sure ratelimit is actually really per-service with the new cgroup changes -* libsystemd-logind: sd_session_is_active() and friends: verify - validity of session name before appending it to a path - * gparted needs to disable auto-activation of mount units somehow, or maybe we should stop doing auto-activation of this after boot entirely. https://bugzilla.gnome.org/show_bug.cgi?id=701676 diff --git a/src/login/login-shared.c b/src/login/login-shared.c new file mode 100644 index 0000000000..ff13c28861 --- /dev/null +++ b/src/login/login-shared.c @@ -0,0 +1,8 @@ +#include "login-shared.h" +#include "def.h" + +bool session_id_valid(const char *id) { + assert(id); + + return id + strspn(id, LETTERS DIGITS) == '\0'; +} diff --git a/src/login/login-shared.h b/src/login/login-shared.h new file mode 100644 index 0000000000..728ef0038f --- /dev/null +++ b/src/login/login-shared.h @@ -0,0 +1,3 @@ +#include + +bool session_id_valid(const char *id); diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 345df9f1cc..d052e74789 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -554,6 +554,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message) { * the audit data and let's better register a new * ID */ if (hashmap_get(m->sessions, id)) { + log_warning("Existing logind session ID %s used by new audit session, ignoring", id); audit_id = 0; free(id); diff --git a/src/login/logind-session.c b/src/login/logind-session.c index a726fb1bed..2d22a68b6e 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -41,6 +41,7 @@ Session* session_new(Manager *m, const char *id) { assert(m); assert(id); + assert(session_id_valid(id)); s = new0(Session, 1); if (!s) diff --git a/src/login/logind-session.h b/src/login/logind-session.h index edaae8d20a..9cf64850be 100644 --- a/src/login/logind-session.h +++ b/src/login/logind-session.h @@ -29,6 +29,7 @@ typedef enum KillWho KillWho; #include "logind.h" #include "logind-seat.h" #include "logind-user.h" +#include "login-shared.h" typedef enum SessionState { SESSION_OPENING, /* Session scope is being created */ diff --git a/src/login/logind.c b/src/login/logind.c index 9094567b8d..4ef92b8253 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -684,6 +684,12 @@ int manager_enumerate_sessions(Manager *m) { if (!dirent_is_file(de)) continue; + if (!session_id_valid(de->d_name)) { + log_warning("Invalid session file name '%s', ignoring.", de->d_name); + r = -EINVAL; + continue; + } + k = manager_add_session(m, de->d_name, &s); if (k < 0) { log_error("Failed to add session by file name %s: %s", de->d_name, strerror(-k)); diff --git a/src/login/sd-login.c b/src/login/sd-login.c index 8a7838d566..71d8c2942e 100644 --- a/src/login/sd-login.c +++ b/src/login/sd-login.c @@ -31,6 +31,7 @@ #include "sd-login.h" #include "strv.h" #include "fileio.h" +#include "login-shared.h" _public_ int sd_pid_get_session(pid_t pid, char **session) { if (pid < 0) @@ -226,17 +227,19 @@ static int file_of_session(const char *session, char **_p) { assert(_p); - if (session) + if (session) { + if (!session_id_valid(session)) + return -EINVAL; + p = strappend("/run/systemd/sessions/", session); - else { - char *buf; + } else { + _cleanup_free_ char *buf = NULL; r = sd_pid_get_session(0, &buf); if (r < 0) return r; p = strappend("/run/systemd/sessions/", buf); - free(buf); } if (!p) @@ -255,7 +258,6 @@ _public_ int sd_session_is_active(const char *session) { return r; r = parse_env_file(p, NEWLINE, "ACTIVE", &s, NULL); - if (r < 0) return r; diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index 1d545e0466..0bffebdac8 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -1511,9 +1511,7 @@ char *cg_unescape(const char *p) { } #define CONTROLLER_VALID \ - "0123456789" \ - "abcdefghijklmnopqrstuvwxyz" \ - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ + DIGITS LETTERS \ "_" bool cg_controller_is_valid(const char *p, bool allow_named) { diff --git a/src/shared/def.h b/src/shared/def.h index 5abb544247..edd0bcf7a4 100644 --- a/src/shared/def.h +++ b/src/shared/def.h @@ -33,3 +33,8 @@ #define SIGNALS_CRASH_HANDLER SIGSEGV,SIGILL,SIGFPE,SIGBUS,SIGQUIT,SIGABRT #define SIGNALS_IGNORE SIGPIPE + +#define DIGITS "0123456789" +#define LOWERCASE_LETTERS "abcdefghijklmnopqrstuvwxyz" +#define UPPERCASE_LETTERS "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +#define LETTERS LOWERCASE_LETTERS UPPERCASE_LETTERS diff --git a/src/shared/env-util.c b/src/shared/env-util.c index 6a52fb960d..5e29629efd 100644 --- a/src/shared/env-util.c +++ b/src/shared/env-util.c @@ -27,11 +27,10 @@ #include "utf8.h" #include "util.h" #include "env-util.h" +#include "def.h" #define VALID_CHARS_ENV_NAME \ - "0123456789" \ - "abcdefghijklmnopqrstuvwxyz" \ - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ + DIGITS LETTERS \ "_" #ifndef ARG_MAX diff --git a/src/shared/replace-var.c b/src/shared/replace-var.c index e11c57a43d..478fc43a38 100644 --- a/src/shared/replace-var.c +++ b/src/shared/replace-var.c @@ -24,6 +24,7 @@ #include "macro.h" #include "util.h" #include "replace-var.h" +#include "def.h" /* * Generic infrastructure for replacing @FOO@ style variables in @@ -40,7 +41,7 @@ static int get_variable(const char *b, char **r) { if (*b != '@') return 0; - k = strspn(b + 1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ_"); + k = strspn(b + 1, UPPERCASE_LETTERS "_"); if (k <= 0 || b[k+1] != '@') return 0; diff --git a/src/shared/unit-name.c b/src/shared/unit-name.c index 1baa6eb7e5..8f6c28e86a 100644 --- a/src/shared/unit-name.c +++ b/src/shared/unit-name.c @@ -26,11 +26,10 @@ #include "path-util.h" #include "util.h" #include "unit-name.h" +#include "def.h" #define VALID_CHARS \ - "0123456789" \ - "abcdefghijklmnopqrstuvwxyz" \ - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ + DIGITS LETTERS \ ":-_.\\" static const char* const unit_type_table[_UNIT_TYPE_MAX] = { -- cgit v1.2.1 From d8c8508bad097c5cc354b684866a5b7a83fce394 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Fri, 13 Sep 2013 12:42:12 +0200 Subject: build: check for build/link flags harder Use AC_LINK_IFELSE instead of AC_COMPILE_IFELSE to test for flags that might succeed during compilation but not during linking. An example is gcc compiled with libssp support but gnu-ld without it. In this case -fstack-protector works fine during compilation but fails during linking as several internal helpers are missing. --- m4/attributes.m4 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/m4/attributes.m4 b/m4/attributes.m4 index 7e080da65d..aa53ef2380 100644 --- a/m4/attributes.m4 +++ b/m4/attributes.m4 @@ -42,9 +42,9 @@ AC_DEFUN([CC_CHECK_FLAG_APPEND], [ AS_TR_SH([cc_cv_$2_$3]), [eval "AS_TR_SH([cc_save_$2])='${$2}'" eval "AS_TR_SH([$2])='-Werror $3'" - AC_COMPILE_IFELSE([AC_LANG_SOURCE([int a = 0; int main(void) { return a; } ])], - [eval "AS_TR_SH([cc_cv_$2_$3])='yes'"], - [eval "AS_TR_SH([cc_cv_$2_$3])='no'"]) + AC_LINK_IFELSE([AC_LANG_SOURCE([int a = 0; int main(void) { return a; } ])], + [eval "AS_TR_SH([cc_cv_$2_$3])='yes'"], + [eval "AS_TR_SH([cc_cv_$2_$3])='no'"]) eval "AS_TR_SH([$2])='$cc_save_$2'"]) AS_IF([eval test x$]AS_TR_SH([cc_cv_$2_$3])[ = xyes], -- cgit v1.2.1 From 3cf0f8f7e0b950b5f6d678f3e8b7f0fc0f52d4bf Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Mon, 16 Sep 2013 11:22:35 -0400 Subject: udev-rules: avoid erroring on trailing whitespace https://bugs.archlinux.org/task/36950 --- src/udev/udev-rules.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index f14158b500..6f8b127872 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -1068,6 +1068,12 @@ static int add_rule(struct udev_rules *rules, char *line, enum operation_type op; if (get_key(rules->udev, &linepos, &key, &op, &value) != 0) { + /* Avoid erroring on trailing whitespace. This is probably rare + * so save the work for the error case instead of always trying + * to strip the trailing whitespace with strstrip(). */ + while (isblank(*linepos)) + linepos++; + /* If we aren't at the end of the line, this is a parsing error. * Make a best effort to describe where the problem is. */ if (*linepos != '\n') { -- cgit v1.2.1 From 35375afec5aeffbbebe4e66f2728eec6ffcaecc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 16 Sep 2013 11:04:20 -0500 Subject: login: fix login_is_valid test --- Makefile.am | 10 +++++++++- src/login/login-shared.c | 23 ++++++++++++++++++++++- src/login/login-shared.h | 21 +++++++++++++++++++++ src/login/test-login-shared.c | 38 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 src/login/test-login-shared.c diff --git a/Makefile.am b/Makefile.am index f7bc5f36cc..4db064e7c2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3836,6 +3836,13 @@ test_login_LDADD = \ libsystemd-login-internal.la \ libsystemd-shared.la +test_login_shared_SOURCES = \ + src/login/test-login-shared.c + +test_login_shared_LDADD = \ + libsystemd-login-internal.la \ + libsystemd-shared.la + test_inhibit_SOURCES = \ src/login/test-inhibit.c @@ -3862,7 +3869,8 @@ manual_tests += \ test-inhibit tests += \ - test-login-tables + test-login-tables \ + test-login-shared libsystemd_login_la_SOURCES = \ src/login/sd-login.c \ diff --git a/src/login/login-shared.c b/src/login/login-shared.c index ff13c28861..054c77503b 100644 --- a/src/login/login-shared.c +++ b/src/login/login-shared.c @@ -1,8 +1,29 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Zbigniew Jędrzejewski-Szmek + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + #include "login-shared.h" #include "def.h" bool session_id_valid(const char *id) { assert(id); - return id + strspn(id, LETTERS DIGITS) == '\0'; + return id[0] && id[strspn(id, LETTERS DIGITS)] == '\0'; } diff --git a/src/login/login-shared.h b/src/login/login-shared.h index 728ef0038f..b2787c9c62 100644 --- a/src/login/login-shared.h +++ b/src/login/login-shared.h @@ -1,3 +1,24 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Zbigniew Jędrzejewski-Szmek + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + #include bool session_id_valid(const char *id); diff --git a/src/login/test-login-shared.c b/src/login/test-login-shared.c new file mode 100644 index 0000000000..2df60292bf --- /dev/null +++ b/src/login/test-login-shared.c @@ -0,0 +1,38 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Zbigniew Jędrzejewski-Szmek + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include "macro.h" +#include "login-shared.h" + +static void test_session_id_valid(void) { + assert_se(session_id_valid("c1")); + assert_se(session_id_valid("1234")); + + assert_se(!session_id_valid("1-2")); + assert_se(!session_id_valid("")); + assert_se(!session_id_valid("\tid")); +} + +int main(int argc, char* argv[]) { + test_session_id_valid(); + + return 0; +} -- cgit v1.2.1 From 6e1452d6f015ebca6801e497d12bc6c7c114386d Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Mon, 16 Sep 2013 14:25:44 -0500 Subject: keymap: Add Samsung Series 5 [Ultra] Also consolidate the wlan key into the "all Samsung" rule to avoid repetition. Thanks to Mauro Carvalho Chehab! https://bugzilla.redhat.com/show_bug.cgi?id=989103 --- hwdb/60-keyboard.hwdb | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index 53e83ad426..3862b4ca20 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -882,6 +882,8 @@ keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn* KEYBOARD_KEY_b1=!prog2 # Fn+F7 run Samsung Magic Doctor (keypressed event is generated twice) KEYBOARD_KEY_b3=!prog3 # Fn+F8 switch power mode (battery/dynamic/performance) KEYBOARD_KEY_b4=!wlan # Fn+F9 (X60P) + KEYBOARD_KEY_c5=!prog3 # Fn+F8 switch power mode (battery/dynamic/performance) + KEYBOARD_KEY_d5=!wlan # Fn+F12 wlan/airplane switch KEYBOARD_KEY_f7=!f22 # Fn+F10 Touchpad on KEYBOARD_KEY_f9=!f23 # Fn+F10 Touchpad off @@ -889,9 +891,18 @@ keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn* keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*300E[457]*:pvr* keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*200E[45]*:pvr* KEYBOARD_KEY_ce=! # Fn+F1 launch control setting - KEYBOARD_KEY_d5=! # Fn+F12 Wi-Fi toggle # Series 5 +keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*530U*:pvr* + KEYBOARD_KEY_ce=!prog1 # Fn+F1 launch settings + KEYBOARD_KEY_a8=! # Fn Lock - Function lock on + KEYBOARD_KEY_a9=! # Fn Lock - Function lock off + +keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*550P*:pvr* + KEYBOARD_KEY_ce=!prog1 # Fn+F1 launch settings + KEYBOARD_KEY_a8=! # Fn Lock - Function lock on + KEYBOARD_KEY_a9=! # Fn Lock - Function lock off + keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700Z*:pvr* KEYBOARD_KEY_ce=!prog1 # Fn+F1 launch settings KEYBOARD_KEY_a0=!mute # Fn+F6 mute @@ -900,7 +911,6 @@ keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700Z*:pvr* KEYBOARD_KEY_97=!kbdillumdown # Fn+F9 keyboard backlight down KEYBOARD_KEY_96=!kbdillumup # Fn+F10 keyboard backlight up KEYBOARD_KEY_b3=!prog3 # Fn+F11 fan/cooling mode changer - KEYBOARD_KEY_d5=!wlan # Fn+F12 wlan/airplane switch # Series 9 keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*90X3A*:pvr* @@ -936,9 +946,6 @@ keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700Z*:pvr* keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700T*:pvr* KEYBOARD_KEY_ad=leftmeta -keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn535U*:pvr* - KEYBOARD_KEY_d5=!wlan - ########################################################### # SONY ########################################################### -- cgit v1.2.1 From d2e2c03d87618688eae262a2f2f2d299bf62a4dd Mon Sep 17 00:00:00 2001 From: David Strauss Date: Mon, 16 Sep 2013 17:40:00 -0500 Subject: TODO spelling fix. --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index bfeaa818ee..8f944d8766 100644 --- a/TODO +++ b/TODO @@ -60,7 +60,7 @@ Features: * Move backlight and random-seed into /var/lib/systemd -* If we try to find a unit via a danglign symlink generate a clean +* If we try to find a unit via a dangling symlink generate a clean error. Currently we just ignore it and read the unit from the search path anyway. -- cgit v1.2.1 From 328b5bc96e452b67ae2eb3dee3a09ff3ce03f662 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Mon, 16 Sep 2013 19:09:36 -0400 Subject: Add YouCompleteMe configuration --- .ycm_extra_conf.py | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 .ycm_extra_conf.py diff --git a/.ycm_extra_conf.py b/.ycm_extra_conf.py new file mode 100644 index 0000000000..06a2344661 --- /dev/null +++ b/.ycm_extra_conf.py @@ -0,0 +1,81 @@ +import os +import ycm_core +from clang_helpers import PrepareClangFlags + +compilation_database_folder = '' + +flags = [ +'-include', +'./config.h', +'-I', +'/usr/include/dbus-1.0', +'-I', +'./src/shared', +'-Wall', +'-Wextra', +'-Werror', +'-Wno-long-long', +'-Wno-variadic-macros', +'-fexceptions', +'-DNDEBUG', +'-DUSE_CLANG_COMPLETER', +'-D_GNU_SOURCE', +'-std=c99', +] + +if compilation_database_folder: + database = ycm_core.CompilationDatabase(compilation_database_folder) +else: + database = None + + +def DirectoryOfThisScript(): + return os.path.dirname(os.path.abspath(__file__)) + + +def MakeRelativePathsInFlagsAbsolute(flags, working_directory): + if not working_directory: + return flags + new_flags = [] + make_next_absolute = False + path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ] + for flag in flags: + new_flag = flag + + if make_next_absolute: + make_next_absolute = False + if not flag.startswith('/'): + new_flag = os.path.join(working_directory, flag) + + for path_flag in path_flags: + if flag == path_flag: + make_next_absolute = True + break + + if flag.startswith(path_flag): + path = flag[ len(path_flag): ] + new_flag = path_flag + os.path.join(working_directory, path) + break + + if new_flag: + new_flags.append(new_flag) + return new_flags + + +def FlagsForFile(filename): + if database: + compilation_info = database.GetCompilationInfoForFile(filename) + final_flags = PrepareClangFlags( + MakeRelativePathsInFlagsAbsolute( + compilation_info.compiler_flags_, + compilation_info.compiler_working_dir_), + filename) + + else: + relative_to = DirectoryOfThisScript() + final_flags = MakeRelativePathsInFlagsAbsolute(flags, relative_to) + + return { + 'flags': final_flags, + 'do_cache': True + } -- cgit v1.2.1 From 0aafd43d235982510d1c40564079f7bcec0c7c19 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 17 Sep 2013 10:01:08 -0500 Subject: update TODO --- TODO | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/TODO b/TODO index 8f944d8766..1ca3142529 100644 --- a/TODO +++ b/TODO @@ -58,6 +58,15 @@ CGroup Rework Completion: Features: +* Get rid of MemorySoftLimit= + +* After coming back from hibernation reset hibernation swap partition + +* mounts: do not test each mount unit against each other mount unit to + determine prefixes. Instead generated list of all prefixes and + interate through that to bring down complexity from O(n^2) to O(n) + when loading units + * Move backlight and random-seed into /var/lib/systemd * If we try to find a unit via a dangling symlink generate a clean -- cgit v1.2.1 From 19f6d710772305610b928bc2678b9d77fe11e770 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 17 Sep 2013 10:03:46 -0500 Subject: specifier: rework specifier calls to return proper error message Previously the specifier calls could only indicate OOM by returning NULL. With this change they will return negative errno-style error codes like everything else. --- src/core/load-fragment.c | 184 ++++++++++++++++++++++++---------------- src/core/service.c | 6 +- src/core/socket.c | 6 +- src/core/unit-printf.c | 200 +++++++++++++++++++++++++++++--------------- src/core/unit-printf.h | 6 +- src/shared/install-printf.c | 54 ++++++++---- src/shared/install-printf.h | 2 +- src/shared/install.c | 25 +++--- src/shared/specifier.c | 105 ++++++++++++++--------- src/shared/specifier.h | 14 ++-- src/test/test-strv.c | 16 +++- src/test/test-unit-file.c | 7 +- src/test/test-unit-name.c | 8 +- 13 files changed, 395 insertions(+), 238 deletions(-) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index f4a268c1ef..cfc6f078a6 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -99,9 +99,12 @@ int config_parse_unit_deps(const char* unit, if (!t) return log_oom(); - k = unit_name_printf(u, t); - if (!k) - return log_oom(); + r = unit_name_printf(u, t, &k); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, -r, + "Failed to resolve specifiers, ignoring: %s", strerror(-r)); + continue; + } r = unit_add_dependency_by_name(u, d, k, NULL, true); if (r < 0) @@ -124,16 +127,17 @@ int config_parse_unit_string_printf(const char *unit, Unit *u = userdata; _cleanup_free_ char *k = NULL; + int r; assert(filename); assert(lvalue); assert(rvalue); assert(u); - k = unit_full_printf(u, rvalue); - if (!k) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Failed to resolve unit specifiers on %s. Ignoring.", rvalue); + r = unit_full_printf(u, rvalue, &k); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, -r, + "Failed to resolve unit specifiers on %s, ignoring: %s", rvalue, strerror(-r)); return config_parse_string(unit, filename, line, section, lvalue, ltype, k ? k : rvalue, data, userdata); @@ -151,16 +155,17 @@ int config_parse_unit_strv_printf(const char *unit, Unit *u = userdata; _cleanup_free_ char *k = NULL; + int r; assert(filename); assert(lvalue); assert(rvalue); assert(u); - k = unit_full_printf(u, rvalue); - if (!k) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Failed to resolve unit specifiers on %s. Ignoring.", rvalue); + r = unit_full_printf(u, rvalue, &k); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, -r, + "Failed to resolve unit specifiers on %s, ignoring: %s", rvalue, strerror(-r)); return config_parse_strv(unit, filename, line, section, lvalue, ltype, k ? k : rvalue, data, userdata); @@ -178,16 +183,17 @@ int config_parse_unit_path_printf(const char *unit, Unit *u = userdata; _cleanup_free_ char *k = NULL; + int r; assert(filename); assert(lvalue); assert(rvalue); assert(u); - k = unit_full_printf(u, rvalue); - if (!k) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Failed to resolve unit specifiers on %s. Ignoring.", rvalue); + r = unit_full_printf(u, rvalue, &k); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, -r, + "Failed to resolve unit specifiers on %s, ignoring: %s", rvalue, strerror(-r)); return config_parse_path(unit, filename, line, section, lvalue, ltype, k ? k : rvalue, data, userdata); @@ -205,6 +211,7 @@ int config_parse_socket_listen(const char *unit, SocketPort *p, *tail; Socket *s; + int r; assert(filename); assert(lvalue); @@ -226,32 +233,31 @@ int config_parse_socket_listen(const char *unit, if (ltype != SOCKET_SOCKET) { p->type = ltype; - p->path = unit_full_printf(UNIT(s), rvalue); - if (!p->path) { + r = unit_full_printf(UNIT(s), rvalue, &p->path); + if (r < 0) { p->path = strdup(rvalue); if (!p->path) { free(p); return log_oom(); } else - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Failed to resolve unit specifiers on %s. Ignoring.", rvalue); + log_syntax(unit, LOG_ERR, filename, line, -r, + "Failed to resolve unit specifiers on %s, ignoring: %s", rvalue, strerror(-r)); } path_kill_slashes(p->path); } else if (streq(lvalue, "ListenNetlink")) { _cleanup_free_ char *k = NULL; - int r; p->type = SOCKET_SOCKET; - k = unit_full_printf(UNIT(s), rvalue); - if (!k) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Failed to resolve unit specifiers on %s. Ignoring.", rvalue); + r = unit_full_printf(UNIT(s), rvalue, &k); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, -r, + "Failed to resolve unit specifiers on %s, ignoring: %s", rvalue, strerror(-r)); r = socket_address_parse_netlink(&p->address, k ? k : rvalue); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, + log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to parse address value, ignoring: %s", rvalue); free(p); return 0; @@ -259,17 +265,16 @@ int config_parse_socket_listen(const char *unit, } else { _cleanup_free_ char *k = NULL; - int r; p->type = SOCKET_SOCKET; - k = unit_full_printf(UNIT(s), rvalue); - if (!k) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Failed to resolve unit specifiers on %s. Ignoring.", rvalue); + r = unit_full_printf(UNIT(s), rvalue, &k); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, -r, + "Failed to resolve unit specifiers on %s, ignoring: %s", rvalue, strerror(-r)); r = socket_address_parse(&p->address, k ? k : rvalue); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, + log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to parse address value, ignoring: %s", rvalue); free(p); return 0; @@ -1230,11 +1235,12 @@ int config_parse_trigger_unit( return 0; } - p = unit_name_printf(u, rvalue); - if (!p) - return log_oom(); + r = unit_name_printf(u, rvalue, &p); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, -r, + "Failed to resolve specifiers, ignoring: %s", strerror(-r)); - type = unit_name_to_type(p); + type = unit_name_to_type(p ?: rvalue); if (type < 0) { log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Unit type not valid, ignoring: %s", rvalue); @@ -1247,10 +1253,10 @@ int config_parse_trigger_unit( return 0; } - r = unit_add_two_dependencies_by_name(u, UNIT_BEFORE, UNIT_TRIGGERS, p, NULL, true); + r = unit_add_two_dependencies_by_name(u, UNIT_BEFORE, UNIT_TRIGGERS, p ?: rvalue, NULL, true); if (r < 0) { log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to add trigger on %s, ignoring: %s", p, strerror(-r)); + "Failed to add trigger on %s, ignoring: %s", p ?: rvalue, strerror(-r)); return 0; } @@ -1271,6 +1277,7 @@ int config_parse_path_spec(const char *unit, PathSpec *s; PathType b; _cleanup_free_ char *k = NULL; + int r; assert(filename); assert(lvalue); @@ -1290,13 +1297,13 @@ int config_parse_path_spec(const char *unit, return 0; } - k = unit_full_printf(UNIT(p), rvalue); - if (!k) { + r = unit_full_printf(UNIT(p), rvalue, &k); + if (r < 0) { k = strdup(rvalue); if (!k) return log_oom(); else - log_syntax(unit, LOG_ERR, filename, line, EINVAL, + log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to resolve unit specifiers on %s. Ignoring.", rvalue); } @@ -1344,19 +1351,20 @@ int config_parse_socket_service(const char *unit, dbus_error_init(&error); - p = unit_name_printf(UNIT(s), rvalue); - if (!p) - return log_oom(); + r = unit_name_printf(UNIT(s), rvalue, &p); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, -r, + "Failed to resolve specifiers, ignoring: %s", rvalue); - if (!endswith(p, ".service")) { + if (!endswith(p ?: rvalue, ".service")) { log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Unit must be of type service, ignoring: %s", rvalue); return 0; } - r = manager_load_unit(UNIT(s)->manager, p, NULL, &error, &x); + r = manager_load_unit(UNIT(s)->manager, p ?: rvalue, NULL, &error, &x); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to load unit %s, ignoring: %s", rvalue, bus_error(&error, r)); dbus_error_free(&error); @@ -1395,23 +1403,24 @@ int config_parse_service_sockets(const char *unit, if (!t) return log_oom(); - k = unit_name_printf(UNIT(s), t); - if (!k) - return log_oom(); + r = unit_name_printf(UNIT(s), t, &k); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, -r, + "Failed to resolve specifiers, ignoring: %s", strerror(-r)); - if (!endswith(k, ".socket")) { + if (!endswith(k ?: t, ".socket")) { log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Unit must be of type socket, ignoring: %s", k); + "Unit must be of type socket, ignoring: %s", k ?: t); continue; } - r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_WANTS, UNIT_AFTER, k, NULL, true); + r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_WANTS, UNIT_AFTER, k ?: t, NULL, true); if (r < 0) log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to add dependency on %s, ignoring: %s", - k, strerror(-r)); + k ?: t, strerror(-r)); - r = unit_add_dependency_by_name(UNIT(s), UNIT_TRIGGERED_BY, k, NULL, true); + r = unit_add_dependency_by_name(UNIT(s), UNIT_TRIGGERED_BY, k ?: t, NULL, true); if (r < 0) return r; } @@ -1463,7 +1472,8 @@ int config_parse_unit_env_file(const char *unit, char ***env = data; Unit *u = userdata; - _cleanup_free_ char *s = NULL; + _cleanup_free_ char *n = NULL; + const char *s; int r; assert(filename); @@ -1478,10 +1488,12 @@ int config_parse_unit_env_file(const char *unit, return 0; } - s = unit_full_printf(u, rvalue); - if (!s) - return log_oom(); + r = unit_full_printf(u, rvalue, &n); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to resolve specifiers, ignoring: %s", rvalue); + s = n ?: rvalue; if (!path_is_absolute(s[0] == '-' ? s + 1 : s)) { log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Path '%s' is not absolute, ignoring.", s); @@ -1509,6 +1521,7 @@ int config_parse_environ(const char *unit, char*** env = data, *w, *state; size_t l; _cleanup_free_ char *k = NULL; + int r; assert(filename); assert(lvalue); @@ -1522,11 +1535,15 @@ int config_parse_environ(const char *unit, return 0; } - if (u) - k = unit_full_printf(u, rvalue); - else - k = strdup(rvalue); + if (u) { + r = unit_full_printf(u, rvalue, &k); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, -r, + "Failed to resolve specifiers, ignoring: %s", rvalue); + } + if (!k) + k = strdup(rvalue); if (!k) return log_oom(); @@ -1598,6 +1615,7 @@ int config_parse_unit_condition_path(const char *unit, bool trigger, negate; Condition *c; _cleanup_free_ char *p = NULL; + int r; assert(filename); assert(lvalue); @@ -1619,9 +1637,15 @@ int config_parse_unit_condition_path(const char *unit, if (negate) rvalue++; - p = unit_full_printf(u, rvalue); - if (!p) - return log_oom(); + r = unit_full_printf(u, rvalue, &p); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, -r, + "Failed to resolve specifiers, ignoring: %s", rvalue); + if (!p) { + p = strdup(rvalue); + if (!p) + return log_oom(); + } if (!path_is_absolute(p)) { log_syntax(unit, LOG_ERR, filename, line, EINVAL, @@ -1652,6 +1676,7 @@ int config_parse_unit_condition_string(const char *unit, bool trigger, negate; Condition *c; _cleanup_free_ char *s = NULL; + int r; assert(filename); assert(lvalue); @@ -1673,9 +1698,15 @@ int config_parse_unit_condition_string(const char *unit, if (negate) rvalue++; - s = unit_full_printf(u, rvalue); - if (!s) - return log_oom(); + r = unit_full_printf(u, rvalue, &s); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, -r, + "Failed to resolve specifiers, ignoring: %s", rvalue); + if (!s) { + s = strdup(rvalue); + if (!s) + return log_oom(); + } c = condition_new(cond, s, trigger, negate); if (!c) @@ -1929,21 +1960,26 @@ int config_parse_unit_slice( assert(rvalue); assert(u); - k = unit_name_printf(u, rvalue); - if (!k) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, + r = unit_name_printf(u, rvalue, &k); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to resolve unit specifiers on %s. Ignoring.", rvalue); + if (!k) { + k = strdup(rvalue); + if (!k) + return log_oom(); + } - r = manager_load_unit(u->manager, k ? k : rvalue, NULL, NULL, &slice); + r = manager_load_unit(u->manager, k, NULL, NULL, &slice); if (r < 0) { log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to load slice unit %s. Ignoring.", k ? k : rvalue); + "Failed to load slice unit %s. Ignoring.", k); return 0; } if (slice->type != UNIT_SLICE) { log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Slice unit %s is not a slice. Ignoring.", k ? k : rvalue); + "Slice unit %s is not a slice. Ignoring.", k); return 0; } diff --git a/src/core/service.c b/src/core/service.c index 246a86e23f..cc61b546fc 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -1765,11 +1765,9 @@ static int service_spawn( } else unit_unwatch_timer(UNIT(s), &s->timer_watch); - argv = unit_full_printf_strv(UNIT(s), c->argv); - if (!argv) { - r = -ENOMEM; + r = unit_full_printf_strv(UNIT(s), c->argv, &argv); + if (r < 0) goto fail; - } our_env = new0(char*, 5); if (!our_env) { diff --git a/src/core/socket.c b/src/core/socket.c index 2130e48686..46a73e0108 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -1226,11 +1226,9 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) { if (r < 0) goto fail; - argv = unit_full_printf_strv(UNIT(s), c->argv); - if (!argv) { - r = -ENOMEM; + r = unit_full_printf_strv(UNIT(s), c->argv, &argv); + if (r < 0) goto fail; - } r = exec_spawn(c, argv, diff --git a/src/core/unit-printf.c b/src/core/unit-printf.c index ffc203dd92..1a29a986e9 100644 --- a/src/core/unit-printf.c +++ b/src/core/unit-printf.c @@ -30,98 +30,158 @@ #include "cgroup-util.h" #include "special.h" -static char *specifier_prefix_and_instance(char specifier, void *data, void *userdata) { +static int specifier_prefix_and_instance(char specifier, void *data, void *userdata, char **ret) { Unit *u = userdata; + char *n; + assert(u); - return unit_name_to_prefix_and_instance(u->id); + n = unit_name_to_prefix_and_instance(u->id); + if (!n) + return -ENOMEM; + + *ret = n; + return 0; } -static char *specifier_prefix(char specifier, void *data, void *userdata) { +static int specifier_prefix(char specifier, void *data, void *userdata, char **ret) { Unit *u = userdata; + char *n; + assert(u); - return unit_name_to_prefix(u->id); + n = unit_name_to_prefix(u->id); + if (!n) + return -ENOMEM; + + *ret = n; + return 0; } -static char *specifier_prefix_unescaped(char specifier, void *data, void *userdata) { +static int specifier_prefix_unescaped(char specifier, void *data, void *userdata, char **ret) { Unit *u = userdata; - char *p, *r; + _cleanup_free_ char *p = NULL; + char *n; assert(u); p = unit_name_to_prefix(u->id); if (!p) - return NULL; + return -ENOMEM; - r = unit_name_unescape(p); - free(p); + n = unit_name_unescape(p); + if (!n) + return -ENOMEM; - return r; + *ret = n; + return 0; } -static char *specifier_instance_unescaped(char specifier, void *data, void *userdata) { +static int specifier_instance_unescaped(char specifier, void *data, void *userdata, char **ret) { Unit *u = userdata; + char *n; + assert(u); if (u->instance) - return unit_name_unescape(u->instance); + n = unit_name_unescape(u->instance); + else + n = strdup(""); + + if (!n) + return -ENOMEM; - return strdup(""); + *ret = n; + return 0; } -static char *specifier_filename(char specifier, void *data, void *userdata) { +static int specifier_filename(char specifier, void *data, void *userdata, char **ret) { Unit *u = userdata; + char *n; + assert(u); if (u->instance) - return unit_name_path_unescape(u->instance); + n = unit_name_path_unescape(u->instance); + else + n = unit_name_to_path(u->id); - return unit_name_to_path(u->id); + if (!n) + return -ENOMEM; + + *ret = n; + return 0; } -static char *specifier_cgroup(char specifier, void *data, void *userdata) { +static int specifier_cgroup(char specifier, void *data, void *userdata, char **ret) { Unit *u = userdata; + char *n; + assert(u); - return unit_default_cgroup_path(u); + n = unit_default_cgroup_path(u); + if (!n) + return -ENOMEM; + + *ret = n; + return 0; } -static char *specifier_cgroup_root(char specifier, void *data, void *userdata) { - _cleanup_free_ char *p = NULL; +static int specifier_cgroup_root(char specifier, void *data, void *userdata, char **ret) { Unit *u = userdata; const char *slice; + char *n; int r; assert(u); slice = unit_slice_name(u); if (specifier == 'R' || !slice) - return strdup(u->manager->cgroup_root); + n = strdup(u->manager->cgroup_root); + else { + _cleanup_free_ char *p = NULL; - r = cg_slice_to_path(slice, &p); - if (r < 0) - return NULL; + r = cg_slice_to_path(slice, &p); + if (r < 0) + return r; + + n = strjoin(u->manager->cgroup_root, "/", p, NULL); + if (!n) + return -ENOMEM; + } - return strjoin(u->manager->cgroup_root, "/", p, NULL); + *ret = n; + return 0; } -static char *specifier_runtime(char specifier, void *data, void *userdata) { +static int specifier_runtime(char specifier, void *data, void *userdata, char **ret) { Unit *u = userdata; + char *n = NULL; + assert(u); if (u->manager->running_as == SYSTEMD_USER) { const char *e; e = getenv("XDG_RUNTIME_DIR"); - if (e) - return strdup(e); + if (e) { + n = strdup(e); + if (!n) + return -ENOMEM; + } } - return strdup("/run"); + if (!n) { + n = strdup("/run"); + if (!n) + return -ENOMEM; + } + + *ret = n; + return 0; } -static char *specifier_user_name(char specifier, void *data, void *userdata) { +static int specifier_user_name(char specifier, void *data, void *userdata, char **ret) { Unit *u = userdata; ExecContext *c; int r; @@ -143,26 +203,31 @@ static char *specifier_user_name(char specifier, void *data, void *userdata) { /* fish username from passwd */ r = get_user_creds(&username, &uid, NULL, NULL, NULL); if (r < 0) - return NULL; + return r; switch (specifier) { case 'U': if (asprintf(&printed, "%d", uid) < 0) - return NULL; + return -ENOMEM; break; case 'u': printed = strdup(username); break; } - return printed; + if (!printed) + return -ENOMEM; + + *ret = printed; + return 0; } -static char *specifier_user_home(char specifier, void *data, void *userdata) { +static int specifier_user_home(char specifier, void *data, void *userdata, char **ret) { Unit *u = userdata; ExecContext *c; int r; const char *username, *home; + char *n; assert(u); @@ -174,25 +239,31 @@ static char *specifier_user_home(char specifier, void *data, void *userdata) { r = get_home_dir(&h); if (r < 0) - return NULL; + return r; - return h; + *ret = h; + return 0; } username = c->user; r = get_user_creds(&username, NULL, NULL, &home, NULL); if (r < 0) - return NULL; + return r; - return strdup(home); + n = strdup(home); + if (!n) + return -ENOMEM; + + *ret = n; + return 0; } -static char *specifier_user_shell(char specifier, void *data, void *userdata) { +static int specifier_user_shell(char specifier, void *data, void *userdata, char **ret) { Unit *u = userdata; ExecContext *c; int r; const char *username, *shell; - char *ret; + char *n; assert(u); @@ -205,27 +276,18 @@ static char *specifier_user_shell(char specifier, void *data, void *userdata) { /* return /bin/sh for root, otherwise the value from passwd */ r = get_user_creds(&username, NULL, NULL, NULL, &shell); - if (r < 0) { - log_warning_unit(u->id, - "Failed to determine shell: %s", - strerror(-r)); - return NULL; - } - - if (!path_is_absolute(shell)) { - log_warning_unit(u->id, - "Shell %s is not absolute, ignoring.", - shell); - } + if (r < 0) + return r; - ret = strdup(shell); - if (!ret) - log_oom(); + n = strdup(shell); + if (!n) + return -ENOMEM; - return ret; + *ret = n; + return 0; } -char *unit_name_printf(Unit *u, const char* format) { +int unit_name_printf(Unit *u, const char* format, char **ret) { /* * This will use the passed string as format string and @@ -247,11 +309,12 @@ char *unit_name_printf(Unit *u, const char* format) { assert(u); assert(format); + assert(ret); - return specifier_printf(format, table, u); + return specifier_printf(format, table, u, ret); } -char *unit_full_printf(Unit *u, const char *format) { +int unit_full_printf(Unit *u, const char *format, char **ret) { /* This is similar to unit_name_printf() but also supports * unescaping. Also, adds a couple of additional codes: @@ -296,14 +359,17 @@ char *unit_full_printf(Unit *u, const char *format) { {} }; + assert(u); assert(format); + assert(ret); - return specifier_printf(format, table, u); + return specifier_printf(format, table, u, ret); } -char **unit_full_printf_strv(Unit *u, char **l) { +int unit_full_printf_strv(Unit *u, char **l, char ***ret) { size_t n; char **r, **i, **j; + int q; /* Applies unit_full_printf to every entry in l */ @@ -312,22 +378,22 @@ char **unit_full_printf_strv(Unit *u, char **l) { n = strv_length(l); r = new(char*, n+1); if (!r) - return NULL; + return -ENOMEM; for (i = l, j = r; *i; i++, j++) { - *j = unit_full_printf(u, *i); - if (!*j) + q = unit_full_printf(u, *i, j); + if (q < 0) goto fail; } *j = NULL; - return r; + *ret = r; + return 0; fail: for (j--; j >= r; j--) free(*j); free(r); - - return NULL; + return q; } diff --git a/src/core/unit-printf.h b/src/core/unit-printf.h index d2f4ccd178..51acad63e9 100644 --- a/src/core/unit-printf.h +++ b/src/core/unit-printf.h @@ -23,6 +23,6 @@ #include "unit.h" -char *unit_name_printf(Unit *u, const char* text); -char *unit_full_printf(Unit *u, const char *text); -char **unit_full_printf_strv(Unit *u, char **l); +int unit_name_printf(Unit *u, const char* text, char **ret); +int unit_full_printf(Unit *u, const char *text, char **ret); +int unit_full_printf_strv(Unit *u, char **l, char ***ret); diff --git a/src/shared/install-printf.c b/src/shared/install-printf.c index 1157ea989b..1ee1243f4d 100644 --- a/src/shared/install-printf.c +++ b/src/shared/install-printf.c @@ -27,21 +27,35 @@ #include "util.h" #include "install-printf.h" -static char *specifier_prefix_and_instance(char specifier, void *data, void *userdata) { +static int specifier_prefix_and_instance(char specifier, void *data, void *userdata, char **ret) { InstallInfo *i = userdata; + char *n; + assert(i); - return unit_name_to_prefix_and_instance(i->name); + n = unit_name_to_prefix_and_instance(i->name); + if (!n) + return -ENOMEM; + + *ret = n; + return 0; } -static char *specifier_prefix(char specifier, void *data, void *userdata) { +static int specifier_prefix(char specifier, void *data, void *userdata, char **ret) { InstallInfo *i = userdata; + char *n; + assert(i); - return unit_name_to_prefix(i->name); + n = unit_name_to_prefix(i->name); + if (!n) + return -ENOMEM; + + *ret = n; + return 0; } -static char *specifier_instance(char specifier, void *data, void *userdata) { +static int specifier_instance(char specifier, void *data, void *userdata, char **ret) { InstallInfo *i = userdata; char *instance; int r; @@ -50,14 +64,19 @@ static char *specifier_instance(char specifier, void *data, void *userdata) { r = unit_name_to_instance(i->name, &instance); if (r < 0) - return NULL; - if (instance != NULL) - return instance; - else - return strdup(""); + return r; + + if (!instance) { + instance = strdup(""); + if (!instance) + return -ENOMEM; + } + + *ret = instance; + return 0; } -static char *specifier_user_name(char specifier, void *data, void *userdata) { +static int specifier_user_name(char specifier, void *data, void *userdata, char **ret) { InstallInfo *i = userdata; const char *username; _cleanup_free_ char *tmp = NULL; @@ -82,18 +101,20 @@ static char *specifier_user_name(char specifier, void *data, void *userdata) { r = get_user_creds(&username, &uid, NULL, NULL, NULL); if (r < 0) - return NULL; + return r; if (asprintf(&printed, "%d", uid) < 0) - return NULL; + return -ENOMEM; break; }} - return printed; + + *ret = printed; + return 0; } -char *install_full_printf(InstallInfo *i, const char *format) { +int install_full_printf(InstallInfo *i, const char *format, char **ret) { /* This is similar to unit_full_printf() but does not support * anything path-related. @@ -129,6 +150,7 @@ char *install_full_printf(InstallInfo *i, const char *format) { assert(i); assert(format); + assert(ret); - return specifier_printf(format, table, i); + return specifier_printf(format, table, i, ret); } diff --git a/src/shared/install-printf.h b/src/shared/install-printf.h index 46f5294d21..6ffa488b1b 100644 --- a/src/shared/install-printf.h +++ b/src/shared/install-printf.h @@ -22,4 +22,4 @@ #pragma once #include "install.h" -char *install_full_printf(InstallInfo *i, const char *format); +int install_full_printf(InstallInfo *i, const char *format, char **ret); diff --git a/src/shared/install.c b/src/shared/install.c index 07e06c425f..9722ed4e1c 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -967,14 +967,15 @@ static int config_parse_user(const char *unit, InstallInfo *i = data; char* printed; + int r; assert(filename); assert(lvalue); assert(rvalue); - printed = install_full_printf(i, rvalue); - if (!printed) - return -ENOMEM; + r = install_full_printf(i, rvalue, &printed); + if (r < 0) + return r; free(i->user); i->user = printed; @@ -1200,9 +1201,9 @@ static int install_info_symlink_alias( STRV_FOREACH(s, i->aliases) { _cleanup_free_ char *alias_path = NULL, *dst = NULL; - dst = install_full_printf(i, *s); - if (!dst) - return -ENOMEM; + q = install_full_printf(i, *s, &dst); + if (q < 0) + return q; alias_path = path_make_absolute(dst, config_path); if (!alias_path) @@ -1232,9 +1233,9 @@ static int install_info_symlink_wants( STRV_FOREACH(s, i->wanted_by) { _cleanup_free_ char *path = NULL, *dst = NULL; - dst = install_full_printf(i, *s); - if (!dst) - return -ENOMEM; + q = install_full_printf(i, *s, &dst); + if (q < 0) + return q; if (!unit_name_is_valid(dst, true)) { r = -EINVAL; @@ -1269,9 +1270,9 @@ static int install_info_symlink_requires( STRV_FOREACH(s, i->required_by) { _cleanup_free_ char *path = NULL, *dst = NULL; - dst = install_full_printf(i, *s); - if (!dst) - return -ENOMEM; + q = install_full_printf(i, *s, &dst); + if (q < 0) + return q; if (!unit_name_is_valid(dst, true)) { r = -EINVAL; diff --git a/src/shared/specifier.c b/src/shared/specifier.c index bb8859fdfd..8fbf6db5df 100644 --- a/src/shared/specifier.c +++ b/src/shared/specifier.c @@ -32,21 +32,22 @@ * */ -char *specifier_printf(const char *text, const Specifier table[], void *userdata) { - char *r, *t; +int specifier_printf(const char *text, const Specifier table[], void *userdata, char **_ret) { + char *ret, *t; const char *f; bool percent = false; size_t l; + int r; assert(text); assert(table); l = strlen(text); - r = new(char, l+1); - if (!r) - return NULL; + ret = new(char, l+1); + if (!ret) + return -ENOMEM; - t = r; + t = ret; for (f = text; *f; f++, l--) { @@ -61,32 +62,31 @@ char *specifier_printf(const char *text, const Specifier table[], void *userdata break; if (i->lookup) { - char *n, *w; + _cleanup_free_ char *w = NULL; + char *n; size_t k, j; - w = i->lookup(i->specifier, i->data, userdata); - if (!w) { - free(r); - return NULL; + r = i->lookup(i->specifier, i->data, userdata, &w); + if (r < 0) { + free(ret); + return r; } - j = t - r; + j = t - ret; k = strlen(w); n = new(char, j + k + l + 1); if (!n) { - free(r); - free(w); - return NULL; + free(ret); + return -ENOMEM; } - memcpy(n, r, j); + memcpy(n, ret, j); memcpy(n + j, w, k); - free(r); - free(w); + free(ret); - r = n; + ret = n; t = n + j + k; } else { *(t++) = '%'; @@ -102,58 +102,81 @@ char *specifier_printf(const char *text, const Specifier table[], void *userdata } *t = 0; - return r; + *_ret = ret; + return 0; } /* Generic handler for simple string replacements */ -char* specifier_string(char specifier, void *data, void *userdata) { - return strdup(strempty(data)); +int specifier_string(char specifier, void *data, void *userdata, char **ret) { + char *n; + + n = strdup(strempty(data)); + if (!n) + return -ENOMEM; + + *ret = n; + return 0; } -char *specifier_machine_id(char specifier, void *data, void *userdata) { +int specifier_machine_id(char specifier, void *data, void *userdata, char **ret) { sd_id128_t id; - char *buf; + char *n; int r; r = sd_id128_get_machine(&id); if (r < 0) - return NULL; + return r; - buf = new(char, 33); - if (!buf) - return NULL; + n = new(char, 33); + if (!n) + return -ENOMEM; - return sd_id128_to_string(id, buf); + *ret = sd_id128_to_string(id, n); + return 0; } -char *specifier_boot_id(char specifier, void *data, void *userdata) { +int specifier_boot_id(char specifier, void *data, void *userdata, char **ret) { sd_id128_t id; - char *buf; + char *n; int r; r = sd_id128_get_boot(&id); if (r < 0) - return NULL; + return r; - buf = new(char, 33); - if (!buf) - return NULL; + n = new(char, 33); + if (!n) + return -ENOMEM; - return sd_id128_to_string(id, buf); + *ret = sd_id128_to_string(id, n); + return 0; } -char *specifier_host_name(char specifier, void *data, void *userdata) { - return gethostname_malloc(); +int specifier_host_name(char specifier, void *data, void *userdata, char **ret) { + char *n; + + n = gethostname_malloc(); + if (!n) + return -ENOMEM; + + *ret = n; + return 0; } -char *specifier_kernel_release(char specifier, void *data, void *userdata) { +int specifier_kernel_release(char specifier, void *data, void *userdata, char **ret) { struct utsname uts; + char *n; int r; r = uname(&uts); if (r < 0) - return NULL; + return -errno; + + n = strdup(uts.release); + if (!n) + return -ENOMEM; - return strdup(uts.release); + *ret = n; + return 0; } diff --git a/src/shared/specifier.h b/src/shared/specifier.h index d13e6406b6..fca206f665 100644 --- a/src/shared/specifier.h +++ b/src/shared/specifier.h @@ -21,7 +21,7 @@ along with systemd; If not, see . ***/ -typedef char* (*SpecifierCallback)(char specifier, void *data, void *userdata); +typedef int (*SpecifierCallback)(char specifier, void *data, void *userdata, char **ret); typedef struct Specifier { const char specifier; @@ -29,11 +29,11 @@ typedef struct Specifier { void *data; } Specifier; -char *specifier_printf(const char *text, const Specifier table[], void *userdata); +int specifier_printf(const char *text, const Specifier table[], void *userdata, char **ret); -char *specifier_string(char specifier, void *data, void *userdata); +int specifier_string(char specifier, void *data, void *userdata, char **ret); -char *specifier_machine_id(char specifier, void *data, void *userdata); -char *specifier_boot_id(char specifier, void *data, void *userdata); -char *specifier_host_name(char specifier, void *data, void *userdata); -char *specifier_kernel_release(char specifier, void *data, void *userdata); +int specifier_machine_id(char specifier, void *data, void *userdata, char **ret); +int specifier_boot_id(char specifier, void *data, void *userdata, char **ret); +int specifier_host_name(char specifier, void *data, void *userdata, char **ret); +int specifier_kernel_release(char specifier, void *data, void *userdata, char **ret); diff --git a/src/test/test-strv.c b/src/test/test-strv.c index 25bee22dfe..6513d2e07b 100644 --- a/src/test/test-strv.c +++ b/src/test/test-strv.c @@ -28,18 +28,30 @@ static void test_specifier_printf(void) { _cleanup_free_ char *w = NULL; + int r; const Specifier table[] = { { 'a', specifier_string, (char*) "AAAA" }, { 'b', specifier_string, (char*) "BBBB" }, + { 'm', specifier_machine_id, NULL }, + { 'B', specifier_boot_id, NULL }, + { 'H', specifier_host_name, NULL }, + { 'v', specifier_kernel_release, NULL }, { 0, NULL, NULL } }; - w = specifier_printf("xxx a=%a b=%b yyy", table, NULL); + r = specifier_printf("xxx a=%a b=%b yyy", table, NULL, &w); + assert_se(r >= 0); + assert_se(w); + puts(w); + assert_se(streq(w, "xxx a=AAAA b=BBBB yyy")); + free(w); + r = specifier_printf("machine=%m, boot=%B, host=%H, version=%v", table, NULL, &w); + assert_se(r >= 0); assert_se(w); - assert_se(streq(w, "xxx a=AAAA b=BBBB yyy")); + puts(w); } static const char* const input_table_multiple[] = { diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c index dc6bc55244..0413ae2117 100644 --- a/src/test/test-unit-file.c +++ b/src/test/test-unit-file.c @@ -302,17 +302,18 @@ static void test_install_printf(void) { _cleanup_free_ char *mid, *bid, *host; - assert_se((mid = specifier_machine_id('m', NULL, NULL))); - assert_se((bid = specifier_boot_id('b', NULL, NULL))); + assert_se(specifier_machine_id('m', NULL, NULL, &mid) >= 0 && mid); + assert_se(specifier_boot_id('b', NULL, NULL, &bid) >= 0 && bid); assert_se((host = gethostname_malloc())); #define expect(src, pattern, result) \ do { \ - _cleanup_free_ char *t = install_full_printf(&src, pattern); \ + _cleanup_free_ char *t = NULL; \ _cleanup_free_ char \ *d1 = strdup(i.name), \ *d2 = strdup(i.path), \ *d3 = strdup(i.user); \ + assert_se(install_full_printf(&src, pattern, &t) >= 0 || !result); \ memzero(i.name, strlen(i.name)); \ memzero(i.path, strlen(i.path)); \ memzero(i.user, strlen(i.user)); \ diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c index c17692b845..67ccdd4228 100644 --- a/src/test/test-unit-name.c +++ b/src/test/test-unit-name.c @@ -117,8 +117,8 @@ static int test_unit_printf(void) { _cleanup_free_ char *mid, *bid, *host, *root_uid; struct passwd *root; - assert_se((mid = specifier_machine_id('m', NULL, NULL))); - assert_se((bid = specifier_boot_id('b', NULL, NULL))); + assert_se(specifier_machine_id('m', NULL, NULL, &mid) >= 0 && mid); + assert_se(specifier_boot_id('b', NULL, NULL, &bid) >= 0 && bid); assert_se((host = gethostname_malloc())); assert_se((root = getpwnam("root"))); @@ -134,8 +134,8 @@ static int test_unit_printf(void) { #define expect(unit, pattern, expected) \ { \ char *e; \ - _cleanup_free_ char *t = \ - unit_full_printf(unit, pattern); \ + _cleanup_free_ char *t; \ + assert_se(unit_full_printf(unit, pattern, &t) >= 0); \ printf("result: %s\nexpect: %s\n", t, expected); \ if ((e = endswith(expected, "*"))) \ assert(strncmp(t, e, e-expected)); \ -- cgit v1.2.1 From 43638332c4236ac2db44b0524ea5ade4f918e602 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 15 Sep 2013 11:56:19 -0400 Subject: man: add a list of environment variables --- man/systemd.exec.xml | 138 ++++++++++++++++++++++++++++++++++++++++++--------- src/core/manager.c | 5 +- 2 files changed, 117 insertions(+), 26 deletions(-) diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 5721dc1553..ba4e808ddd 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -57,7 +57,7 @@ Description Unit configuration files for services, sockets, - mount points and swap devices share a subset of + mount points, and swap devices share a subset of configuration options which define the execution environment of spawned processes. @@ -76,27 +76,6 @@ configuration options are configured in the [Service], [Socket], [Mount], or [Swap] sections, depending on the unit type. - - Processes started by the system systemd instance - are executed in a clean environment in which only the - $PATH and $LANG - variables are set by default. In order to add - additional variables, see the - Environment= and - EnvironmentFile= options below. To - specify variables globally, see - DefaultEnvironment= in - systemd-system.conf5 - or the kernel option - systemd.setenv= in - systemd1. Processes - started by the user systemd instances inherit all - environment variables from the user systemd instance, - and have $HOME, - $USER, - $XDG_RUNTIME_DIR defined, among - others. In addition, $MANAGERPID - contains the PID of the user systemd instance. @@ -1005,6 +984,118 @@ + + Environment variables in spawned processes + + Processes started by the system are executed in + a clean environment in which select variables + listed below are set. System processes started by systemd + do not inherit variables from PID 1, but processes + started by user systemd instances inherit all + environment variables from the user systemd instance. + + + + + $PATH + + Colon-separated list + of directiories to use when launching + executables. Systemd uses a fixed + value of + /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin. + + + + + $LANG + + Locale. Can be set in + locale.conf5 + or on the kernel command line (see + systemd1 + and + kernel-command-line7). + + + + + $USER + $HOME + + User name and home + directory. Set for the units which + have User= set, + which includes user + systemd instances. + See + passwd5. + + + + + $XDG_RUNTIME_DIR + + The directory for volatile + state. Set for the user systemd + instance, and also in user sessions. + See + pam_systemd8. + + + + + $XDG_SESSION_ID + $XDG_SEAT + $XDG_VTNR + + The identifier of the + session, and the seat name, and + virtual terminal of the session. Set + by + pam_systemd8 + for login sessions. + $XDG_SEAT and + $XDG_VTNR will be + only set when attached to a seat and a + tty. + + + + $MANAGERPID + + The PID of the user + systemd instance, + set for processes spawned by it. + + + + + $LISTEN_FDS + $LISTEN_PID + + Information about file + descriptors passed to a service for + socket activation. See + sd_listen_fds3. + + + + + Additional variables may be configured by the + following means: for processes spawned in specific + units, use the Environment= and + EnvironmentFile= options above; to + specify variables globally, use + DefaultEnvironment= (see + systemd-system.conf5) + or the kernel option + systemd.setenv= (see + systemd1). Additional + variables may also be set through PAM, + c.f. pam_env8. + + See Also @@ -1018,7 +1109,8 @@ systemd.mount5, systemd.kill5, systemd.cgroup5, - systemd.directives7 + systemd.directives7, + exec3 diff --git a/src/core/manager.c b/src/core/manager.c index 669af1524f..079db4157b 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -456,8 +456,6 @@ static int manager_setup_signals(Manager *m) { } static int manager_default_environment(Manager *m) { - const char *path = "PATH=" DEFAULT_PATH; - assert(m); if (m->running_as == SYSTEMD_SYSTEM) { @@ -468,7 +466,8 @@ static int manager_default_environment(Manager *m) { * The initial passed environ is untouched to keep * /proc/self/environ valid; it is used for tagging * the init process inside containers. */ - m->environment = strv_new(path, NULL); + m->environment = strv_new("PATH=" DEFAULT_PATH, + NULL); /* Import locale variables LC_*= from configuration */ locale_setup(&m->environment); -- cgit v1.2.1 From f485606bf8957d2954cf6fa5b0aabd5c39db15c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 16 Sep 2013 15:50:38 -0500 Subject: Make tmpdir removal asynchronous https://bugs.freedesktop.org/show_bug.cgi?id=68232 --- Makefile.am | 4 +-- src/core/async.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/core/async.h | 25 +++++++++++++++++++ src/core/execute.c | 41 +++++++++++++++++++------------ src/core/job.c | 2 +- src/core/sync.c | 65 ------------------------------------------------ src/core/sync.h | 24 ------------------ 7 files changed, 125 insertions(+), 108 deletions(-) create mode 100644 src/core/async.c create mode 100644 src/core/async.h delete mode 100644 src/core/sync.c delete mode 100644 src/core/sync.h diff --git a/Makefile.am b/Makefile.am index 4db064e7c2..b69d66da18 100644 --- a/Makefile.am +++ b/Makefile.am @@ -967,8 +967,8 @@ libsystemd_core_la_SOURCES = \ src/core/syscall-list.h \ src/core/audit-fd.c \ src/core/audit-fd.h \ - src/core/sync.c \ - src/core/sync.h + src/core/async.c \ + src/core/async.h if HAVE_KMOD libsystemd_core_la_SOURCES += \ diff --git a/src/core/async.c b/src/core/async.c new file mode 100644 index 0000000000..af527bea4e --- /dev/null +++ b/src/core/async.c @@ -0,0 +1,72 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include "async.h" +#include "log.h" + +int asynchronous_job(void* (*func)(void *p), void *arg) { + pthread_attr_t a; + pthread_t t; + int r; + + /* It kinda sucks that we have to resort to threads to + * implement an asynchronous sync(), but well, such is + * life. + * + * Note that issuing this command right before exiting a + * process will cause the process to wait for the sync() to + * complete. This function hence is nicely asynchronous really + * only in long running processes. */ + + r = pthread_attr_init(&a); + if (r != 0) + return -r; + + r = pthread_attr_setdetachstate(&a, PTHREAD_CREATE_DETACHED); + if (r != 0) { + r = -r; + goto finish; + } + + r = pthread_create(&t, &a, func, arg); + if (r != 0) { + r = -r; + goto finish; + } + +finish: + pthread_attr_destroy(&a); + return r; +} + +static void *sync_thread(void *p) { + sync(); + return NULL; +} + +int asynchronous_sync(void) { + log_debug("Spawning new thread for sync"); + + return asynchronous_job(sync_thread, NULL); +} diff --git a/src/core/async.h b/src/core/async.h new file mode 100644 index 0000000000..6601b4dc4b --- /dev/null +++ b/src/core/async.h @@ -0,0 +1,25 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +int asynchronous_job(void* (*func)(void *p), void *arg); +int asynchronous_sync(void); diff --git a/src/core/execute.c b/src/core/execute.c index 43b571e043..f840642d14 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -67,6 +67,7 @@ #include "env-util.h" #include "fileio.h" #include "unit.h" +#include "async.h" #define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC) #define IDLE_TIMEOUT2_USEC (1*USEC_PER_SEC) @@ -1581,6 +1582,28 @@ void exec_context_init(ExecContext *c) { c->timer_slack_nsec = (nsec_t) -1; } +static void *remove_tmpdir_thread(void *p) { + int r; + _cleanup_free_ char *dirp = p; + char *dir; + + assert(dirp); + + r = rm_rf_dangerous(dirp, false, true, false); + dir = dirname(dirp); + if (r < 0) + log_warning("Failed to remove content of temporary directory %s: %s", + dir, strerror(-r)); + else { + r = rmdir(dir); + if (r < 0) + log_warning("Failed to remove temporary directory %s: %s", + dir, strerror(-r)); + } + + return NULL; +} + void exec_context_tmp_dirs_done(ExecContext *c) { char* dirs[] = {c->tmp_dir ? c->tmp_dir : c->var_tmp_dir, c->tmp_dir ? c->var_tmp_dir : NULL, @@ -1588,22 +1611,8 @@ void exec_context_tmp_dirs_done(ExecContext *c) { char **dirp; for(dirp = dirs; *dirp; dirp++) { - char *dir; - int r; - - r = rm_rf_dangerous(*dirp, false, true, false); - dir = dirname(*dirp); - if (r < 0) - log_warning("Failed to remove content of temporary directory %s: %s", - dir, strerror(-r)); - else { - r = rmdir(dir); - if (r < 0) - log_warning("Failed to remove temporary directory %s: %s", - dir, strerror(-r)); - } - - free(*dirp); + log_debug("Spawning thread to nuke %s", *dirp); + asynchronous_job(remove_tmpdir_thread, *dirp); } c->tmp_dir = c->var_tmp_dir = NULL; diff --git a/src/core/job.c b/src/core/job.c index 85f77e8f0d..bf1d956908 100644 --- a/src/core/job.c +++ b/src/core/job.c @@ -35,7 +35,7 @@ #include "log.h" #include "dbus-job.h" #include "special.h" -#include "sync.h" +#include "async.h" #include "virt.h" JobBusClient* job_bus_client_new(DBusConnection *connection, const char *name) { diff --git a/src/core/sync.c b/src/core/sync.c deleted file mode 100644 index 7e74b63071..0000000000 --- a/src/core/sync.c +++ /dev/null @@ -1,65 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see . -***/ - -#include -#include - -#include "sync.h" - -static void *sync_thread(void *p) { - sync(); - return NULL; -} - -int asynchronous_sync(void) { - pthread_attr_t a; - pthread_t t; - int r; - - /* It kinda sucks that we have to resort to threads to - * implement an asynchronous sync(), but well, such is - * life. - * - * Note that issuing this command right before exiting a - * process will cause the process to wait for the sync() to - * complete. This function hence is nicely asynchronous really - * only in long running processes. */ - - r = pthread_attr_init(&a); - if (r != 0) - return -r; - - r = pthread_attr_setdetachstate(&a, PTHREAD_CREATE_DETACHED); - if (r != 0) { - r = -r; - goto finish; - } - - r = pthread_create(&t, &a, sync_thread, NULL); - if (r != 0) { - r = -r; - goto finish; - } - -finish: - pthread_attr_destroy(&a); - return r; -} diff --git a/src/core/sync.h b/src/core/sync.h deleted file mode 100644 index eb26c88deb..0000000000 --- a/src/core/sync.h +++ /dev/null @@ -1,24 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -#pragma once - -/*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see . -***/ - -int asynchronous_sync(void); -- cgit v1.2.1 From 1731e34a4ebddf6e1247ad252c7a45c2c1163f42 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 17 Sep 2013 11:02:02 -0500 Subject: tmpfiles: support simple specifier expansion for specified paths --- Makefile.am | 7 ++++-- man/tmpfiles.d.xml | 57 ++++++++++++++++++++++++++++++++++++++++++++++++- src/test/test-strv.c | 10 ++++----- src/tmpfiles/tmpfiles.c | 51 ++++++++++++++++++++++++++----------------- 4 files changed, 97 insertions(+), 28 deletions(-) diff --git a/Makefile.am b/Makefile.am index b69d66da18..af12fa5912 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1542,12 +1542,15 @@ EXTRA_DIST += \ # ------------------------------------------------------------------------------ if ENABLE_TMPFILES systemd_tmpfiles_SOURCES = \ - src/tmpfiles/tmpfiles.c + src/tmpfiles/tmpfiles.c \ + src/shared/specifier.c \ + src/shared/specifier.h systemd_tmpfiles_LDADD = \ libsystemd-label.la \ libsystemd-shared.la \ - libsystemd-capability.la + libsystemd-capability.la \ + libsystemd-id128-internal.la rootbin_PROGRAMS += \ systemd-tmpfiles diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml index cdc87c9192..1cf899226a 100644 --- a/man/tmpfiles.d.xml +++ b/man/tmpfiles.d.xml @@ -67,7 +67,7 @@ Configuration Format Each configuration file shall be named in the - style of <program>.conf. + style of <package>.conf. Files in /etc/ override files with the same name in /usr/lib/ and /run/. Files in @@ -100,8 +100,12 @@ d /run/user 0755 root root 10d - L /tmp/foobar - - - - /dev/null + Type + + The following line types are understood: + f @@ -233,6 +237,57 @@ L /tmp/foobar - - - - /dev/null + + Path + + The file system path specification supports simple specifier + expansion. The following expansions are + understood: + +
+ Specifiers available + + + + + + + Specifier + Meaning + Details + + + + + %m + Machine ID + The machine ID of the running system, formatted as string. See machine-id5 for more information. + + + %b + Boot ID + The boot ID of the running system, formatted as string. See random4 for more information. + + + %H + Host name + The hostname of the running system. + + + %v + Kernel release + Identical to uname -r output. + + + %% + Escaped % + Single percent sign. + + + +
+ + Mode diff --git a/src/test/test-strv.c b/src/test/test-strv.c index 6513d2e07b..c3d536d057 100644 --- a/src/test/test-strv.c +++ b/src/test/test-strv.c @@ -27,19 +27,19 @@ #include "strv.h" static void test_specifier_printf(void) { - _cleanup_free_ char *w = NULL; - int r; - - const Specifier table[] = { + static const Specifier table[] = { { 'a', specifier_string, (char*) "AAAA" }, { 'b', specifier_string, (char*) "BBBB" }, { 'm', specifier_machine_id, NULL }, { 'B', specifier_boot_id, NULL }, { 'H', specifier_host_name, NULL }, { 'v', specifier_kernel_release, NULL }, - { 0, NULL, NULL } + {} }; + _cleanup_free_ char *w = NULL; + int r; + r = specifier_printf("xxx a=%a b=%b yyy", table, NULL, &w); assert_se(r >= 0); assert_se(w); diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 5eca82ad26..fb25b77b2b 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -51,6 +51,7 @@ #include "set.h" #include "conf-files.h" #include "capability.h" +#include "specifier.h" /* This reads all files listed in /etc/tmpfiles.d/?*.conf and creates * them in the file system. This is intended to be used to create @@ -1038,10 +1039,19 @@ static bool should_include_path(const char *path) { } static int parse_line(const char *fname, unsigned line, const char *buffer) { + + static const Specifier specifier_table[] = { + { 'm', specifier_machine_id, NULL }, + { 'b', specifier_boot_id, NULL }, + { 'H', specifier_host_name, NULL }, + { 'v', specifier_kernel_release, NULL }, + {} + }; + _cleanup_item_free_ Item *i = NULL; Item *existing; _cleanup_free_ char - *mode = NULL, *user = NULL, *group = NULL, *age = NULL; + *mode = NULL, *user = NULL, *group = NULL, *age = NULL, *path = NULL; char type; Hashmap *h; int r, n = -1; @@ -1050,14 +1060,10 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { assert(line >= 1); assert(buffer); - i = new0(Item, 1); - if (!i) - return log_oom(); - r = sscanf(buffer, "%c %ms %ms %ms %ms %ms %n", &type, - &i->path, + &path, &mode, &user, &group, @@ -1068,6 +1074,16 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { return -EIO; } + i = new0(Item, 1); + if (!i) + return log_oom(); + + r = specifier_printf(path, specifier_table, NULL, &i->path); + if (r < 0) { + log_error("[%s:%u] Failed to replace specifiers: %s", fname, line, path); + return r; + } + if (n >= 0) { n += strspn(buffer+n, WHITESPACE); if (buffer[n] != 0 && (buffer[n] != '-' || buffer[n+1] != 0)) { @@ -1307,11 +1323,12 @@ static int parse_argv(int argc, char *argv[]) { } static int read_config_file(const char *fn, bool ignore_enoent) { - FILE *f; - unsigned v = 0; - int r; + _cleanup_fclose_ FILE *f = NULL; + char line[LINE_MAX]; Iterator iterator; + unsigned v = 0; Item *i; + int r; assert(fn); @@ -1324,23 +1341,19 @@ static int read_config_file(const char *fn, bool ignore_enoent) { return r; } - log_debug("apply: %s\n", fn); - for (;;) { - char line[LINE_MAX], *l; + FOREACH_LINE(line, f, break) { + char *l; int k; - if (!(fgets(line, sizeof(line), f))) - break; - v++; l = strstrip(line); if (*l == '#' || *l == 0) continue; - if ((k = parse_line(fn, v, l)) < 0) - if (r == 0) - r = k; + k = parse_line(fn, v, l); + if (k < 0 && r == 0) + r = k; } /* we have to determine age parameter for each entry of type X */ @@ -1377,8 +1390,6 @@ static int read_config_file(const char *fn, bool ignore_enoent) { r = -EIO; } - fclose(f); - return r; } -- cgit v1.2.1 From 718d006a63f773c42106494e823250c48942cf08 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 17 Sep 2013 17:39:54 +0200 Subject: logind: listen actively for session devices Session compositors need access to fbdev, DRM and evdev devices if they control a session. To make logind pass them to sessions, we need to listen for them actively. However, we avoid creating new seats for non master-of-seat devices. Only once a seat is created, we start remembering all other session devices. If the last master-device is removed (even if there are other non-master devices still available), we destroy the seat. This is the current behavior, but we need to explicitly implement it now as there may be non-master devices in the seat->devices list. Unlike master devices, we don't care whether our list of non-master devices is complete. We don't export this list but use it only as cache if sessions request these devices. Hence, if a session requests a device that is not in the list, we will simply look it up. However, once a session requested a device, we must be notified of "remove" udev events. So we must link the devices somehow into the device-list. Regarding the implementation, we now sort the device list by the "master" flag. This guarantees that master devices are at the front and non-master devices at the tail of the list. Thus, we can easily test whether a seat has a master device attached. --- src/login/logind-device.c | 35 ++++++++++++++++++--- src/login/logind-device.h | 3 +- src/login/logind-seat.c | 11 +++++-- src/login/logind-seat.h | 1 + src/login/logind.c | 79 +++++++++++++++++++++++++++++++++++++++++------ src/login/logind.h | 6 ++-- 6 files changed, 116 insertions(+), 19 deletions(-) diff --git a/src/login/logind-device.c b/src/login/logind-device.c index 51b15358ba..2bcd6a10c5 100644 --- a/src/login/logind-device.c +++ b/src/login/logind-device.c @@ -25,7 +25,7 @@ #include "logind-device.h" #include "util.h" -Device* device_new(Manager *m, const char *sysfs) { +Device* device_new(Manager *m, const char *sysfs, bool master) { Device *d; assert(m); @@ -48,6 +48,7 @@ Device* device_new(Manager *m, const char *sysfs) { } d->manager = m; + d->master = master; dual_timestamp_get(&d->timestamp); return d; @@ -75,11 +76,16 @@ void device_detach(Device *d) { LIST_REMOVE(Device, devices, d->seat->devices, d); d->seat = NULL; - seat_add_to_gc_queue(s); - seat_send_changed(s, "CanGraphical\0"); + if (!seat_has_master_device(s)) { + seat_add_to_gc_queue(s); + seat_send_changed(s, "CanGraphical\0"); + } } void device_attach(Device *d, Seat *s) { + Device *i; + bool had_master; + assert(d); assert(s); @@ -90,7 +96,26 @@ void device_attach(Device *d, Seat *s) { device_detach(d); d->seat = s; - LIST_PREPEND(Device, devices, s->devices, d); + had_master = seat_has_master_device(s); + + /* We keep the device list sorted by the "master" flag. That is, master + * devices are at the front, other devices at the tail. As there is no + * way to easily add devices at the list-tail, we need to iterate the + * list to find the first non-master device when adding non-master + * devices. We assume there is only a few (normally 1) master devices + * per seat, so we iterate only a few times. */ + + if (d->master || !s->devices) + LIST_PREPEND(Device, devices, s->devices, d); + else { + LIST_FOREACH(devices, i, s->devices) { + if (!i->devices_next || !i->master) { + LIST_INSERT_AFTER(Device, devices, s->devices, i, d); + break; + } + } + } - seat_send_changed(s, "CanGraphical\0"); + if (!had_master && d->master) + seat_send_changed(s, "CanGraphical\0"); } diff --git a/src/login/logind-device.h b/src/login/logind-device.h index 3b153568cb..315f0e66b0 100644 --- a/src/login/logind-device.h +++ b/src/login/logind-device.h @@ -33,13 +33,14 @@ struct Device { char *sysfs; Seat *seat; + bool master; dual_timestamp timestamp; LIST_FIELDS(struct Device, devices); }; -Device* device_new(Manager *m, const char *sysfs); +Device* device_new(Manager *m, const char *sysfs, bool master); void device_free(Device *d); void device_attach(Device *d, Seat *s); void device_detach(Device *d); diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c index 470d08bc05..2c60b8ae51 100644 --- a/src/login/logind-seat.c +++ b/src/login/logind-seat.c @@ -448,10 +448,17 @@ bool seat_can_tty(Seat *s) { return seat_is_vtconsole(s); } +bool seat_has_master_device(Seat *s) { + assert(s); + + /* device list is ordered by "master" flag */ + return !!s->devices && s->devices->master; +} + bool seat_can_graphical(Seat *s) { assert(s); - return !!s->devices; + return seat_has_master_device(s); } int seat_get_idle_hint(Seat *s, dual_timestamp *t) { @@ -499,7 +506,7 @@ int seat_check_gc(Seat *s, bool drop_not_started) { if (seat_is_vtconsole(s)) return 1; - return !!s->devices; + return seat_has_master_device(s); } void seat_add_to_gc_queue(Seat *s) { diff --git a/src/login/logind-seat.h b/src/login/logind-seat.h index c8ab17f7cf..bd5390f553 100644 --- a/src/login/logind-seat.h +++ b/src/login/logind-seat.h @@ -63,6 +63,7 @@ int seat_attach_session(Seat *s, Session *session); bool seat_is_vtconsole(Seat *s); bool seat_can_multi_session(Seat *s); bool seat_can_tty(Seat *s); +bool seat_has_master_device(Seat *s); bool seat_can_graphical(Seat *s); int seat_get_idle_hint(Seat *s, dual_timestamp *t); diff --git a/src/login/logind.c b/src/login/logind.c index 4ef92b8253..29019c214b 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -151,6 +151,8 @@ void manager_free(Manager *m) { if (m->udev_seat_monitor) udev_monitor_unref(m->udev_seat_monitor); + if (m->udev_device_monitor) + udev_monitor_unref(m->udev_device_monitor); if (m->udev_vcsa_monitor) udev_monitor_unref(m->udev_vcsa_monitor); if (m->udev_button_monitor) @@ -184,7 +186,7 @@ void manager_free(Manager *m) { free(m); } -int manager_add_device(Manager *m, const char *sysfs, Device **_device) { +int manager_add_device(Manager *m, const char *sysfs, bool master, Device **_device) { Device *d; assert(m); @@ -195,10 +197,13 @@ int manager_add_device(Manager *m, const char *sysfs, Device **_device) { if (_device) *_device = d; + /* we support adding master-flags, but not removing them */ + d->master = d->master || master; + return 0; } - d = device_new(m, sysfs); + d = device_new(m, sysfs, master); if (!d) return -ENOMEM; @@ -373,7 +378,8 @@ int manager_process_seat_device(Manager *m, struct udev_device *d) { } else { const char *sn; - Seat *seat; + Seat *seat = NULL; + bool master; sn = udev_device_get_property_value(d, "ID_SEAT"); if (isempty(sn)) @@ -384,16 +390,23 @@ int manager_process_seat_device(Manager *m, struct udev_device *d) { return 0; } - r = manager_add_device(m, udev_device_get_syspath(d), &device); + /* ignore non-master devices for unknown seats */ + master = udev_device_has_tag(d, "master-of-seat"); + if (!master && !(seat = hashmap_get(m->seats, sn))) + return 0; + + r = manager_add_device(m, udev_device_get_syspath(d), master, &device); if (r < 0) return r; - r = manager_add_seat(m, sn, &seat); - if (r < 0) { - if (!device->seat) - device_free(device); + if (!seat) { + r = manager_add_seat(m, sn, &seat); + if (r < 0) { + if (!device->seat) + device_free(device); - return r; + return r; + } } device_attach(device, seat); @@ -762,6 +775,22 @@ int manager_dispatch_seat_udev(Manager *m) { return r; } +static int manager_dispatch_device_udev(Manager *m) { + struct udev_device *d; + int r; + + assert(m); + + d = udev_monitor_receive_device(m->udev_device_monitor); + if (!d) + return -ENOMEM; + + r = manager_process_seat_device(m, d); + udev_device_unref(d); + + return r; +} + int manager_dispatch_vcsa_udev(Manager *m) { struct udev_device *d; int r = 0; @@ -1149,6 +1178,7 @@ static int manager_connect_udev(Manager *m) { assert(m); assert(!m->udev_seat_monitor); + assert(!m->udev_device_monitor); assert(!m->udev_vcsa_monitor); assert(!m->udev_button_monitor); @@ -1169,6 +1199,33 @@ static int manager_connect_udev(Manager *m) { if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_seat_fd, &ev) < 0) return -errno; + m->udev_device_monitor = udev_monitor_new_from_netlink(m->udev, "udev"); + if (!m->udev_device_monitor) + return -ENOMEM; + + r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "input", NULL); + if (r < 0) + return r; + + r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "graphics", NULL); + if (r < 0) + return r; + + r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "drm", NULL); + if (r < 0) + return r; + + r = udev_monitor_enable_receiving(m->udev_device_monitor); + if (r < 0) + return r; + + m->udev_device_fd = udev_monitor_get_fd(m->udev_device_monitor); + zero(ev); + ev.events = EPOLLIN; + ev.data.u32 = FD_DEVICE_UDEV; + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_device_fd, &ev) < 0) + return -errno; + /* Don't watch keys if nobody cares */ if (m->handle_power_key != HANDLE_IGNORE || m->handle_suspend_key != HANDLE_IGNORE || @@ -1545,6 +1602,10 @@ int manager_run(Manager *m) { manager_dispatch_seat_udev(m); break; + case FD_DEVICE_UDEV: + manager_dispatch_device_udev(m); + break; + case FD_VCSA_UDEV: manager_dispatch_vcsa_udev(m); break; diff --git a/src/login/logind.h b/src/login/logind.h index e9838a8afd..1a97351fff 100644 --- a/src/login/logind.h +++ b/src/login/logind.h @@ -57,9 +57,10 @@ struct Manager { LIST_HEAD(User, user_gc_queue); struct udev *udev; - struct udev_monitor *udev_seat_monitor, *udev_vcsa_monitor, *udev_button_monitor; + struct udev_monitor *udev_seat_monitor, *udev_device_monitor, *udev_vcsa_monitor, *udev_button_monitor; int udev_seat_fd; + int udev_device_fd; int udev_vcsa_fd; int udev_button_fd; @@ -121,6 +122,7 @@ struct Manager { enum { FD_SEAT_UDEV, + FD_DEVICE_UDEV, FD_VCSA_UDEV, FD_BUTTON_UDEV, FD_CONSOLE, @@ -132,7 +134,7 @@ enum { Manager *manager_new(void); void manager_free(Manager *m); -int manager_add_device(Manager *m, const char *sysfs, Device **_device); +int manager_add_device(Manager *m, const char *sysfs, bool master, Device **_device); int manager_add_button(Manager *m, const char *name, Button **_button); int manager_add_seat(Manager *m, const char *id, Seat **_seat); int manager_add_session(Manager *m, const char *id, Session **_session); -- cgit v1.2.1 From e8b212fe56f7f4e1778474777a7a2959244d0047 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 17 Sep 2013 17:39:55 +0200 Subject: logind: add infrastructure to watch busnames If we want to track bus-names to allow exclusive resource-access, we need a way to get notified when a bus-name is gone. We make logind watch for NameOwnerChanged dbus events and check whether the name is currently watched. If it is, we remove it from the watch-list (notification for other objects can be added in follow-up patches). --- src/login/logind-dbus.c | 17 ++++++++++++++++ src/login/logind.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++- src/login/logind.h | 4 ++++ 3 files changed, 74 insertions(+), 1 deletion(-) diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index d052e74789..5decf8114c 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -2459,6 +2459,23 @@ DBusHandlerResult bus_message_filter( HASHMAP_FOREACH(session, m->sessions, i) session_add_to_gc_queue(session); } + + } else if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) { + const char *name, *old, *new; + char *key; + + if (!dbus_message_get_args(message, &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &old, + DBUS_TYPE_STRING, &new, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse NameOwnerChanged message: %s", bus_error_message(&error)); + goto finish; + } + + if (*old && !*new && (key = hashmap_remove(m->busnames, old))) { + free(key); + } } finish: diff --git a/src/login/logind.c b/src/login/logind.c index 29019c214b..89e4eeea16 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -74,6 +74,7 @@ Manager *manager_new(void) { m->users = hashmap_new(trivial_hash_func, trivial_compare_func); m->inhibitors = hashmap_new(string_hash_func, string_compare_func); m->buttons = hashmap_new(string_hash_func, string_compare_func); + m->busnames = hashmap_new(string_hash_func, string_compare_func); m->user_units = hashmap_new(string_hash_func, string_compare_func); m->session_units = hashmap_new(string_hash_func, string_compare_func); @@ -82,7 +83,7 @@ Manager *manager_new(void) { m->inhibitor_fds = hashmap_new(trivial_hash_func, trivial_compare_func); m->button_fds = hashmap_new(trivial_hash_func, trivial_compare_func); - if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || + if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || !m->busnames || !m->user_units || !m->session_units || !m->session_fds || !m->inhibitor_fds || !m->button_fds) { manager_free(m); @@ -111,6 +112,7 @@ void manager_free(Manager *m) { Seat *s; Inhibitor *i; Button *b; + char *n; assert(m); @@ -132,12 +134,16 @@ void manager_free(Manager *m) { while ((b = hashmap_first(m->buttons))) button_free(b); + while ((n = hashmap_first(m->busnames))) + free(hashmap_remove(m->busnames, n)); + hashmap_free(m->devices); hashmap_free(m->seats); hashmap_free(m->sessions); hashmap_free(m->users); hashmap_free(m->inhibitors); hashmap_free(m->buttons); + hashmap_free(m->busnames); hashmap_free(m->user_units); hashmap_free(m->session_units); @@ -361,6 +367,40 @@ int manager_add_button(Manager *m, const char *name, Button **_button) { return 0; } +int manager_watch_busname(Manager *m, const char *name) { + char *n; + int r; + + assert(m); + assert(name); + + if (hashmap_get(m->busnames, name)) + return 0; + + n = strdup(name); + if (!n) + return -ENOMEM; + + r = hashmap_put(m->busnames, n, n); + if (r < 0) { + free(n); + return r; + } + + return 0; +} + +void manager_drop_busname(Manager *m, const char *name) { + char *key; + + assert(m); + assert(name); + + key = hashmap_remove(m->busnames, name); + if (key) + free(key); +} + int manager_process_seat_device(Manager *m, struct udev_device *d) { Device *device; int r; @@ -1043,6 +1083,18 @@ static int manager_connect_bus(Manager *m) { goto fail; } + dbus_bus_add_match(m->bus, + "type='signal'," + "sender='"DBUS_SERVICE_DBUS"'," + "interface='"DBUS_INTERFACE_DBUS"'," + "member='NameOwnerChanged'," + "path='"DBUS_PATH_DBUS"'", + &error); + if (dbus_error_is_set(&error)) { + log_error("Failed to add match for NameOwnerChanged: %s", bus_error_message(&error)); + dbus_error_free(&error); + } + dbus_bus_add_match(m->bus, "type='signal'," "sender='org.freedesktop.systemd1'," diff --git a/src/login/logind.h b/src/login/logind.h index 1a97351fff..a76936da17 100644 --- a/src/login/logind.h +++ b/src/login/logind.h @@ -51,6 +51,7 @@ struct Manager { Hashmap *users; Hashmap *inhibitors; Hashmap *buttons; + Hashmap *busnames; LIST_HEAD(Seat, seat_gc_queue); LIST_HEAD(Session, session_gc_queue); @@ -190,3 +191,6 @@ int manager_unit_is_active(Manager *manager, const char *unit); /* gperf lookup function */ const struct ConfigPerfItem* logind_gperf_lookup(const char *key, unsigned length); + +int manager_watch_busname(Manager *manager, const char *name); +void manager_drop_busname(Manager *manager, const char *name); -- cgit v1.2.1 From ae5e06bda24ebbb2ac00741738ad3a872fc577a5 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 17 Sep 2013 17:39:56 +0200 Subject: logind: add session controllers A session usually has only a single compositor or other application that controls graphics and input devices on it. To avoid multiple applications from hijacking each other's devices or even using the devices in parallel, we add session controllers. A session controller is an application that manages a session. Specific API calls may be limited to controllers to avoid others from getting unprivileged access to restricted resources. A session becomes a controller by calling the RequestControl() dbus API call. It can drop it via ReleaseControl(). logind tracks bus-names to release the controller once an application closes the bus. We use the new bus-name tracking to do that. Note that during ReleaseControl() we need to check whether some other session also tracks the name before we remove it from the bus-name tracking list. Currently, we only allow one controller at a time. However, the public API does not enforce this restriction. So if it makes sense, we can allow multiple controllers in parallel later. Or we can add a "scope" parameter, which allows a different controller for graphics-devices, sound-devices and whatever you want. Note that currently you get -EBUSY if there is already a controller. You can force the RequestControl() call (root-only) to drop the current controller and recover the session during an emergency. To recover a seat, this is not needed, though. You can simply create a new session or force-activate it. To become a session controller, a dbus caller must either be root or the same user as the user of the session. This allows us to run a session compositor as user and we no longer need any CAP_SYS_ADMIN. --- src/login/logind-dbus.c | 8 +++++++ src/login/logind-session-dbus.c | 42 ++++++++++++++++++++++++++++++++++++ src/login/logind-session.c | 48 +++++++++++++++++++++++++++++++++++++++++ src/login/logind-session.h | 6 ++++++ src/login/logind.c | 10 +++++++++ 5 files changed, 114 insertions(+) diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 5decf8114c..113a2b73b6 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -2473,8 +2473,16 @@ DBusHandlerResult bus_message_filter( goto finish; } + /* drop all controllers owned by this name */ if (*old && !*new && (key = hashmap_remove(m->busnames, old))) { + Session *session; + Iterator i; + free(key); + + HASHMAP_FOREACH(session, m->sessions, i) + if (session_is_controller(session, old)) + session_drop_controller(session); } } diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c index 2cc4d8587b..35bf4480cb 100644 --- a/src/login/logind-session-dbus.c +++ b/src/login/logind-session-dbus.c @@ -40,6 +40,10 @@ " \n" \ " \n" \ " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ @@ -366,6 +370,44 @@ static DBusHandlerResult session_message_dispatch( if (!reply) goto oom; + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "TakeControl")) { + dbus_bool_t force; + unsigned long ul; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_BOOLEAN, &force, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + ul = dbus_bus_get_unix_user(connection, dbus_message_get_sender(message), &error); + if (ul == (unsigned long) -1) + return bus_send_error_reply(connection, message, &error, -EIO); + + if (ul != 0 && (force || ul != s->user->uid)) + return bus_send_error_reply(connection, message, NULL, -EPERM); + + r = session_set_controller(s, bus_message_get_sender_with_fallback(message), force); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "ReleaseControl")) { + const char *sender = bus_message_get_sender_with_fallback(message); + + if (!session_is_controller(s, sender)) + return bus_send_error_reply(connection, message, NULL, -EPERM); + + session_drop_controller(s); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + } else { const BusBoundProperties bps[] = { { "org.freedesktop.login1.Session", bus_login_session_properties, s }, diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 2d22a68b6e..fe5fa27be1 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -73,6 +73,8 @@ void session_free(Session *s) { if (s->in_gc_queue) LIST_REMOVE(Session, gc_queue, s->manager->session_gc_queue, s); + session_drop_controller(s); + if (s->user) { LIST_REMOVE(Session, sessions_by_user, s->user->sessions, s); @@ -918,6 +920,52 @@ int session_kill(Session *s, KillWho who, int signo) { return manager_kill_unit(s->manager, s->scope, who, signo, NULL); } +bool session_is_controller(Session *s, const char *sender) +{ + assert(s); + + return streq_ptr(s->controller, sender); +} + +int session_set_controller(Session *s, const char *sender, bool force) { + char *t; + int r; + + assert(s); + assert(sender); + + if (session_is_controller(s, sender)) + return 0; + if (s->controller && !force) + return -EBUSY; + + t = strdup(sender); + if (!t) + return -ENOMEM; + + r = manager_watch_busname(s->manager, sender); + if (r) { + free(t); + return r; + } + + session_drop_controller(s); + + s->controller = t; + return 0; +} + +void session_drop_controller(Session *s) { + assert(s); + + if (!s->controller) + return; + + manager_drop_busname(s->manager, s->controller); + free(s->controller); + s->controller = NULL; +} + static const char* const session_state_table[_SESSION_STATE_MAX] = { [SESSION_OPENING] = "opening", [SESSION_ONLINE] = "online", diff --git a/src/login/logind-session.h b/src/login/logind-session.h index 9cf64850be..839fb230dc 100644 --- a/src/login/logind-session.h +++ b/src/login/logind-session.h @@ -106,6 +106,8 @@ struct Session { DBusMessage *create_message; + char *controller; + LIST_FIELDS(Session, sessions_by_user); LIST_FIELDS(Session, sessions_by_seat); @@ -154,3 +156,7 @@ SessionClass session_class_from_string(const char *s) _pure_; const char *kill_who_to_string(KillWho k) _const_; KillWho kill_who_from_string(const char *s) _pure_; + +bool session_is_controller(Session *s, const char *sender); +int session_set_controller(Session *s, const char *sender, bool force); +void session_drop_controller(Session *s); diff --git a/src/login/logind.c b/src/login/logind.c index 89e4eeea16..c99c2844e8 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -391,11 +391,21 @@ int manager_watch_busname(Manager *m, const char *name) { } void manager_drop_busname(Manager *m, const char *name) { + Session *session; + Iterator i; char *key; assert(m); assert(name); + if (!hashmap_get(m->busnames, name)) + return; + + /* keep it if the name still owns a controller */ + HASHMAP_FOREACH(session, m->sessions, i) + if (session_is_controller(session, name)) + return; + key = hashmap_remove(m->busnames, name); if (key) free(key); -- cgit v1.2.1 From ab60f2ffb1a1fe2024aea077b3f42c3653bf1df1 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 17 Sep 2013 17:39:57 +0200 Subject: logind: make Session.Activate() lazy Currently, Activate() calls chvt(), which does an ioctl(VT_ACTIVATE) and immediately calls seat_set_active(). However, VTs are allowed to prevent being deactivated. Therefore, logind cannot be sure the VT_ACTIVATE call was actually successful. Furthermore, compositors often need to clean up their devices before they acknowledge the VT switch. The immediate call to seat_set_active() may modify underlying ACLs, though. Thus, some compositors may fail cleaning up their stuff. Moreover, the compositor being switched to (if listening to logind instead of VTs) will not be able to activate its devices if the old VT still has them active. We could simply add an VT_WAITACTIVE call, which blocks until the given VT is active. However, this can block forever if the compositor hangs. So to fix this, we make Activate() lazy. That is, it only schedules a session-switch but does not wait for it to complete. The caller can no longer rely on it being immediate. Instead, a caller is required to wait for the PropertiesChanged signal and read the "Active" field. We could make Activate() wait asynchronously for the session-switch to complete and then send the return-message afterwards. However, this would add a lot of state-tracking with no real gain: 1) Sessions normally don't care whether Activate() was actually successful as they currently _must_ wait for the VT activation to do anything for real. 2) Error messages for failed session switches can be printed by logind instead of the session issuing Activate(). 3) Sessions that require synchronous Activate() calls can simply issue the call and then wait for "Active" properties to change. This also allows them to implement their own timeout. This change prepares for multi-session on seats without VTs. Forced VT switches are always bad as compositors cannot perform any cleanup. This isn't strictly required, but may lead to loss of information and ambiguous error messages. So for multi-session on seats without VTs, we must wait for the current session to clean-up before finalizing the session-switch. This requires Activate() to be lazy as we cannot block here. Note that we can always implement a timeout which allows us to guarantee the session switch to happen. Nevertheless, this calls for a lazy Activate(). --- src/login/logind-session.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/login/logind-session.c b/src/login/logind-session.c index fe5fa27be1..fa8b5157e8 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -360,8 +360,6 @@ int session_load(Session *s) { } int session_activate(Session *s) { - int r; - assert(s); assert(s->user); @@ -376,11 +374,7 @@ int session_activate(Session *s) { assert(seat_is_vtconsole(s->seat)); - r = chvt(s->vtnr); - if (r < 0) - return r; - - return seat_set_active(s->seat, s); + return chvt(s->vtnr); } static int session_link_x11_socket(Session *s) { -- cgit v1.2.1 From e58ae4103710295a8afd43c83d0c6bf088ae744f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 17 Sep 2013 11:59:41 -0500 Subject: update TODO --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index 1ca3142529..6a96c7781a 100644 --- a/TODO +++ b/TODO @@ -58,6 +58,8 @@ CGroup Rework Completion: Features: +* always set memory.user_hierarchy for all cgroups we create + * Get rid of MemorySoftLimit= * After coming back from hibernation reset hibernation swap partition -- cgit v1.2.1 From 3331234adc763378a5e48e7ad6dc2bf9657aa535 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 17 Sep 2013 11:59:47 -0500 Subject: nspawn: update unit file ControlGroup= is obsolete, so let's drop it from the default nspawn unit file. --- units/systemd-nspawn@.service.in | 1 - 1 file changed, 1 deletion(-) diff --git a/units/systemd-nspawn@.service.in b/units/systemd-nspawn@.service.in index c0d5886f88..eca62e3b17 100644 --- a/units/systemd-nspawn@.service.in +++ b/units/systemd-nspawn@.service.in @@ -11,7 +11,6 @@ Documentation=man:systemd-nspawn(1) [Service] ExecStart=@bindir@/systemd-nspawn -bjD /var/lib/container/%i -ControlGroup=%R/machine/%i.nspawn cpu:/ Type=notify [Install] -- cgit v1.2.1 From 92432fcc7f3a0320c07e99c5d395568a3aa216b6 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 17 Sep 2013 17:39:59 +0200 Subject: logind: rename vtconsole to seat0 The seat->vtconsole member always points to the default seat seat0. Even if VTs are disabled, it's used as default seat. Therefore, rename it to seat0 to correctly state what it is. This also changes the seat files in /run from IS_VTCONSOLE to IS_SEAT0. It wasn't used by any code, yet, so this seems fine. While we are at it, we also remove every "if (s->vtconsole)" as this pointer is always valid! --- src/login/logind-dbus.c | 8 ++++---- src/login/logind-seat.c | 14 +++++++------- src/login/logind-seat.h | 2 +- src/login/logind-session.c | 2 +- src/login/logind.c | 8 ++++---- src/login/logind.h | 2 +- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 113a2b73b6..4a23c93bd9 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -404,8 +404,8 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message) { int v; if (!seat) - seat = m->vtconsole; - else if (seat != m->vtconsole) + seat = m->seat0; + else if (seat != m->seat0) return -EINVAL; v = vtnr_from_tty(tty); @@ -420,8 +420,8 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message) { } else if (tty_is_console(tty)) { if (!seat) - seat = m->vtconsole; - else if (seat != m->vtconsole) + seat = m->seat0; + else if (seat != m->seat0) return -EINVAL; if (vtnr != 0) diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c index 2c60b8ae51..9b6ceb31af 100644 --- a/src/login/logind-seat.c +++ b/src/login/logind-seat.c @@ -105,11 +105,11 @@ int seat_save(Seat *s) { fprintf(f, "# This is private data. Do not parse.\n" - "IS_VTCONSOLE=%i\n" + "IS_SEAT0=%i\n" "CAN_MULTI_SESSION=%i\n" "CAN_TTY=%i\n" "CAN_GRAPHICAL=%i\n", - seat_is_vtconsole(s), + seat_is_seat0(s), seat_can_multi_session(s), seat_can_tty(s), seat_can_graphical(s)); @@ -424,16 +424,16 @@ int seat_attach_session(Seat *s, Session *session) { return 0; } -bool seat_is_vtconsole(Seat *s) { +bool seat_is_seat0(Seat *s) { assert(s); - return s->manager->vtconsole == s; + return s->manager->seat0 == s; } bool seat_can_multi_session(Seat *s) { assert(s); - if (!seat_is_vtconsole(s)) + if (!seat_is_seat0(s)) return false; /* If we can't watch which VT is in the foreground, we don't @@ -445,7 +445,7 @@ bool seat_can_multi_session(Seat *s) { bool seat_can_tty(Seat *s) { assert(s); - return seat_is_vtconsole(s); + return seat_is_seat0(s); } bool seat_has_master_device(Seat *s) { @@ -503,7 +503,7 @@ int seat_check_gc(Seat *s, bool drop_not_started) { if (drop_not_started && !s->started) return 0; - if (seat_is_vtconsole(s)) + if (seat_is_seat0(s)) return 1; return seat_has_master_device(s); diff --git a/src/login/logind-seat.h b/src/login/logind-seat.h index bd5390f553..47fe89a690 100644 --- a/src/login/logind-seat.h +++ b/src/login/logind-seat.h @@ -60,7 +60,7 @@ int seat_preallocate_vts(Seat *s); int seat_attach_session(Seat *s, Session *session); -bool seat_is_vtconsole(Seat *s); +bool seat_is_seat0(Seat *s); bool seat_can_multi_session(Seat *s); bool seat_can_tty(Seat *s); bool seat_has_master_device(Seat *s); diff --git a/src/login/logind-session.c b/src/login/logind-session.c index fa8b5157e8..407429c48a 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -372,7 +372,7 @@ int session_activate(Session *s) { if (s->seat->active == s) return 0; - assert(seat_is_vtconsole(s->seat)); + assert(seat_is_seat0(s->seat)); return chvt(s->vtnr); } diff --git a/src/login/logind.c b/src/login/logind.c index c99c2844e8..702382acff 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -858,7 +858,7 @@ int manager_dispatch_vcsa_udev(Manager *m) { * VTs, to make sure our auto VTs never go away. */ if (name && startswith(name, "vcsa") && streq_ptr(udev_device_get_action(d), "remove")) - r = seat_preallocate_vts(m->vtconsole); + r = seat_preallocate_vts(m->seat0); udev_device_unref(d); @@ -883,9 +883,9 @@ int manager_dispatch_button_udev(Manager *m) { int manager_dispatch_console(Manager *m) { assert(m); + assert(m->seat0); - if (m->vtconsole) - seat_read_active_vt(m->vtconsole); + seat_read_active_vt(m->seat0); return 0; } @@ -1543,7 +1543,7 @@ int manager_startup(Manager *m) { return r; /* Instantiate magic seat 0 */ - r = manager_add_seat(m, "seat0", &m->vtconsole); + r = manager_add_seat(m, "seat0", &m->seat0); if (r < 0) return r; diff --git a/src/login/logind.h b/src/login/logind.h index a76936da17..9e6296cb7e 100644 --- a/src/login/logind.h +++ b/src/login/logind.h @@ -74,7 +74,7 @@ struct Manager { unsigned reserve_vt; int reserve_vt_fd; - Seat *vtconsole; + Seat *seat0; char **kill_only_users, **kill_exclude_users; bool kill_user_processes; -- cgit v1.2.1 From 20e1bd9d1b289761a1b0010d778bdaf924f317b3 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 17 Sep 2013 17:40:00 +0200 Subject: logind: fix seat_can_tty() to check for VTs A seat provides text-logins if it has VTs. This is always limited to seat0 so the seat_is_seat0() check is correct. However, if VTs are disabled, no seat provides text-logins so we also need to check for the console-fd. This was previously: return seat_is_vtconsole(); It looked right, but was functionally equivalent to seat_is_seat0(). The rename of this helper made it more obvious that it is missing the VT test. --- src/login/logind-seat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c index 9b6ceb31af..c5350fbf53 100644 --- a/src/login/logind-seat.c +++ b/src/login/logind-seat.c @@ -445,7 +445,7 @@ bool seat_can_multi_session(Seat *s) { bool seat_can_tty(Seat *s) { assert(s); - return seat_is_seat0(s); + return seat_is_seat0(s) && s->manager->console_active_fd >= 0; } bool seat_has_master_device(Seat *s) { -- cgit v1.2.1 From 9209d5121dfb3049cbf280139c4cc40c2038edcc Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 17 Sep 2013 17:40:01 +0200 Subject: logind: fix session_activate(vtnr = 0) VT numbers start with 1. If a session has vtnr == 0, we must not assume it is running on a VT. Note that this could trigger the assert() below as CreateSession() sets vtnr to 0, not <0. --- src/login/logind-session.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 407429c48a..ab1c79cfa2 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -363,7 +363,7 @@ int session_activate(Session *s) { assert(s); assert(s->user); - if (s->vtnr < 0) + if (s->vtnr <= 0) return -ENOTSUP; if (!s->seat) -- cgit v1.2.1 From bf7825ae69f53a7e80a740547919833e49ed1df4 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 17 Sep 2013 17:40:02 +0200 Subject: logind: extract has_vts() from can_multi_session() We currently use seat_can_multi_session() to test for two things: * whether the seat can handle session-switching * whether the seat has VTs As both are currently logically equivalent, we didn't care. However, we want to allow session-switching on seats without VTs, so split this helper into: * seat_can_multi_session(): whether session-switching is supported * seat_has_vts(): whether the seat has VTs Note that only one seat on a system can have VTs. There is only one set of them. We automatically assign them to seat0 as usual. With this patch in place, we can easily add new session-switching/tracking methods without breaking any VT code as it is now protected by has_vts(), no longer by can_multi_session(). --- src/login/logind-dbus.c | 2 +- src/login/logind-seat.c | 32 ++++++++++++++------------------ src/login/logind-seat.h | 1 + src/login/logind-session.c | 6 +++--- 4 files changed, 19 insertions(+), 22 deletions(-) diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 4a23c93bd9..fd8ee1b801 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -429,7 +429,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message) { } if (seat) { - if (seat_can_multi_session(seat)) { + if (seat_has_vts(seat)) { if (vtnr > 63) return -EINVAL; } else { diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c index c5350fbf53..3dc529b2b9 100644 --- a/src/login/logind-seat.c +++ b/src/login/logind-seat.c @@ -201,7 +201,7 @@ int seat_preallocate_vts(Seat *s) { if (s->manager->n_autovts <= 0) return 0; - if (!seat_can_multi_session(s)) + if (!seat_has_vts(s)) return 0; for (i = 1; i <= s->manager->n_autovts; i++) { @@ -277,7 +277,7 @@ int seat_active_vt_changed(Seat *s, int vtnr) { assert(s); assert(vtnr >= 1); - if (!seat_can_multi_session(s)) + if (!seat_has_vts(s)) return -EINVAL; log_debug("VT changed to %i", vtnr); @@ -301,7 +301,7 @@ int seat_read_active_vt(Seat *s) { assert(s); - if (!seat_can_multi_session(s)) + if (!seat_has_vts(s)) return 0; lseek(s->manager->console_active_fd, SEEK_SET, 0); @@ -412,18 +412,20 @@ int seat_attach_session(Seat *s, Session *session) { seat_send_changed(s, "Sessions\0"); - /* Note that even if a seat is not multi-session capable it - * still might have multiple sessions on it since old, dead - * sessions might continue to be tracked until all their - * processes are gone. The most recently added session - * (i.e. the first in s->sessions) is the one that matters. */ - - if (!seat_can_multi_session(s)) + /* On seats with VTs, the VT logic defines which session is active. On + * seats without VTs, we automatically activate the first session. */ + if (!seat_has_vts(s) && !s->active) seat_set_active(s, session); return 0; } +bool seat_has_vts(Seat *s) { + assert(s); + + return seat_is_seat0(s) && s->manager->console_active_fd >= 0; +} + bool seat_is_seat0(Seat *s) { assert(s); @@ -433,19 +435,13 @@ bool seat_is_seat0(Seat *s) { bool seat_can_multi_session(Seat *s) { assert(s); - if (!seat_is_seat0(s)) - return false; - - /* If we can't watch which VT is in the foreground, we don't - * support VT switching */ - - return s->manager->console_active_fd >= 0; + return seat_has_vts(s); } bool seat_can_tty(Seat *s) { assert(s); - return seat_is_seat0(s) && s->manager->console_active_fd >= 0; + return seat_has_vts(s); } bool seat_has_master_device(Seat *s) { diff --git a/src/login/logind-seat.h b/src/login/logind-seat.h index 47fe89a690..d3438b8495 100644 --- a/src/login/logind-seat.h +++ b/src/login/logind-seat.h @@ -60,6 +60,7 @@ int seat_preallocate_vts(Seat *s); int seat_attach_session(Seat *s, Session *session); +bool seat_has_vts(Seat *s); bool seat_is_seat0(Seat *s); bool seat_can_multi_session(Seat *s); bool seat_can_tty(Seat *s); diff --git a/src/login/logind-session.c b/src/login/logind-session.c index ab1c79cfa2..f856127eae 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -191,7 +191,7 @@ int session_save(Session *s) { if (s->service) fprintf(f, "SERVICE=%s\n", s->service); - if (s->seat && seat_can_multi_session(s->seat)) + if (s->seat && seat_has_vts(s->seat)) fprintf(f, "VTNR=%i\n", s->vtnr); if (s->leader > 0) @@ -301,7 +301,7 @@ int session_load(Session *s) { seat_attach_session(o, s); } - if (vtnr && s->seat && seat_can_multi_session(s->seat)) { + if (vtnr && s->seat && seat_has_vts(s->seat)) { int v; k = safe_atoi(vtnr, &v); @@ -372,7 +372,7 @@ int session_activate(Session *s) { if (s->seat->active == s) return 0; - assert(seat_is_seat0(s->seat)); + assert(seat_has_vts(s->seat)); return chvt(s->vtnr); } -- cgit v1.2.1 From dd8b2bf433a42683380b6fa041660dd92f91b6a9 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Tue, 17 Sep 2013 19:16:08 +0200 Subject: udev: path_id - fix by-path link generation for scm devices Set some_transport = true to prevent scm devices from being ignored. Suggested-by: Harald Hoyer Signed-off-by: Sebastian Ott --- src/udev/udev-builtin-path_id.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c index da0273197b..0659967c68 100644 --- a/src/udev/udev-builtin-path_id.c +++ b/src/udev/udev-builtin-path_id.c @@ -531,6 +531,7 @@ static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool } else if (streq(subsys, "scm")) { path_prepend(&path, "scm-%s", udev_device_get_sysname(parent)); parent = skip_subsystem(parent, "scm"); + some_transport = true; } parent = udev_device_get_parent(parent); -- cgit v1.2.1 From 387abf80ad40e4a6c2f4725c8eff4d66bf110d1f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 17 Sep 2013 13:57:04 -0500 Subject: NEWS: add some clarifications As suggested by Colin Guthrie on the ML. --- NEWS | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/NEWS b/NEWS index 7e2a441a50..d2e6510690 100644 --- a/NEWS +++ b/NEWS @@ -37,7 +37,7 @@ CHANGES WITH 207: * The option "discard" (as known from Debian) is now synonymous to "allow-discards" in /etc/crypttab. In fact, - the latter is preferred now (since it is easier to remember + "discard" is preferred now (since it is easier to remember and type). * Some licensing clean-ups were made, so that more code is now @@ -62,12 +62,13 @@ CHANGES WITH 207: environment for all services, do so via the kernel command line systemd.setenv= assignment. - * The systemd-sysctl tool no longer natively reads the - file /etc/sysctl.conf. If desired, the file should be - symlinked from /etc/sysctl.d/99-sysctl.conf. Apart from - providing legacy support by a symlink rather than built-in - code, it also makes the otherwise hidden order of application - of the different files visible. + * The systemd-sysctl tool no longer natively reads the file + /etc/sysctl.conf. If desired, the file should be symlinked + from /etc/sysctl.d/99-sysctl.conf. Apart from providing + legacy support by a symlink rather than built-in code, it + also makes the otherwise hidden order of application of the + different files visible. (Note that this partly reverts to a + pre-198 application order of sysctl knobs!) * The "systemctl set-log-level" and "systemctl dump" commands have been moved to systemd-analyze. -- cgit v1.2.1 From ddca82aca08712a302cfabdbe59f73ee9ed3f73a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 17 Sep 2013 14:58:00 -0500 Subject: cgroup: get rid of MemorySoftLimit= The cgroup attribute memory.soft_limit_in_bytes is unlikely to stay around in the kernel for good, so let's not expose it for now. We can readd something like it later when the kernel guys decided on a final API for this. --- TODO | 2 -- man/systemd.cgroup.xml | 15 +++++---------- src/core/cgroup.c | 16 ++-------------- src/core/cgroup.h | 1 - src/core/dbus-cgroup.c | 10 ++-------- src/core/dbus-cgroup.h | 1 - src/core/load-fragment-gperf.gperf.m4 | 1 - src/core/load-fragment.c | 7 ++----- src/systemctl/systemctl.c | 2 +- 9 files changed, 12 insertions(+), 43 deletions(-) diff --git a/TODO b/TODO index 6a96c7781a..d109e01f71 100644 --- a/TODO +++ b/TODO @@ -60,8 +60,6 @@ Features: * always set memory.user_hierarchy for all cgroups we create -* Get rid of MemorySoftLimit= - * After coming back from hibernation reset hibernation swap partition * mounts: do not test each mount unit against each other mount unit to diff --git a/man/systemd.cgroup.xml b/man/systemd.cgroup.xml index cc0eb15abb..ac5896233c 100644 --- a/man/systemd.cgroup.xml +++ b/man/systemd.cgroup.xml @@ -136,22 +136,17 @@ along with systemd; If not, see . MemoryLimit=bytes - MemorySoftLimit=bytes - Specify the hard and soft limits on maximum memory - usage of the executed processes. The "hard" limit specifies - how much process and kernel memory can be used by tasks in - this unit, when there is no memory contention. If the kernel - detects memory contention, memory reclaim will be performed - until the memory usage is within the "soft" limit. Takes a + Specify the limit on maximum memory usage of the + executed processes. The limit specifies how much process and + kernel memory can be used by tasks in this unit. Takes a memory size in bytes. If the value is suffixed with K, M, G or T, the specified memory size is parsed as Kilobytes, Megabytes, Gigabytes, or Terabytes (with the base 1024), respectively. This controls the - memory.limit_in_bytes and - memory.soft_limit_in_bytes control group - attributes. For details about these control group attributes, + memory.limit_in_bytes control group + attribute. For details about this control group attribute, see memory.txt. diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 9277dd69f6..d10f205a2f 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -33,7 +33,7 @@ void cgroup_context_init(CGroupContext *c) { * structure is preinitialized to 0 */ c->cpu_shares = 1024; - c->memory_limit = c->memory_soft_limit = (uint64_t) -1; + c->memory_limit = (uint64_t) -1; c->blockio_weight = 1000; } @@ -94,7 +94,6 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) { "%sCPUShares=%lu\n" "%sBlockIOWeight=%lu\n" "%sMemoryLimit=%" PRIu64 "\n" - "%sMemorySoftLimit=%" PRIu64 "\n" "%sDevicePolicy=%s\n", prefix, yes_no(c->cpu_accounting), prefix, yes_no(c->blockio_accounting), @@ -102,7 +101,6 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) { prefix, c->cpu_shares, prefix, c->blockio_weight, prefix, c->memory_limit, - prefix, c->memory_soft_limit, prefix, cgroup_device_policy_to_string(c->device_policy)); LIST_FOREACH(device_allow, a, c->device_allow) @@ -265,15 +263,6 @@ void cgroup_context_apply(CGroupContext *c, CGroupControllerMask mask, const cha if (r < 0) log_error("Failed to set memory.limit_in_bytes on %s: %s", path, strerror(-r)); - - if (c->memory_soft_limit != (uint64_t) -1) { - sprintf(buf, "%" PRIu64 "\n", c->memory_soft_limit); - r = cg_set_attribute("memory", path, "memory.soft_limit_in_bytes", buf); - } else - r = cg_set_attribute("memory", path, "memory.soft_limit_in_bytes", "-1"); - - if (r < 0) - log_error("Failed to set memory.soft_limit_in_bytes on %s: %s", path, strerror(-r)); } if (mask & CGROUP_DEVICE) { @@ -336,8 +325,7 @@ CGroupControllerMask cgroup_context_get_mask(CGroupContext *c) { mask |= CGROUP_BLKIO; if (c->memory_accounting || - c->memory_limit != (uint64_t) -1 || - c->memory_soft_limit != (uint64_t) -1) + c->memory_limit != (uint64_t) -1) mask |= CGROUP_MEMORY; if (c->device_allow || c->device_policy != CGROUP_AUTO) diff --git a/src/core/cgroup.h b/src/core/cgroup.h index 786bd71c8b..0a079e909d 100644 --- a/src/core/cgroup.h +++ b/src/core/cgroup.h @@ -77,7 +77,6 @@ struct CGroupContext { LIST_HEAD(CGroupBlockIODeviceBandwidth, blockio_device_bandwidths); uint64_t memory_limit; - uint64_t memory_soft_limit; CGroupDevicePolicy device_policy; LIST_HEAD(CGroupDeviceAllow, device_allow); diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c index 1f2a396a6d..9ebcad9da6 100644 --- a/src/core/dbus-cgroup.c +++ b/src/core/dbus-cgroup.c @@ -133,7 +133,6 @@ const BusProperty bus_cgroup_context_properties[] = { { "BlockIOWriteBandwidth", bus_cgroup_append_device_bandwidths, "a(st)", 0 }, { "MemoryAccounting", bus_property_append_bool, "b", offsetof(CGroupContext, memory_accounting) }, { "MemoryLimit", bus_property_append_uint64, "t", offsetof(CGroupContext, memory_limit) }, - { "MemorySoftLimit", bus_property_append_uint64, "t", offsetof(CGroupContext, memory_soft_limit) }, { "DevicePolicy", bus_cgroup_append_device_policy, "s", offsetof(CGroupContext, device_policy) }, { "DeviceAllow", bus_cgroup_append_device_allow, "a(ss)", 0 }, {} @@ -418,21 +417,16 @@ int bus_cgroup_set_property( return 1; - } else if (streq(name, "MemoryLimit") || streq(name, "MemorySoftLimit")) { + } else if (streq(name, "MemoryLimit")) { if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_UINT64) return -EINVAL; if (mode != UNIT_CHECK) { uint64_t limit; - dbus_message_iter_get_basic(i, &limit); - if (streq(name, "MemoryLimit")) - c->memory_limit = limit; - else - c->memory_soft_limit = limit; - + c->memory_limit = limit; unit_write_drop_in_private_format(u, mode, name, "%s=%" PRIu64, name, limit); } diff --git a/src/core/dbus-cgroup.h b/src/core/dbus-cgroup.h index 4ce1e7e7fa..e5ac4c3af7 100644 --- a/src/core/dbus-cgroup.h +++ b/src/core/dbus-cgroup.h @@ -37,7 +37,6 @@ " \n" \ " \n" \ " \n" \ - " \n" \ " \n" \ " \n" diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index 33c6880b5d..25bd3aae47 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -89,7 +89,6 @@ $1.CPUAccounting, config_parse_bool, 0, $1.CPUShares, config_parse_cpu_shares, 0, offsetof($1, cgroup_context) $1.MemoryAccounting, config_parse_bool, 0, offsetof($1, cgroup_context.memory_accounting) $1.MemoryLimit, config_parse_memory_limit, 0, offsetof($1, cgroup_context) -$1.MemorySoftLimit, config_parse_memory_limit, 0, offsetof($1, cgroup_context) $1.DeviceAllow, config_parse_device_allow, 0, offsetof($1, cgroup_context) $1.DevicePolicy, config_parse_device_policy, 0, offsetof($1, cgroup_context.device_policy) $1.BlockIOAccounting, config_parse_bool, 0, offsetof($1, cgroup_context.blockio_accounting) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index cfc6f078a6..74454abe49 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -2036,14 +2036,11 @@ int config_parse_memory_limit( void *userdata) { CGroupContext *c = data; - uint64_t *limit; off_t bytes; int r; - limit = streq(lvalue, "MemoryLimit") ? &c->memory_limit : &c->memory_soft_limit; - if (isempty(rvalue)) { - *limit = (uint64_t) -1; + c->memory_limit = (uint64_t) -1; return 0; } @@ -2056,7 +2053,7 @@ int config_parse_memory_limit( return 0; } - *limit = (uint64_t) bytes; + c->memory_limit = (uint64_t) bytes; return 0; } diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 57e5bb941b..62b5616d80 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -3657,7 +3657,7 @@ static int append_assignment(DBusMessageIter *iter, const char *assignment) { !dbus_message_iter_append_basic(&sub, DBUS_TYPE_BOOLEAN, &b)) return log_oom(); - } else if (streq(field, "MemoryLimit") || streq(field, "MemorySoftLimit")) { + } else if (streq(field, "MemoryLimit")) { off_t bytes; uint64_t u; -- cgit v1.2.1 From 07ba97757505ea94458ef32cdc45311fd6efc298 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Mon, 16 Sep 2013 18:06:57 -0500 Subject: TEST-01-BASIC, TEST-02-CRYPTSETUP: fixed strip also output more status about failed jobs --- test/TEST-01-BASIC/test.sh | 6 +++--- test/TEST-02-CRYPTSETUP/test.sh | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/TEST-01-BASIC/test.sh b/test/TEST-01-BASIC/test.sh index e41ed9dcfe..9b55a27a20 100755 --- a/test/TEST-01-BASIC/test.sh +++ b/test/TEST-01-BASIC/test.sh @@ -132,7 +132,7 @@ Description=Testsuite service After=multi-user.target [Service] -ExecStart=/bin/bash -c 'set -x; systemctl --failed --no-legend --no-pager > /failed ; echo OK > /testok; while : ;do echo "testsuite service waiting for journal to move to /var/log/journal" > /dev/console ; for i in /var/log/journal/*;do [ -d "\$i" ] && echo "\$i" && break 2; done; sleep 1; done; sleep 1; exit 0;' +ExecStart=/bin/bash -c 'set -x; ( systemctl --failed --no-legend --no-pager; systemctl status --failed ) > /failed ; echo OK > /testok; while : ;do echo "testsuite service waiting for journal to move to /var/log/journal" > /dev/console ; for i in /var/log/journal/*;do [ -d "\$i" ] && echo "\$i" && break 2; done; sleep 1; done; sleep 1; exit 0;' Type=oneshot EOF @@ -190,7 +190,7 @@ EOF # softlink mtab ln -fs /proc/self/mounts $initdir/etc/mtab - # install any Exec's from the service files + # install any Execs from the service files egrep -ho '^Exec[^ ]*=[^ ]+' $initdir/lib/systemd/system/*.service \ | while read i; do i=${i##Exec*=}; i=${i##-} @@ -213,7 +213,7 @@ EOF cp -a /etc/ld.so.conf* $initdir/etc ldconfig -r "$initdir" ddebug "Strip binaries" - find "$initdir" -perm +111 -type f | xargs strip --strip-unneeded | ddebug + find "$initdir" -executable -not -path '*/lib/modules/*.ko' -type f | xargs strip --strip-unneeded | ddebug # copy depmod files inst /lib/modules/$KERNEL_VER/modules.order diff --git a/test/TEST-02-CRYPTSETUP/test.sh b/test/TEST-02-CRYPTSETUP/test.sh index ec714301c6..b98d23810a 100755 --- a/test/TEST-02-CRYPTSETUP/test.sh +++ b/test/TEST-02-CRYPTSETUP/test.sh @@ -131,7 +131,7 @@ Description=Testsuite service After=multi-user.target [Service] -ExecStart=/bin/bash -c 'set -x; systemctl --failed --no-legend --no-pager > /failed ; echo OK > /testok; while : ;do systemd-cat echo "testsuite service waiting for /var/log/journal" ; echo "testsuite service waiting for journal to move to /var/log/journal" > /dev/console ; for i in /var/log/journal/*;do [ -d "\$i" ] && echo "\$i" && break 2; done; sleep 1; done; sleep 1; exit 0;' +ExecStart=/bin/bash -c 'set -x; ( systemctl --failed --no-legend --no-pager; systemctl status --failed ) > /failed ; echo OK > /testok; while : ;do systemd-cat echo "testsuite service waiting for /var/log/journal" ; echo "testsuite service waiting for journal to move to /var/log/journal" > /dev/console ; for i in /var/log/journal/*;do [ -d "\$i" ] && echo "\$i" && break 2; done; sleep 1; done; sleep 1; exit 0;' Type=oneshot EOF @@ -197,7 +197,7 @@ EOF # softlink mtab ln -fs /proc/self/mounts $initdir/etc/mtab - # install any Exec's from the service files + # install any Execs from the service files egrep -ho '^Exec[^ ]*=[^ ]+' $initdir/lib/systemd/system/*.service \ | while read i; do i=${i##Exec*=}; i=${i##-} @@ -220,7 +220,7 @@ EOF cp -a /etc/ld.so.conf* $initdir/etc ldconfig -r "$initdir" ddebug "Strip binaeries" - find "$initdir" -perm +111 -type f | xargs strip --strip-unneeded | ddebug + find "$initdir" -executable -not -path '*/lib/modules/*.ko' -type f | xargs strip --strip-unneeded | ddebug # copy depmod files inst /lib/modules/$KERNEL_VER/modules.order -- cgit v1.2.1 From 41a5ef639b248aa3d10609d9af5d0043b909d93c Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Mon, 16 Sep 2013 18:07:43 -0500 Subject: TEST-03-JOBS/test.sh: do not output the "failed" if it does not exist --- test/TEST-03-JOBS/test.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/TEST-03-JOBS/test.sh b/test/TEST-03-JOBS/test.sh index 6440d1f54b..02fd8b9ce8 100755 --- a/test/TEST-03-JOBS/test.sh +++ b/test/TEST-03-JOBS/test.sh @@ -21,10 +21,10 @@ run_qemu() { mkdir -p $TESTDIR/root mount ${LOOPDEV}p1 $TESTDIR/root [[ -e $TESTDIR/root/testok ]] && ret=0 - cp -a $TESTDIR/root/failed $TESTDIR + [[ -f $TESTDIR/root/failed ]] && cp -a $TESTDIR/root/failed $TESTDIR cp -a $TESTDIR/root/var/log/journal $TESTDIR umount $TESTDIR/root - cat $TESTDIR/failed + [[ -f $TESTDIR/failed ]] && cat $TESTDIR/failed ls -l $TESTDIR/journal/*/*.journal test -s $TESTDIR/failed && ret=$(($ret+1)) return $ret @@ -35,9 +35,9 @@ run_nspawn() { ../../systemd-nspawn -b -D $TESTDIR/nspawn-root /usr/lib/systemd/systemd ret=1 [[ -e $TESTDIR/nspawn-root/testok ]] && ret=0 - cp -a $TESTDIR/nspawn-root/failed $TESTDIR + [[ -f $TESTDIR/root/failed ]] && cp -a $TESTDIR/nspawn-root/failed $TESTDIR cp -a $TESTDIR/nspawn-root/var/log/journal $TESTDIR - cat $TESTDIR/failed + [[ -f $TESTDIR/failed ]] && cat $TESTDIR/failed ls -l $TESTDIR/journal/*/*.journal test -s $TESTDIR/failed && ret=$(($ret+1)) return $ret -- cgit v1.2.1 From 0a244b8ecb6dfcb381fe831dc2aa9bacb2c12975 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 17 Sep 2013 15:21:00 -0500 Subject: journald: log the slice of a process along with each message in _SYSTEMD_SLICE= --- man/systemd.journal-fields.xml | 19 +++++++++++-------- src/journal/journald-server.c | 6 ++++++ src/journal/journald-server.h | 2 +- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/man/systemd.journal-fields.xml b/man/systemd.journal-fields.xml index cffcccb53e..8a15598e63 100644 --- a/man/systemd.journal-fields.xml +++ b/man/systemd.journal-fields.xml @@ -223,17 +223,20 @@ _SYSTEMD_UNIT= _SYSTEMD_USER_UNIT= _SYSTEMD_OWNER_UID= + _SYSTEMD_SLICE= - The control group path in - the systemd hierarchy, the + The control group path + in the systemd hierarchy, the systemd session ID (if any), - the systemd unit name (if any), - the systemd user session unit name (if any) - and the owner UID of the - systemd session (if any) of - the process the journal entry - originates from. + the systemd unit name (if + any), the systemd user session + unit name (if any), the owner + UID of the systemd session (if + any) and the systemd slice + unit of the process the + journal entry originates + from. diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index ba211b3724..709fa8b7d0 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -638,6 +638,12 @@ static void dispatch_message_real( IOVEC_SET_STRING(iovec[n++], x); } + if (cg_path_get_slice(c, &t) >= 0) { + x = strappenda("_SYSTEMD_SLICE=", t); + free(t); + IOVEC_SET_STRING(iovec[n++], x); + } + free(c); } diff --git a/src/journal/journald-server.h b/src/journal/journald-server.h index e856ef277a..238fc8c3fb 100644 --- a/src/journal/journald-server.h +++ b/src/journal/journald-server.h @@ -125,7 +125,7 @@ typedef struct Server { bool sync_scheduled; } Server; -#define N_IOVEC_META_FIELDS 19 +#define N_IOVEC_META_FIELDS 20 #define N_IOVEC_KERNEL_FIELDS 64 #define N_IOVEC_UDEV_FIELDS 32 #define N_IOVEC_OBJECT_FIELDS 11 -- cgit v1.2.1 From bf24e638afb32ebc49b063c007888410fb9d19bd Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 17 Sep 2013 15:28:22 -0500 Subject: Update TODO --- TODO | 3 +++ 1 file changed, 3 insertions(+) diff --git a/TODO b/TODO index d109e01f71..b5a93b2efe 100644 --- a/TODO +++ b/TODO @@ -58,6 +58,9 @@ CGroup Rework Completion: Features: +* When using "systemd status" on a slice unit also show all messages + matching _SYSTEMD_SLICE= not just _SYSTEMD_UNIT= + * always set memory.user_hierarchy for all cgroups we create * After coming back from hibernation reset hibernation swap partition -- cgit v1.2.1 From 02a36bc9a1769c744f141f127898dbe076dbfd96 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Tue, 17 Sep 2013 15:39:09 -0400 Subject: move utf8 functions from libudev-private.h to utf8.h There's now some more obvious overlap amongst the two utf8 validation functions, but no more than there already was previously. This also adds some menial tests for anyone who wants to do more merging of these two in the future. --- .gitignore | 2 + Makefile.am | 10 +++ src/libudev/libudev-util.c | 171 +-------------------------------------------- src/shared/utf8.c | 151 +++++++++++++++++++++++++++++++++++++++ src/shared/utf8.h | 4 ++ src/test/test-utf8.c | 59 ++++++++++++++++ 6 files changed, 229 insertions(+), 168 deletions(-) create mode 100644 src/test/test-utf8.c diff --git a/.gitignore b/.gitignore index 61bc2a3494..deeee53182 100644 --- a/.gitignore +++ b/.gitignore @@ -124,6 +124,7 @@ /test-list /test-log /test-login +/test-login-shared /test-loopback /test-mmap-cache /test-ns @@ -143,6 +144,7 @@ /test-udev /test-unit-file /test-unit-name +/test-utf8 /test-util /test-watchdog /timedatectl diff --git a/Makefile.am b/Makefile.am index af12fa5912..49c1a1d3c4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1123,6 +1123,7 @@ tests += \ test-strxcpyx \ test-unit-name \ test-unit-file \ + test-utf8 \ test-util \ test-date \ test-sleep \ @@ -1225,6 +1226,15 @@ test_unit_file_CFLAGS = \ test_unit_file_LDADD = \ libsystemd-core.la +test_utf8_SOURCES = \ + src/test/test-utf8.c + +test_utf8_CFLAGS = \ + $(AM_CFLAGS) + +test_utf8_LDADD = \ + libsystemd-shared.la + test_util_SOURCES = \ src/test/test-util.c diff --git a/src/libudev/libudev-util.c b/src/libudev/libudev-util.c index 714dc50ae9..d54430cad0 100644 --- a/src/libudev/libudev-util.c +++ b/src/libudev/libudev-util.c @@ -34,6 +34,7 @@ #include "libudev.h" #include "libudev-private.h" +#include "utf8.h" /** * SECTION:libudev-util @@ -306,129 +307,6 @@ void util_remove_trailing_chars(char *path, char c) path[--len] = '\0'; } -/* count of characters used to encode one unicode char */ -static int utf8_encoded_expected_len(const char *str) -{ - unsigned char c = (unsigned char)str[0]; - - if (c < 0x80) - return 1; - if ((c & 0xe0) == 0xc0) - return 2; - if ((c & 0xf0) == 0xe0) - return 3; - if ((c & 0xf8) == 0xf0) - return 4; - if ((c & 0xfc) == 0xf8) - return 5; - if ((c & 0xfe) == 0xfc) - return 6; - return 0; -} - -/* decode one unicode char */ -static int utf8_encoded_to_unichar(const char *str) -{ - int unichar; - int len; - int i; - - len = utf8_encoded_expected_len(str); - switch (len) { - case 1: - return (int)str[0]; - case 2: - unichar = str[0] & 0x1f; - break; - case 3: - unichar = (int)str[0] & 0x0f; - break; - case 4: - unichar = (int)str[0] & 0x07; - break; - case 5: - unichar = (int)str[0] & 0x03; - break; - case 6: - unichar = (int)str[0] & 0x01; - break; - default: - return -1; - } - - for (i = 1; i < len; i++) { - if (((int)str[i] & 0xc0) != 0x80) - return -1; - unichar <<= 6; - unichar |= (int)str[i] & 0x3f; - } - - return unichar; -} - -/* expected size used to encode one unicode char */ -static int utf8_unichar_to_encoded_len(int unichar) -{ - if (unichar < 0x80) - return 1; - if (unichar < 0x800) - return 2; - if (unichar < 0x10000) - return 3; - if (unichar < 0x200000) - return 4; - if (unichar < 0x4000000) - return 5; - return 6; -} - -/* check if unicode char has a valid numeric range */ -static int utf8_unichar_valid_range(int unichar) -{ - if (unichar > 0x10ffff) - return 0; - if ((unichar & 0xfffff800) == 0xd800) - return 0; - if ((unichar > 0xfdcf) && (unichar < 0xfdf0)) - return 0; - if ((unichar & 0xffff) == 0xffff) - return 0; - return 1; -} - -/* validate one encoded unicode char and return its length */ -static int utf8_encoded_valid_unichar(const char *str) -{ - int len; - int unichar; - int i; - - len = utf8_encoded_expected_len(str); - if (len == 0) - return -1; - - /* ascii is valid */ - if (len == 1) - return 1; - - /* check if expected encoded chars are available */ - for (i = 0; i < len; i++) - if ((str[i] & 0x80) != 0x80) - return -1; - - unichar = utf8_encoded_to_unichar(str); - - /* check if encoded length matches encoded value */ - if (utf8_unichar_to_encoded_len(unichar) != len) - return -1; - - /* check if value has valid range */ - if (!utf8_unichar_valid_range(unichar)) - return -1; - - return len; -} - int util_replace_whitespace(const char *str, char *to, size_t len) { size_t i, j; @@ -457,17 +335,6 @@ int util_replace_whitespace(const char *str, char *to, size_t len) return 0; } -static int is_whitelisted(char c, const char *white) -{ - if ((c >= '0' && c <= '9') || - (c >= 'A' && c <= 'Z') || - (c >= 'a' && c <= 'z') || - strchr("#+-.:=@_", c) != NULL || - (white != NULL && strchr(white, c) != NULL)) - return 1; - return 0; -} - /* allow chars in whitelist, plain ascii, hex-escaping and valid utf8 */ int util_replace_chars(char *str, const char *white) { @@ -477,7 +344,7 @@ int util_replace_chars(char *str, const char *white) while (str[i] != '\0') { int len; - if (is_whitelisted(str[i], white)) { + if (is_utf8_encoding_whitelisted(str[i], white)) { i++; continue; } @@ -525,39 +392,7 @@ int util_replace_chars(char *str, const char *white) **/ _public_ int udev_util_encode_string(const char *str, char *str_enc, size_t len) { - size_t i, j; - - if (str == NULL || str_enc == NULL) - return -1; - - for (i = 0, j = 0; str[i] != '\0'; i++) { - int seqlen; - - seqlen = utf8_encoded_valid_unichar(&str[i]); - if (seqlen > 1) { - if (len-j < (size_t)seqlen) - goto err; - memcpy(&str_enc[j], &str[i], seqlen); - j += seqlen; - i += (seqlen-1); - } else if (str[i] == '\\' || !is_whitelisted(str[i], NULL)) { - if (len-j < 4) - goto err; - sprintf(&str_enc[j], "\\x%02x", (unsigned char) str[i]); - j += 4; - } else { - if (len-j < 1) - goto err; - str_enc[j] = str[i]; - j++; - } - } - if (len-j < 1) - goto err; - str_enc[j] = '\0'; - return 0; -err: - return -1; + return udev_encode_string(str, str_enc, len); } /* diff --git a/src/shared/utf8.c b/src/shared/utf8.c index 655cc771d4..1a68394a53 100644 --- a/src/shared/utf8.c +++ b/src/shared/utf8.c @@ -317,3 +317,154 @@ char *utf16_to_utf8(const void *s, size_t length) { return r; } + +/* count of characters used to encode one unicode char */ +static int utf8_encoded_expected_len(const char *str) { + unsigned char c = (unsigned char)str[0]; + + if (c < 0x80) + return 1; + if ((c & 0xe0) == 0xc0) + return 2; + if ((c & 0xf0) == 0xe0) + return 3; + if ((c & 0xf8) == 0xf0) + return 4; + if ((c & 0xfc) == 0xf8) + return 5; + if ((c & 0xfe) == 0xfc) + return 6; + return 0; +} + +/* decode one unicode char */ +static int utf8_encoded_to_unichar(const char *str) { + int unichar; + int len; + int i; + + len = utf8_encoded_expected_len(str); + switch (len) { + case 1: + return (int)str[0]; + case 2: + unichar = str[0] & 0x1f; + break; + case 3: + unichar = (int)str[0] & 0x0f; + break; + case 4: + unichar = (int)str[0] & 0x07; + break; + case 5: + unichar = (int)str[0] & 0x03; + break; + case 6: + unichar = (int)str[0] & 0x01; + break; + default: + return -1; + } + + for (i = 1; i < len; i++) { + if (((int)str[i] & 0xc0) != 0x80) + return -1; + unichar <<= 6; + unichar |= (int)str[i] & 0x3f; + } + + return unichar; +} + +/* expected size used to encode one unicode char */ +static int utf8_unichar_to_encoded_len(int unichar) { + if (unichar < 0x80) + return 1; + if (unichar < 0x800) + return 2; + if (unichar < 0x10000) + return 3; + if (unichar < 0x200000) + return 4; + if (unichar < 0x4000000) + return 5; + return 6; +} + +/* validate one encoded unicode char and return its length */ +int utf8_encoded_valid_unichar(const char *str) { + int len; + int unichar; + int i; + + len = utf8_encoded_expected_len(str); + if (len == 0) + return -1; + + /* ascii is valid */ + if (len == 1) + return 1; + + /* check if expected encoded chars are available */ + for (i = 0; i < len; i++) + if ((str[i] & 0x80) != 0x80) + return -1; + + unichar = utf8_encoded_to_unichar(str); + + /* check if encoded length matches encoded value */ + if (utf8_unichar_to_encoded_len(unichar) != len) + return -1; + + /* check if value has valid range */ + if (!is_unicode_valid(unichar)) + return -1; + + return len; +} + +int is_utf8_encoding_whitelisted(char c, const char *white) { + if ((c >= '0' && c <= '9') || + (c >= 'A' && c <= 'Z') || + (c >= 'a' && c <= 'z') || + strchr("#+-.:=@_", c) != NULL || + (white != NULL && strchr(white, c) != NULL)) + return 1; + return 0; +} + +int udev_encode_string(const char *str, char *str_enc, size_t len) { + size_t i, j; + + if (str == NULL || str_enc == NULL) + return -1; + + for (i = 0, j = 0; str[i] != '\0'; i++) { + int seqlen; + + seqlen = utf8_encoded_valid_unichar(&str[i]); + if (seqlen > 1) { + if (len-j < (size_t)seqlen) + goto err; + memcpy(&str_enc[j], &str[i], seqlen); + j += seqlen; + i += (seqlen-1); + } else if (str[i] == '\\' || !is_utf8_encoding_whitelisted(str[i], NULL)) { + if (len-j < 4) + goto err; + sprintf(&str_enc[j], "\\x%02x", (unsigned char) str[i]); + j += 4; + } else { + if (len-j < 1) + goto err; + str_enc[j] = str[i]; + j++; + } + } + if (len-j < 1) + goto err; + str_enc[j] = '\0'; + return 0; +err: + return -1; +} diff --git a/src/shared/utf8.h b/src/shared/utf8.h index f805ea6b59..7a5608c9ee 100644 --- a/src/shared/utf8.h +++ b/src/shared/utf8.h @@ -34,3 +34,7 @@ char *utf8_filter(const char *s); char *ascii_filter(const char *s); char *utf16_to_utf8(const void *s, size_t length); + +int utf8_encoded_valid_unichar(const char *str); +int is_utf8_encoding_whitelisted(char c, const char *white); +int udev_encode_string(const char *str, char *str_enc, size_t len); diff --git a/src/test/test-utf8.c b/src/test/test-utf8.c new file mode 100644 index 0000000000..d2b9771f4b --- /dev/null +++ b/src/test/test-utf8.c @@ -0,0 +1,59 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Dave Reisner + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + + +#include "utf8.h" +#include "util.h" + +/* helpers for test_udev_encode_string */ +static char *do_encode_string(const char *in) { + size_t out_len = strlen(in) * 4; + char *out = malloc(out_len); + + assert_se(out); + assert_se(udev_encode_string(in, out, out_len) >= 0); + puts(out); + + return out; +} + +static bool expect_encoded_as(const char *in, const char *expected) { + _cleanup_free_ char *encoded = do_encode_string(in); + return streq(encoded, expected); +} + +static void test_udev_encode_string(void) { + assert_se(expect_encoded_as("systemd sucks", "systemd\\x20sucks")); + assert_se(expect_encoded_as("pinkiepie", "pinkiepie")); + assert_se(expect_encoded_as("valíd\\ųtf8", "valíd\\x5cųtf8")); + assert_se(expect_encoded_as("s/ash/ng", "s\\x2fash\\x2fng")); +} + +static void test_utf8_is_valid(void) { + assert_se(utf8_is_valid("ascii is valid unicode")); + assert_se(utf8_is_valid("\341\204\242")); + assert_se(!utf8_is_valid("\341\204")); +} + +int main(int argc, char *argv[]) { + test_utf8_is_valid(); + test_udev_encode_string(); +} -- cgit v1.2.1 From 22f5f6281fc25f43a85938e9dad2480b2595c471 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Tue, 17 Sep 2013 15:47:08 -0400 Subject: Use udev_encode_string in fstab_node_to_udev_node Resolves a longstanding bug which caused this function to wrongly handle (escape) valid utf8 characters. --- src/shared/util.c | 20 +++++++++----------- src/test/test-util.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/src/shared/util.c b/src/shared/util.c index f6f3b18bfc..2b76a5c885 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -73,6 +73,7 @@ #include "hashmap.h" #include "env-util.h" #include "fileio.h" +#include "utf8.h" int saved_argc = 0; char **saved_argv = NULL; @@ -3495,26 +3496,23 @@ int signal_from_string_try_harder(const char *s) { } static char *tag_to_udev_node(const char *tagvalue, const char *by) { - char *dn, *t, *u; - int r; - - /* FIXME: to follow udev's logic 100% we need to leave valid - * UTF8 chars unescaped */ + _cleanup_free_ char *t = NULL, *u = NULL; + char *dn; + size_t enc_len; u = unquote(tagvalue, "\"\'"); if (u == NULL) return NULL; - t = xescape(u, "/ "); - free(u); - + enc_len = strlen(u) * 4; + t = new(char, enc_len); if (t == NULL) return NULL; - r = asprintf(&dn, "/dev/disk/by-%s/%s", by, t); - free(t); + if (udev_encode_string(u, t, enc_len) < 0) + return NULL; - if (r < 0) + if (asprintf(&dn, "/dev/disk/by-%s/%s", by, t) < 0) return NULL; return dn; diff --git a/src/test/test-util.c b/src/test/test-util.c index dd7768d36c..ad13d53de3 100644 --- a/src/test/test-util.c +++ b/src/test/test-util.c @@ -547,6 +547,41 @@ static void test_split_pair(void) { assert_se(streq(b, "=")); } +static void test_fstab_node_to_udev_node(void) { + char *n; + + n = fstab_node_to_udev_node("LABEL=applé/jack"); + puts(n); + assert_se(streq(n, "/dev/disk/by-label/applé\\x2fjack")); + free(n); + + n = fstab_node_to_udev_node("PARTLABEL=pinkié pie"); + puts(n); + assert_se(streq(n, "/dev/disk/by-partlabel/pinkié\\x20pie")); + free(n); + + n = fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535"); + puts(n); + assert_se(streq(n, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535")); + free(n); + + n = fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535"); + puts(n); + assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535")); + free(n); + + + n = fstab_node_to_udev_node("PONIES=awesome"); + puts(n); + assert_se(streq(n, "PONIES=awesome")); + free(n); + + n = fstab_node_to_udev_node("/dev/xda1"); + puts(n); + assert_se(streq(n, "/dev/xda1")); + free(n); +} + int main(int argc, char *argv[]) { test_streq_ptr(); test_first_word(); @@ -582,6 +617,7 @@ int main(int argc, char *argv[]) { test_strrep(); test_parse_user_at_host(); test_split_pair(); + test_fstab_node_to_udev_node(); return 0; } -- cgit v1.2.1 From 9fb3675e7ef0c6b7a1780980e51492c44fd1faaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 17 Sep 2013 15:12:16 -0500 Subject: Use first partition in /proc/swaps for hibernation test It seems that the kernel uses the first configured partition for hibernation. If it is too full, hibernation will fail. Test that directly. --- src/core/swap.c | 7 +---- src/shared/sleep-config.c | 80 +++++++++++++++++++++++++++++++++++++---------- 2 files changed, 64 insertions(+), 23 deletions(-) diff --git a/src/core/swap.c b/src/core/swap.c index 76c7d45006..82bfad187e 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -1074,7 +1074,7 @@ static int swap_load_proc_swaps(Manager *m, bool set_flags) { (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n"); for (i = 1;; i++) { - char *dev = NULL, *d; + _cleanup_free_ char *dev = NULL, *d = NULL; int prio = 0, k; k = fscanf(m->proc_swaps, @@ -1089,19 +1089,14 @@ static int swap_load_proc_swaps(Manager *m, bool set_flags) { break; log_warning("Failed to parse /proc/swaps:%u", i); - free(dev); continue; } d = cunescape(dev); - free(dev); - if (!d) return -ENOMEM; k = swap_process_new_swap(m, d, prio, set_flags); - free(d); - if (k < 0) r = k; } diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c index 148c4dc617..d068bfce3c 100644 --- a/src/shared/sleep-config.c +++ b/src/shared/sleep-config.c @@ -165,24 +165,70 @@ int can_sleep_disk(char **types) { #define HIBERNATION_SWAP_THRESHOLD 0.98 -static bool enough_memory_for_hibernation(void) { - _cleanup_free_ char *active = NULL, *swapfree = NULL; - unsigned long long act, swap; - int r; +static int hibernation_partition_size(size_t *size, size_t *used) { + _cleanup_fclose_ FILE *f; + int i; + + assert(size); + assert(used); + + f = fopen("/proc/swaps", "r"); + if (!f) { + log_full(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, + "Failed to retrieve open /proc/swaps: %m"); + assert(errno > 0); + return -errno; + } - r = get_status_field("/proc/meminfo", "\nSwapFree:", &swapfree); - if (r < 0) { - log_full(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, - "Failed to retrieve SwapFree from /proc/meminfo: %s", strerror(-r)); - return false; + (void) fscanf(f, "%*s %*s %*s %*s %*s\n"); + + for (i = 1;; i++) { + _cleanup_free_ char *dev = NULL, *d = NULL, *type = NULL; + size_t size_field, used_field; + int k; + + k = fscanf(f, + "%ms " /* device/file */ + "%ms " /* type of swap */ + "%zd " /* swap size */ + "%zd " /* used */ + "%*i\n", /* priority */ + &dev, &type, &size_field, &used_field); + if (k != 4) { + if (k == EOF) + break; + + log_warning("Failed to parse /proc/swaps:%u", i); + continue; + } + + d = cunescape(dev); + if (!d) + return -ENOMEM; + + if (!streq(type, "partition")) { + log_debug("Partition %s has type %s, ignoring.", d, type); + continue; + } + + *size = size_field; + *used = used_field; + return 0; } - r = safe_atollu(swapfree, &swap); - if (r < 0) { - log_error("Failed to parse SwapFree from /proc/meminfo: %s: %s", - swapfree, strerror(-r)); + log_debug("No swap partitions were found."); + return -ENOSYS; +} + +static bool enough_memory_for_hibernation(void) { + _cleanup_free_ char *active = NULL; + unsigned long long act; + size_t size, used; + int r; + + r = hibernation_partition_size(&size, &used); + if (r < 0) return false; - } r = get_status_field("/proc/meminfo", "\nActive(anon):", &active); if (r < 0) { @@ -197,9 +243,9 @@ static bool enough_memory_for_hibernation(void) { return false; } - r = act <= swap * HIBERNATION_SWAP_THRESHOLD; - log_debug("Hibernation is %spossible, Active(anon)=%llu kB, SwapFree=%llu kB, threshold=%.2g%%", - r ? "" : "im", act, swap, 100*HIBERNATION_SWAP_THRESHOLD); + r = act <= (size - used) * HIBERNATION_SWAP_THRESHOLD; + log_debug("Hibernation is %spossible, Active(anon)=%llu kB, size=%zu kB, used=%zu kB, threshold=%.2g%%", + r ? "" : "im", act, size, used, 100*HIBERNATION_SWAP_THRESHOLD); return r; } -- cgit v1.2.1 From e9e506ed436859048f6efc3b5962c6809f1a592a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 17 Sep 2013 15:13:18 -0500 Subject: Make test-login and test-sleep output debugging Without a call to log_parse_environment(), things like SYSTEMD_LOG_LEVEL do not work. --- src/login/test-login.c | 9 ++++++++- src/test/test-sleep.c | 12 +++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/login/test-login.c b/src/login/test-login.c index 945cb38be9..228ddb2933 100644 --- a/src/login/test-login.c +++ b/src/login/test-login.c @@ -27,7 +27,7 @@ #include "util.h" #include "strv.h" -int main(int argc, char* argv[]) { +static void test_login(void) { int r, k; uid_t u, u2; char *seat, *type, *class, *display; @@ -215,6 +215,13 @@ int main(int argc, char* argv[]) { } sd_login_monitor_unref(m); +} + +int main(int argc, char* argv[]) { + log_parse_environment(); + log_open(); + + test_login(); return 0; } diff --git a/src/test/test-sleep.c b/src/test/test-sleep.c index 545dfab92c..a1020ad14c 100644 --- a/src/test/test-sleep.c +++ b/src/test/test-sleep.c @@ -29,7 +29,7 @@ #include "sleep-config.h" #include "strv.h" -int main(int argc, char* argv[]) { +static void test_sleep(void) { _cleanup_strv_free_ char **standby = strv_new("standby", NULL), **mem = strv_new("mem", NULL), @@ -52,6 +52,16 @@ int main(int argc, char* argv[]) { log_info("Suspend configured and possible: %s", yes_no(can_sleep("suspend") > 0)); log_info("Hibernation configured and possible: %s", yes_no(can_sleep("hibernate") > 0)); log_info("Hybrid-sleep configured and possible: %s", yes_no(can_sleep("hybrid-sleep") > 0)); +} + +int main(int argc, char* argv[]) { + log_parse_environment(); + log_open(); + + if (getuid() != 0) + log_warning("This program is unlikely to work for unpriviledged users"); + + test_sleep(); return 0; } -- cgit v1.2.1 From d8a110034690bbe50e15455be4427c42dcd59dc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 17 Sep 2013 15:50:49 -0500 Subject: test-fileio: assume that Buffers may be missing --- src/test/test-fileio.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c index 3511f3a3a4..525354b9cb 100644 --- a/src/test/test-fileio.c +++ b/src/test/test-fileio.c @@ -245,7 +245,10 @@ static void test_status_field(void) { puts(p); assert_se(safe_atollu(p, &total) == 0); - assert_se(get_status_field("/proc/meminfo", "\nBuffers:", &s) == 0); + r = get_status_field("/proc/meminfo", "\nBuffers:", &s); + if (r == -ENOENT) + return; + assert(r == 0); puts(s); assert_se(safe_atollu(s, &buffers) == 0); -- cgit v1.2.1 From 265ffa1e05acf12769a64d0734fd2472237c03c5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 17 Sep 2013 16:33:30 -0500 Subject: tmpfiles: add a new "m" line type that adjusts user/group/mode of a file if it exists --- man/systemd-tmpfiles.xml | 2 +- man/tmpfiles.d.xml | 11 +++++++++++ src/tmpfiles/tmpfiles.c | 39 +++++++++++++++++++++++++++++++-------- 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/man/systemd-tmpfiles.xml b/man/systemd-tmpfiles.xml index 281ab3ca25..ba727e1854 100644 --- a/man/systemd-tmpfiles.xml +++ b/man/systemd-tmpfiles.xml @@ -165,7 +165,7 @@ See Also systemd1, - tmpfiles.d5, + tmpfiles.d5 diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml index 1cf899226a..9fc4b7cd8f 100644 --- a/man/tmpfiles.d.xml +++ b/man/tmpfiles.d.xml @@ -155,6 +155,17 @@ L /tmp/foobar - - - - /dev/null Create a block device node if it does not exist yet + + m + If the + specified file path exists + adjust its access mode, group + and user to the specified + values and reset the SELinux + label. If it doesn't exist do + nothing. + + x Ignore a path diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index fb25b77b2b..8122d6af6a 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -69,6 +69,7 @@ typedef enum ItemType { CREATE_SYMLINK = 'L', CREATE_CHAR_DEVICE = 'c', CREATE_BLOCK_DEVICE = 'b', + ADJUST_MODE = 'm', /* These ones take globs */ IGNORE_PATH = 'x', @@ -257,8 +258,8 @@ static int dir_cleanup( dev_t rootdev, bool mountpoint, int maxdepth, - bool keep_this_level) -{ + bool keep_this_level) { + struct dirent *dent; struct timespec times[2]; bool deleted = false; @@ -429,12 +430,16 @@ finish: return r; } -static int item_set_perms(Item *i, const char *path) { +static int item_set_perms_full(Item *i, const char *path, bool ignore_enoent) { + int r; + /* not using i->path directly because it may be a glob */ if (i->mode_set) if (chmod(path, i->mode) < 0) { - log_error("chmod(%s) failed: %m", path); - return -errno; + if (errno != ENOENT || !ignore_enoent) { + log_error("chmod(%s) failed: %m", path); + return -errno; + } } if (i->uid_set || i->gid_set) @@ -442,11 +447,18 @@ static int item_set_perms(Item *i, const char *path) { i->uid_set ? i->uid : (uid_t) -1, i->gid_set ? i->gid : (gid_t) -1) < 0) { - log_error("chown(%s) failed: %m", path); - return -errno; + if (errno != ENOENT || !ignore_enoent) { + log_error("chown(%s) failed: %m", path); + return -errno; + } } - return label_fix(path, false, false); + r = label_fix(path, false, false); + return r == -ENOENT && ignore_enoent ? 0 : r; +} + +static int item_set_perms(Item *i, const char *path) { + return item_set_perms_full(i, path, false); } static int write_one_file(Item *i, const char *path) { @@ -642,6 +654,7 @@ static int create_item(Item *i) { if (r < 0) return r; break; + case WRITE_FILE: r = glob_item(i, write_one_file); if (r < 0) @@ -649,6 +662,13 @@ static int create_item(Item *i) { break; + case ADJUST_MODE: + r = item_set_perms_full(i, i->path, true); + if (r < 0) + return r; + + break; + case TRUNCATE_DIRECTORY: case CREATE_DIRECTORY: @@ -819,6 +839,7 @@ static int remove_item_instance(Item *i, const char *instance) { case RELABEL_PATH: case RECURSIVE_RELABEL_PATH: case WRITE_FILE: + case ADJUST_MODE: break; case REMOVE_PATH: @@ -864,6 +885,7 @@ static int remove_item(Item *i) { case RELABEL_PATH: case RECURSIVE_RELABEL_PATH: case WRITE_FILE: + case ADJUST_MODE: break; case REMOVE_PATH: @@ -1106,6 +1128,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { case RECURSIVE_REMOVE_PATH: case RELABEL_PATH: case RECURSIVE_RELABEL_PATH: + case ADJUST_MODE: break; case CREATE_SYMLINK: -- cgit v1.2.1 From 4608af4333d0f7f5f8e3bc632801b04ef07d246d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 17 Sep 2013 16:42:36 -0500 Subject: journald: avoid NSS in journald In order to avoid a deadlock between journald looking up the "systemd-journal" group name, and nscd (or anyother NSS backing daemon) logging something back to the journal avoid all NSS in journald the same way as we avoid it from PID 1. With this change we rely on the kernel file system logic to adjust the group of created journal files via the SETGID bit on the journal directory. To ensure that it is always set, even after the user created it with a simply "mkdir" on the shell we fix it up via tmpfiles on boot. --- src/journal/journald-server.c | 25 ++----------------------- src/journal/journald-server.h | 3 --- tmpfiles.d/systemd.conf | 3 +++ 3 files changed, 5 insertions(+), 26 deletions(-) diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 709fa8b7d0..cc8ce0dc0d 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -180,25 +180,6 @@ static uint64_t available_space(Server *s, bool verbose) { return s->cached_available_space; } -static void server_read_file_gid(Server *s) { - const char *g = "systemd-journal"; - int r; - - assert(s); - - if (s->file_gid_valid) - return; - - r = get_group_creds(&g, &s->file_gid); - if (r < 0) - log_warning("Failed to resolve '%s' group: %s", g, strerror(-r)); - - /* if we couldn't read the gid, then it will be 0, but that's - * fine and we shouldn't try to resolve the group again, so - * let's just pretend it worked right-away. */ - s->file_gid_valid = true; -} - void server_fix_perms(Server *s, JournalFile *f, uid_t uid) { int r; #ifdef HAVE_ACL @@ -209,11 +190,9 @@ void server_fix_perms(Server *s, JournalFile *f, uid_t uid) { assert(f); - server_read_file_gid(s); - - r = fchmod_and_fchown(f->fd, 0640, 0, s->file_gid); + r = fchmod(f->fd, 0640); if (r < 0) - log_warning("Failed to fix access mode/rights on %s, ignoring: %s", f->path, strerror(-r)); + log_warning("Failed to fix access mode on %s, ignoring: %s", f->path, strerror(-r)); #ifdef HAVE_ACL if (uid <= 0) diff --git a/src/journal/journald-server.h b/src/journal/journald-server.h index 238fc8c3fb..10e9958be0 100644 --- a/src/journal/journald-server.h +++ b/src/journal/journald-server.h @@ -97,9 +97,6 @@ typedef struct Server { usec_t max_file_usec; usec_t oldest_file_usec; - gid_t file_gid; - bool file_gid_valid; - LIST_HEAD(StdoutStream, stdout_streams); unsigned n_stdout_streams; diff --git a/tmpfiles.d/systemd.conf b/tmpfiles.d/systemd.conf index 4924b4ec70..c397c71b75 100644 --- a/tmpfiles.d/systemd.conf +++ b/tmpfiles.d/systemd.conf @@ -23,3 +23,6 @@ d /run/systemd/machines 0755 root root - d /run/systemd/shutdown 0755 root root - F /run/nologin 0644 - - - "System is booting up." + +m /var/log/journal 2755 root systemd-journal - - +m /var/log/journal/%m 2755 root systemd-journal - - -- cgit v1.2.1 From 491d152dbddb85bc8c309ba24133c99219c8d300 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 17 Sep 2013 16:37:42 -0500 Subject: libudev: add missing 'global' to symbol export --- src/libudev/libudev.sym | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libudev/libudev.sym b/src/libudev/libudev.sym index 8e09430aec..1e6f885141 100644 --- a/src/libudev/libudev.sym +++ b/src/libudev/libudev.sym @@ -109,5 +109,6 @@ global: } LIBUDEV_189; LIBUDEV_199 { +global: udev_device_set_sysattr_value; } LIBUDEV_196; -- cgit v1.2.1 From 360e09ea9ad3a8e84e1729ebd2967ab8f7348170 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 17 Sep 2013 17:11:46 -0500 Subject: Update TODO --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index b5a93b2efe..d5b32ac868 100644 --- a/TODO +++ b/TODO @@ -58,6 +58,8 @@ CGroup Rework Completion: Features: +* libdsystemd-bus should expose utf8 validation calls + * When using "systemd status" on a slice unit also show all messages matching _SYSTEMD_SLICE= not just _SYSTEMD_UNIT= -- cgit v1.2.1 From 118ecf32425a590ea266b5c2b6de7962bb242356 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 17 Sep 2013 23:39:04 +0200 Subject: logind: introduce session-devices A session-device is a device that is bound to a seat and used by a session-controller to run the session. This currently includes DRM, fbdev and evdev devices. A session-device can be created via RequestDevice() on the dbus API of the session. You can drop it via ReleaseDevice() again. Once the session is destroyed or you drop control of the session, all session-devices are automatically destroyed. Session devices follow the session "active" state. A device can be active/running or inactive/paused. Whenever a session is not the active session, no session-device of it can be active. That is, if a session is not in foreground, all session-devices are paused. Whenever a session becomes active, all devices are resumed/activated by logind. If it fails, a device may stay paused. With every session-device you request, you also get a file-descriptor back. logind keeps a copy of this fd and uses kernel specific calls to pause/resume the file-descriptors. For example, a DRM fd is muted by logind as long as a given session is not active. Hence, the fd of the application is also muted. Once the session gets active, logind unmutes the fd and the application will get DRM access again. This, however, requires kernel support. DRM devices provide DRM-Master for synchronization, evdev devices have EVIOCREVOKE (pending on linux-input-ML). fbdev devices do not provide such synchronization methods (and never will). Note that for evdev devices, we call EVIOCREVOKE once a session gets inactive. However, this cannot be undone (the fd is still valid but mostly unusable). So we reopen a new fd once the session is activated and send it together with the ResumeDevice() signal. With this infrastructure in place, compositors can now run without CAP_SYS_ADMIN (that is, without being root). They use RequestControl() to acquire a session and listen for devices via udev_monitor. For every device they want to open, they call RequestDevice() on logind. This returns a fd which they can use now. They no longer have to open the devices themselves or call any privileged ioctls. This is all done by logind. Session-switches are still bound to VTs. Hence, compositors will get notified via the usual VT mechanisms and can cleanup their state. Once the VT switch is acknowledged as usual, logind will get notified via sysfs and pause the old-session's devices and resume the devices of the new session. To allow using this infrastructure with systems without VTs, we provide notification signals. logind sends PauseDevice("force") dbus signals to the current session controller for every device that it pauses. And it sends ResumeDevice signals for every device that it resumes. For seats with VTs this is sent _after_ the VT switch is acknowledged. Because the compositor already acknowledged that it cleaned-up all devices. However, for seats without VTs, this is used to notify the active compositor that the session is about to be deactivated. That is, logind sends PauseDevice("force") for each active device and then performs the session-switch. The session-switch changes the "Active" property of the session which can be monitored by the compositor. The new session is activated and the ResumeDevice events are sent. For seats without VTs, this is a forced session-switch. As this is not backwards-compatible (xserver actually crashes, weston drops the related devices, ..) we also provide an acknowledged session-switch. Note that this is never used for sessions with VTs. You use the acknowledged VT-switch on these seats. An acknowledged session switch sends PauseDevice("pause") instead of PauseDevice("force") to the active session. It schedules a short timeout and waits for the session to acknowledge each of them with PauseDeviceComplete(). Once all are acknowledged, or the session ran out of time, a PauseDevice("force") is sent for all remaining active devices and the session switch is performed. Note that this is only partially implemented, yet, as we don't allow multi-session without VTs, yet. A follow up commit will hook it up and implemented the acknowledgements+timeout. The implementation is quite simple. We use major/minor exclusively to identify devices on the bus. On RequestDevice() we retrieve the udev_device from the major/minor and search for an existing "Device" object. If no exists, we create it. This guarantees us that we are notified whenever the device changes seats or is removed. We create a new SessionDevice object and link it to the related Session and Device. Session->devices is a hashtable to lookup SessionDevice objects via major/minor. Device->session_devices is a linked list so we can release all linked session-devices once a device vanishes. Now we only have to hook this up in seat_set_active() so we correctly change device states during session-switches. As mentioned earlier, these are forced state-changes as VTs are currently used exclusively for multi-session implementations. Everything else are hooks to release all session-devices once the controller changes or a session is closed or removed. --- Makefile.am | 2 + src/login/logind-device.c | 4 + src/login/logind-device.h | 2 + src/login/logind-seat.c | 7 +- src/login/logind-session-dbus.c | 126 +++++++++++ src/login/logind-session-device.c | 451 ++++++++++++++++++++++++++++++++++++++ src/login/logind-session-device.h | 59 +++++ src/login/logind-session.c | 27 +++ src/login/logind-session.h | 2 + src/shared/missing.h | 13 ++ 10 files changed, 692 insertions(+), 1 deletion(-) create mode 100644 src/login/logind-session-device.c create mode 100644 src/login/logind-session-device.h diff --git a/Makefile.am b/Makefile.am index 49c1a1d3c4..9b06c28833 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3768,6 +3768,8 @@ libsystemd_logind_core_la_SOURCES = \ src/login/logind-seat.h \ src/login/logind-session.c \ src/login/logind-session.h \ + src/login/logind-session-device.c \ + src/login/logind-session-device.h \ src/login/logind-user.c \ src/login/logind-user.h \ src/login/logind-inhibit.c \ diff --git a/src/login/logind-device.c b/src/login/logind-device.c index 2bcd6a10c5..95c2307baf 100644 --- a/src/login/logind-device.c +++ b/src/login/logind-device.c @@ -67,11 +67,15 @@ void device_free(Device *d) { void device_detach(Device *d) { Seat *s; + SessionDevice *sd; assert(d); if (!d->seat) return; + while ((sd = d->session_devices)) + session_device_free(sd); + s = d->seat; LIST_REMOVE(Device, devices, d->seat->devices, d); d->seat = NULL; diff --git a/src/login/logind-device.h b/src/login/logind-device.h index 315f0e66b0..fa6eda7e55 100644 --- a/src/login/logind-device.h +++ b/src/login/logind-device.h @@ -27,6 +27,7 @@ typedef struct Device Device; #include "util.h" #include "logind.h" #include "logind-seat.h" +#include "logind-session-device.h" struct Device { Manager *manager; @@ -38,6 +39,7 @@ struct Device { dual_timestamp timestamp; LIST_FIELDS(struct Device, devices); + LIST_HEAD(SessionDevice, session_devices); }; Device* device_new(Manager *m, const char *sysfs, bool master); diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c index 3dc529b2b9..f88738ab16 100644 --- a/src/login/logind-seat.c +++ b/src/login/logind-seat.c @@ -246,10 +246,15 @@ int seat_set_active(Seat *s, Session *session) { old_active = s->active; s->active = session; + if (old_active) + session_device_pause_all(old_active); + seat_apply_acls(s, old_active); - if (session && session->started) + if (session && session->started) { session_send_changed(session, "Active\0"); + session_device_resume_all(session); + } if (!session || session->started) seat_send_changed(s, "ActiveSession\0"); diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c index 35bf4480cb..f793f99b77 100644 --- a/src/login/logind-session-dbus.c +++ b/src/login/logind-session-dbus.c @@ -24,6 +24,7 @@ #include "logind.h" #include "logind-session.h" +#include "logind-session-device.h" #include "dbus-common.h" #include "util.h" @@ -44,6 +45,30 @@ " \n" \ " \n" \ " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ @@ -408,6 +433,107 @@ static DBusHandlerResult session_message_dispatch( if (!reply) goto oom; + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "TakeDevice")) { + SessionDevice *sd; + bool b; + dbus_bool_t paused; + uint32_t major, minor; + dev_t dev; + + if (!session_is_controller(s, bus_message_get_sender_with_fallback(message))) + return bus_send_error_reply(connection, message, NULL, -EPERM); + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_UINT32, &major, + DBUS_TYPE_UINT32, &minor, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + dev = makedev(major, minor); + assert_cc(sizeof(unsigned long) >= sizeof(dev_t)); + + sd = hashmap_get(s->devices, ULONG_TO_PTR((unsigned long)dev)); + if (sd) { + /* We don't allow retrieving a device multiple times. + * The related ReleaseDevice call is not ref-counted. + * The caller should use dup() if it requires more than + * one fd (it would be functionally equivalent). */ + return bus_send_error_reply(connection, message, &error, -EBUSY); + } + + r = session_device_new(s, dev, &sd); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) { + session_device_free(sd); + goto oom; + } + + paused = !sd->active; + b = dbus_message_append_args( + reply, + DBUS_TYPE_UNIX_FD, &sd->fd, + DBUS_TYPE_BOOLEAN, &paused, + DBUS_TYPE_INVALID); + if (!b) { + session_device_free(sd); + return bus_send_error_reply(connection, message, NULL, -ENOMEM); + } + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "ReleaseDevice")) { + SessionDevice *sd; + uint32_t major, minor; + + if (!session_is_controller(s, bus_message_get_sender_with_fallback(message))) + return bus_send_error_reply(connection, message, NULL, -EPERM); + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_UINT32, &major, + DBUS_TYPE_UINT32, &minor, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + sd = hashmap_get(s->devices, ULONG_TO_PTR((unsigned long)makedev(major, minor))); + if (!sd) + return bus_send_error_reply(connection, message, NULL, -ENODEV); + + session_device_free(sd); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "PauseDeviceComplete")) { + SessionDevice *sd; + uint32_t major, minor; + + if (!session_is_controller(s, bus_message_get_sender_with_fallback(message))) + return bus_send_error_reply(connection, message, NULL, -EPERM); + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_UINT32, &major, + DBUS_TYPE_UINT32, &minor, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + sd = hashmap_get(s->devices, ULONG_TO_PTR((unsigned long)makedev(major, minor))); + if (!sd) + return bus_send_error_reply(connection, message, NULL, -ENODEV); + + session_device_complete_pause(sd); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + } else { const BusBoundProperties bps[] = { { "org.freedesktop.login1.Session", bus_login_session_properties, s }, diff --git a/src/login/logind-session-device.c b/src/login/logind-session-device.c new file mode 100644 index 0000000000..80fd364139 --- /dev/null +++ b/src/login/logind-session-device.c @@ -0,0 +1,451 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 David Herrmann + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dbus-common.h" +#include "logind-session-device.h" +#include "util.h" +#include "missing.h" + +enum SessionDeviceNotifications { + SESSION_DEVICE_RESUME, + SESSION_DEVICE_TRY_PAUSE, + SESSION_DEVICE_PAUSE, + SESSION_DEVICE_RELEASE, +}; + +static void session_device_notify(SessionDevice *sd, enum SessionDeviceNotifications type) { + _cleanup_dbus_message_unref_ DBusMessage *m = NULL; + _cleanup_free_ char *path = NULL; + const char *t = NULL; + + assert(sd); + + if (!sd->session->controller) + return; + + path = session_bus_path(sd->session); + if (!path) + return; + + m = dbus_message_new_signal(path, + "org.freedesktop.login1.Session", + (type == SESSION_DEVICE_RESUME) ? "ResumeDevice" : "PauseDevice"); + if (!m) + return; + + if (!dbus_message_set_destination(m, sd->session->controller)) + return; + + switch (type) { + case SESSION_DEVICE_RESUME: + if (!dbus_message_append_args(m, + DBUS_TYPE_UINT32, major(sd->dev), + DBUS_TYPE_UINT32, minor(sd->dev), + DBUS_TYPE_UNIX_FD, &sd->fd, + DBUS_TYPE_INVALID)) + return; + break; + case SESSION_DEVICE_TRY_PAUSE: + t = "pause"; + break; + case SESSION_DEVICE_PAUSE: + t = "force"; + break; + case SESSION_DEVICE_RELEASE: + t = "gone"; + break; + default: + return; + } + + if (t && !dbus_message_append_args(m, + DBUS_TYPE_UINT32, major(sd->dev), + DBUS_TYPE_UINT32, minor(sd->dev), + DBUS_TYPE_STRING, &t, + DBUS_TYPE_INVALID)) + return; + + dbus_connection_send(sd->session->manager->bus, m, NULL); +} + +static int sd_eviocrevoke(int fd) { + static bool warned; + int r; + + assert(fd >= 0); + + r = ioctl(fd, EVIOCREVOKE, 1); + if (r < 0) { + r = -errno; + if (r == -EINVAL && !warned) { + warned = true; + log_warning("kernel does not support evdev-revocation"); + } + } + + return 0; +} + +static int sd_drmsetmaster(int fd) { + int r; + + assert(fd >= 0); + + r = ioctl(fd, DRM_IOCTL_SET_MASTER, 0); + if (r < 0) + return -errno; + + return 0; +} + +static int sd_drmdropmaster(int fd) { + int r; + + assert(fd >= 0); + + r = ioctl(fd, DRM_IOCTL_DROP_MASTER, 0); + if (r < 0) + return -errno; + + return 0; +} + +static int session_device_open(SessionDevice *sd, bool active) { + int fd; + + assert(sd->type != DEVICE_TYPE_UNKNOWN); + + /* open device and try to get an udev_device from it */ + fd = open(sd->node, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK); + if (fd < 0) + return -errno; + + switch (sd->type) { + case DEVICE_TYPE_DRM: + if (active) + sd_drmsetmaster(fd); + else { + /* DRM-Master is granted to the first user who opens a + * device automatically (ughh, racy!). Hence, we just + * drop DRM-Master in case we were the first. */ + sd_drmdropmaster(fd); + } + break; + case DEVICE_TYPE_EVDEV: + if (!active) + sd_eviocrevoke(fd); + break; + case DEVICE_TYPE_FBDEV: + case DEVICE_TYPE_UNKNOWN: + default: + /* fallback for devices wihout synchronizations */ + break; + } + + return fd; +} + +static int session_device_start(SessionDevice *sd) { + int r; + + assert(sd); + assert(session_is_active(sd->session)); + + if (sd->active) + return 0; + + switch (sd->type) { + case DEVICE_TYPE_DRM: + /* Device is kept open. Simply call drmSetMaster() and hope + * there is no-one else. In case it fails, we keep the device + * paused. Maybe at some point we have a drmStealMaster(). */ + r = sd_drmsetmaster(sd->fd); + if (r < 0) + return r; + break; + case DEVICE_TYPE_EVDEV: + /* Evdev devices are revoked while inactive. Reopen it and we + * are fine. */ + r = session_device_open(sd, true); + if (r < 0) + return r; + close_nointr_nofail(sd->fd); + sd->fd = r; + break; + case DEVICE_TYPE_FBDEV: + /* fbdev devices have no way to synchronize access. Moreover, + * they mostly operate through mmaps() without any pageflips + * and modesetting, so there is no way for us to prevent access + * but tear down mmaps. + * That would be quite expensive to do on a per-fd context. So + * ignore legcy fbdev and let its users feel the pain they asked + * for when deciding for fbdev. */ + case DEVICE_TYPE_UNKNOWN: + default: + /* fallback for devices wihout synchronizations */ + break; + } + + sd->active = true; + return 0; +} + +static void session_device_stop(SessionDevice *sd) { + assert(sd); + + if (!sd->active) + return; + + switch (sd->type) { + case DEVICE_TYPE_DRM: + /* On DRM devices we simply drop DRM-Master but keep it open. + * This allows the user to keep resources allocated. The + * CAP_SYS_ADMIN restriction to DRM-Master prevents users from + * circumventing this. */ + sd_drmdropmaster(sd->fd); + break; + case DEVICE_TYPE_EVDEV: + /* Revoke access on evdev file-descriptors during deactivation. + * This will basically prevent any operations on the fd and + * cannot be undone. Good side is: it needs no CAP_SYS_ADMIN + * protection this way. */ + sd_eviocrevoke(sd->fd); + break; + case DEVICE_TYPE_FBDEV: + case DEVICE_TYPE_UNKNOWN: + default: + /* fallback for devices without synchronization */ + break; + } + + sd->active = false; +} + +static DeviceType detect_device_type(struct udev_device *dev) { + const char *sysname, *subsystem; + DeviceType type; + + sysname = udev_device_get_sysname(dev); + subsystem = udev_device_get_subsystem(dev); + type = DEVICE_TYPE_UNKNOWN; + + if (streq_ptr(subsystem, "graphics")) { + if (!streq(sysname, "fbcon") && startswith(sysname, "fb")) + type = DEVICE_TYPE_FBDEV; + } else if (streq_ptr(subsystem, "drm")) { + if (startswith(sysname, "card")) + type = DEVICE_TYPE_DRM; + } else if (streq_ptr(subsystem, "input")) { + if (startswith(sysname, "event")) + type = DEVICE_TYPE_EVDEV; + } + + return type; +} + +static int session_device_verify(SessionDevice *sd) { + struct udev_device *dev, *p = NULL; + const char *sp, *node; + int r; + + dev = udev_device_new_from_devnum(sd->session->manager->udev, 'c', sd->dev); + if (!dev) + return -ENODEV; + + sp = udev_device_get_syspath(dev); + node = udev_device_get_devnode(dev); + if (!node) { + r = -EINVAL; + goto err_dev; + } + + /* detect device type so we can find the correct sysfs parent */ + sd->type = detect_device_type(dev); + if (sd->type == DEVICE_TYPE_UNKNOWN) { + r = -ENODEV; + goto err_dev; + } else if (sd->type == DEVICE_TYPE_EVDEV) { + /* for evdev devices we need the parent node as device */ + p = dev; + dev = udev_device_get_parent_with_subsystem_devtype(p, "input", NULL); + if (!dev) { + r = -ENODEV; + goto err_dev; + } + sp = udev_device_get_syspath(dev); + } else if (sd->type != DEVICE_TYPE_FBDEV && + sd->type != DEVICE_TYPE_DRM) { + /* Prevent opening unsupported devices. Especially devices of + * subsystem "input" must be opened via the evdev node as + * we require EVIOCREVOKE. */ + r = -ENODEV; + goto err_dev; + } + + /* search for an existing seat device and return it if available */ + sd->device = hashmap_get(sd->session->manager->devices, sp); + if (!sd->device) { + /* The caller might have gotten the udev event before we were + * able to process it. Hence, fake the "add" event and let the + * logind-manager handle the new device. */ + r = manager_process_seat_device(sd->session->manager, dev); + if (r < 0) + goto err_dev; + + /* if it's still not available, then the device is invalid */ + sd->device = hashmap_get(sd->session->manager->devices, sp); + if (!sd->device) { + r = -ENODEV; + goto err_dev; + } + } + + if (sd->device->seat != sd->session->seat) { + r = -EPERM; + goto err_dev; + } + + sd->node = strdup(node); + if (!sd->node) { + r = -ENOMEM; + goto err_dev; + } + + r = 0; +err_dev: + udev_device_unref(p ? : dev); + return r; +} + +int session_device_new(Session *s, dev_t dev, SessionDevice **out) { + SessionDevice *sd; + int r; + + assert(s); + assert(out); + + if (!s->seat) + return -EPERM; + + sd = new0(SessionDevice, 1); + if (!sd) + return -ENOMEM; + + sd->session = s; + sd->dev = dev; + sd->fd = -1; + sd->type = DEVICE_TYPE_UNKNOWN; + + r = session_device_verify(sd); + if (r < 0) + goto error; + + assert_cc(sizeof(unsigned long) >= sizeof(dev_t)); + + r = hashmap_put(s->devices, ULONG_TO_PTR((unsigned long)sd->dev), sd); + if (r < 0) { + r = -ENOMEM; + goto error; + } + + /* Open the device for the first time. We need a valid fd to pass back + * to the caller. If the session is not active, this _might_ immediately + * revoke access and thus invalidate the fd. But this is still needed + * to pass a valid fd back. */ + sd->active = session_is_active(s); + sd->fd = session_device_open(sd, sd->active); + if (sd->fd < 0) + goto error; + + LIST_PREPEND(SessionDevice, sd_by_device, sd->device->session_devices, sd); + + *out = sd; + return 0; + +error: + hashmap_remove(s->devices, ULONG_TO_PTR((unsigned long)sd->dev)); + free(sd->node); + free(sd); + return r; +} + +void session_device_free(SessionDevice *sd) { + assert(sd); + + session_device_stop(sd); + session_device_notify(sd, SESSION_DEVICE_RELEASE); + close_nointr_nofail(sd->fd); + + LIST_REMOVE(SessionDevice, sd_by_device, sd->device->session_devices, sd); + + hashmap_remove(sd->session->devices, ULONG_TO_PTR((unsigned long)sd->dev)); + + free(sd->node); + free(sd); +} + +void session_device_complete_pause(SessionDevice *sd) { + if (!sd->active) + return; + + session_device_stop(sd); +} + +void session_device_resume_all(Session *s) { + SessionDevice *sd; + Iterator i; + int r; + + assert(s); + + HASHMAP_FOREACH(sd, s->devices, i) { + if (!sd->active) { + r = session_device_start(sd); + if (!r) + session_device_notify(sd, SESSION_DEVICE_RESUME); + } + } +} + +void session_device_pause_all(Session *s) { + SessionDevice *sd; + Iterator i; + + assert(s); + + HASHMAP_FOREACH(sd, s->devices, i) { + if (sd->active) { + session_device_stop(sd); + session_device_notify(sd, SESSION_DEVICE_PAUSE); + } + } +} diff --git a/src/login/logind-session-device.h b/src/login/logind-session-device.h new file mode 100644 index 0000000000..511fce0e61 --- /dev/null +++ b/src/login/logind-session-device.h @@ -0,0 +1,59 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2013 David Herrmann + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +typedef enum DeviceType DeviceType; +typedef struct SessionDevice SessionDevice; + +#include "list.h" +#include "util.h" +#include "logind.h" +#include "logind-device.h" +#include "logind-seat.h" +#include "logind-session.h" + +enum DeviceType { + DEVICE_TYPE_UNKNOWN, + DEVICE_TYPE_FBDEV, + DEVICE_TYPE_DRM, + DEVICE_TYPE_EVDEV, +}; + +struct SessionDevice { + Session *session; + Device *device; + + dev_t dev; + char *node; + int fd; + bool active; + DeviceType type; + + LIST_FIELDS(struct SessionDevice, sd_by_device); +}; + +int session_device_new(Session *s, dev_t dev, SessionDevice **out); +void session_device_free(SessionDevice *sd); +void session_device_complete_pause(SessionDevice *sd); + +void session_device_resume_all(Session *s); +void session_device_pause_all(Session *s); diff --git a/src/login/logind-session.c b/src/login/logind-session.c index f856127eae..fcc1901ed6 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -53,9 +53,17 @@ Session* session_new(Manager *m, const char *id) { return NULL; } + s->devices = hashmap_new(trivial_hash_func, trivial_compare_func); + if (!s->devices) { + free(s->state_file); + free(s); + return NULL; + } + s->id = path_get_file_name(s->state_file); if (hashmap_put(m->sessions, s->id, s) < 0) { + hashmap_free(s->devices); free(s->state_file); free(s); return NULL; @@ -68,6 +76,8 @@ Session* session_new(Manager *m, const char *id) { } void session_free(Session *s) { + SessionDevice *sd; + assert(s); if (s->in_gc_queue) @@ -75,6 +85,11 @@ void session_free(Session *s) { session_drop_controller(s); + while ((sd = hashmap_first(s->devices))) + session_device_free(sd); + + hashmap_free(s->devices); + if (s->user) { LIST_REMOVE(Session, sessions_by_user, s->user->sessions, s); @@ -612,6 +627,7 @@ int session_stop(Session *s) { int session_finalize(Session *s) { int r = 0; + SessionDevice *sd; assert(s); @@ -627,6 +643,10 @@ int session_finalize(Session *s) { "MESSAGE=Removed session %s.", s->id, NULL); + /* Kill session devices */ + while ((sd = hashmap_first(s->devices))) + session_device_free(sd); + /* Remove X11 symlink */ session_unlink_x11_socket(s); @@ -950,6 +970,8 @@ int session_set_controller(Session *s, const char *sender, bool force) { } void session_drop_controller(Session *s) { + SessionDevice *sd; + assert(s); if (!s->controller) @@ -958,6 +980,11 @@ void session_drop_controller(Session *s) { manager_drop_busname(s->manager, s->controller); free(s->controller); s->controller = NULL; + + /* Drop all devices as they're now unused. Do that after the controller + * is released to avoid sending out useles dbus signals. */ + while ((sd = hashmap_first(s->devices))) + session_device_free(sd); } static const char* const session_state_table[_SESSION_STATE_MAX] = { diff --git a/src/login/logind-session.h b/src/login/logind-session.h index 839fb230dc..f175a8995e 100644 --- a/src/login/logind-session.h +++ b/src/login/logind-session.h @@ -28,6 +28,7 @@ typedef enum KillWho KillWho; #include "util.h" #include "logind.h" #include "logind-seat.h" +#include "logind-session-device.h" #include "logind-user.h" #include "login-shared.h" @@ -107,6 +108,7 @@ struct Session { DBusMessage *create_message; char *controller; + Hashmap *devices; LIST_FIELDS(Session, sessions_by_user); LIST_FIELDS(Session, sessions_by_seat); diff --git a/src/shared/missing.h b/src/shared/missing.h index d1ca135c55..6c038d9f08 100644 --- a/src/shared/missing.h +++ b/src/shared/missing.h @@ -29,6 +29,7 @@ #include #include #include +#include #ifdef HAVE_AUDIT #include @@ -310,3 +311,15 @@ static inline int name_to_handle_at(int fd, const char *name, struct file_handle #ifndef SO_REUSEPORT #define SO_REUSEPORT 15 #endif + +#ifndef EVIOCREVOKE +#define EVIOCREVOKE _IOW('E', 0x91, int) +#endif + +#ifndef DRM_IOCTL_SET_MASTER +#define DRM_IOCTL_SET_MASTER _IO('d', 0x1e) +#endif + +#ifndef DRM_IOCTL_DROP_MASTER +#define DRM_IOCTL_DROP_MASTER _IO('d', 0x1f) +#endif -- cgit v1.2.1 From d7bd01b547bd91353513131561de9cc7d9f7d405 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 17 Sep 2013 23:40:19 +0200 Subject: logind: implement generic multi-session This enables the multi-session capability for seats that don't have VTs. For legacy seats with VTs, everything stays the same. However, all other seats now also get the multi-session capability. The only feature that was missing was session-switching. As logind can force a session-switch and signal that via the "Active" property, we only need a way to allow synchronized/delayed session switches. Compositors need to cleanup some devices before acknowledging the session switch. Therefore, we use the session-devices to give compositors a chance to block a session-switch until they cleaned everything up. If you activate a session on a seat without VTs, we send a PauseDevice signal to the active session for every active device. Only once the session acknowledged all these with a PauseDeviceComplete() call, we perform the final session switch. One important note is that delayed session-switching is meant for backwards compatibility. New compositors or other sessions should really try to deal correctly with forced session switches! They only need to handle EACCES/EPERM from syscalls and treat them as "PauseDevice" signal. Following logind patches will add a timeout to session-switches which forces the switch if the active session does not react in a timely fashion. Moreover, explicit ForceActivate() calls might also be supported. Hence, sessions must not crash if their devices get paused. --- src/login/logind-seat.c | 15 +++++++++++++++ src/login/logind-seat.h | 2 ++ src/login/logind-session-device.c | 28 ++++++++++++++++++++++++++++ src/login/logind-session-device.h | 1 + src/login/logind-session.c | 31 ++++++++++++++++++++++++++----- 5 files changed, 72 insertions(+), 5 deletions(-) diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c index f88738ab16..4a4d40adca 100644 --- a/src/login/logind-seat.c +++ b/src/login/logind-seat.c @@ -425,6 +425,21 @@ int seat_attach_session(Seat *s, Session *session) { return 0; } +void seat_complete_switch(Seat *s) { + Session *session; + + assert(s); + + /* if no session-switch is pending or if it got canceled, do nothing */ + if (!s->pending_switch) + return; + + session = s->pending_switch; + s->pending_switch = NULL; + + seat_set_active(s, session); +} + bool seat_has_vts(Seat *s) { assert(s); diff --git a/src/login/logind-seat.h b/src/login/logind-seat.h index d3438b8495..be6db6eed1 100644 --- a/src/login/logind-seat.h +++ b/src/login/logind-seat.h @@ -38,6 +38,7 @@ struct Seat { LIST_HEAD(Device, devices); Session *active; + Session *pending_switch; LIST_HEAD(Session, sessions); bool in_gc_queue:1; @@ -59,6 +60,7 @@ int seat_read_active_vt(Seat *s); int seat_preallocate_vts(Seat *s); int seat_attach_session(Seat *s, Session *session); +void seat_complete_switch(Seat *s); bool seat_has_vts(Seat *s); bool seat_is_seat0(Seat *s); diff --git a/src/login/logind-session-device.c b/src/login/logind-session-device.c index 80fd364139..e92bb54fff 100644 --- a/src/login/logind-session-device.c +++ b/src/login/logind-session-device.c @@ -414,10 +414,21 @@ void session_device_free(SessionDevice *sd) { } void session_device_complete_pause(SessionDevice *sd) { + SessionDevice *iter; + Iterator i; + if (!sd->active) return; session_device_stop(sd); + + /* if not all devices are paused, wait for further completion events */ + HASHMAP_FOREACH(iter, sd->session->devices, i) + if (iter->active) + return; + + /* complete any pending session switch */ + seat_complete_switch(sd->session->seat); } void session_device_resume_all(Session *s) { @@ -449,3 +460,20 @@ void session_device_pause_all(Session *s) { } } } + +unsigned int session_device_try_pause_all(Session *s) { + SessionDevice *sd; + Iterator i; + unsigned int num_pending = 0; + + assert(s); + + HASHMAP_FOREACH(sd, s->devices, i) { + if (sd->active) { + session_device_notify(sd, SESSION_DEVICE_TRY_PAUSE); + ++num_pending; + } + } + + return num_pending; +} diff --git a/src/login/logind-session-device.h b/src/login/logind-session-device.h index 511fce0e61..eac7ca7a63 100644 --- a/src/login/logind-session-device.h +++ b/src/login/logind-session-device.h @@ -57,3 +57,4 @@ void session_device_complete_pause(SessionDevice *sd); void session_device_resume_all(Session *s); void session_device_pause_all(Session *s); +unsigned int session_device_try_pause_all(Session *s); diff --git a/src/login/logind-session.c b/src/login/logind-session.c index fcc1901ed6..eea0bfb85b 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -100,6 +100,8 @@ void session_free(Session *s) { if (s->seat) { if (s->seat->active == s) s->seat->active = NULL; + if (s->seat->pending_switch == s) + s->seat->pending_switch = NULL; LIST_REMOVE(Session, sessions_by_seat, s->seat->sessions, s); } @@ -375,21 +377,40 @@ int session_load(Session *s) { } int session_activate(Session *s) { + unsigned int num_pending; + assert(s); assert(s->user); - if (s->vtnr <= 0) - return -ENOTSUP; - if (!s->seat) return -ENOTSUP; if (s->seat->active == s) return 0; - assert(seat_has_vts(s->seat)); + /* on seats with VTs, we let VTs manage session-switching */ + if (seat_has_vts(s->seat)) { + if (s->vtnr <= 0) + return -ENOTSUP; + + return chvt(s->vtnr); + } - return chvt(s->vtnr); + /* On seats without VTs, we implement session-switching in logind. We + * try to pause all session-devices and wait until the session + * controller acknowledged them. Once all devices are asleep, we simply + * switch the active session and be done. + * We save the session we want to switch to in seat->pending_switch and + * seat_complete_switch() will perform the final switch. */ + + s->seat->pending_switch = s; + + /* if no devices are running, immediately perform the session switch */ + num_pending = session_device_try_pause_all(s); + if (!num_pending) + seat_complete_switch(s->seat); + + return 0; } static int session_link_x11_socket(Session *s) { -- cgit v1.2.1 From ef5bfcf668e6029faa78534dfeb2591df854cdef Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 17 Sep 2013 17:28:35 -0500 Subject: backlight,random-seed: move state files into /var/lib/systemd Let's not scatter (private) files in /var around, let's place them all in /var/lib/systemd and below. --- Makefile.am | 4 ++-- TODO | 2 -- src/backlight/backlight.c | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/Makefile.am b/Makefile.am index 9b06c28833..8d70ad3e5a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -159,7 +159,7 @@ AM_CPPFLAGS = \ -DSYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH=\"$(rootbindir)/systemd-tty-ask-password-agent\" \ -DSYSTEMD_STDIO_BRIDGE_BINARY_PATH=\"$(bindir)/systemd-stdio-bridge\" \ -DROOTPREFIX=\"$(rootprefix)\" \ - -DRANDOM_SEED=\"$(localstatedir)/lib/random-seed\" \ + -DRANDOM_SEED=\"$(localstatedir)/lib/systemd/random-seed\" \ -DSYSTEMD_CRYPTSETUP_PATH=\"$(rootlibexecdir)/systemd-cryptsetup\" \ -DSYSTEM_GENERATOR_PATH=\"$(systemgeneratordir)\" \ -DUSER_GENERATOR_PATH=\"$(usergeneratordir)\" \ @@ -4213,7 +4213,7 @@ substitutions = \ '|PACKAGE_VERSION=$(PACKAGE_VERSION)|' \ '|PACKAGE_NAME=$(PACKAGE_NAME)|' \ '|PACKAGE_URL=$(PACKAGE_URL)|' \ - '|RANDOM_SEED=$(localstatedir)/lib/random-seed|' \ + '|RANDOM_SEED=$(localstatedir)/lib/systemd/random-seed|' \ '|prefix=$(prefix)|' \ '|exec_prefix=$(exec_prefix)|' \ '|libdir=$(libdir)|' \ diff --git a/TODO b/TODO index d5b32ac868..c0f51de28e 100644 --- a/TODO +++ b/TODO @@ -72,8 +72,6 @@ Features: interate through that to bring down complexity from O(n^2) to O(n) when loading units -* Move backlight and random-seed into /var/lib/systemd - * If we try to find a unit via a dangling symlink generate a clean error. Currently we just ignore it and read the unit from the search path anyway. diff --git a/src/backlight/backlight.c b/src/backlight/backlight.c index 1ef0b45cc6..9b2eada397 100644 --- a/src/backlight/backlight.c +++ b/src/backlight/backlight.c @@ -42,7 +42,7 @@ int main(int argc, char *argv[]) { umask(0022); - r = mkdir_p("/var/lib/backlight", 0755); + r = mkdir_p("/var/lib/systemd/backlight", 0755); if (r < 0) { log_error("Failed to create backlight directory: %s", strerror(-r)); goto finish; @@ -72,7 +72,7 @@ int main(int argc, char *argv[]) { goto finish; } - saved = strappend("/var/lib/backlight/", udev_device_get_sysname(device)); + saved = strappend("/var/lib/systemd/backlight/", udev_device_get_sysname(device)); if (!saved) { r = log_oom(); goto finish; -- cgit v1.2.1 From 3db604b907323b8df0fc810216f6112056d26a02 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 17 Sep 2013 18:04:40 -0500 Subject: gpt-auto-generator: do not assume that /dev/block/%u:%u is useable The generator might run before udev, and udev sets up the /dev/block/ symlinks, hence we cannot use them from the gpt generator. Instead, manually translate a major/minor to a device node. --- src/gpt-auto-generator/gpt-auto-generator.c | 109 +++++++++++++++++++--------- 1 file changed, 74 insertions(+), 35 deletions(-) diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index 880661e277..ca54925da4 100644 --- a/src/gpt-auto-generator/gpt-auto-generator.c +++ b/src/gpt-auto-generator/gpt-auto-generator.c @@ -55,18 +55,13 @@ static inline void blkid_free_probep(blkid_probe *b) { } #define _cleanup_blkid_freep_probe_ _cleanup_(blkid_free_probep) -static int verify_gpt_partition(dev_t dev, sd_id128_t *type, unsigned *nr, char **fstype) { - _cleanup_free_ char *t = NULL; +static int verify_gpt_partition(const char *node, sd_id128_t *type, unsigned *nr, char **fstype) { _cleanup_blkid_freep_probe_ blkid_probe b = NULL; const char *v; int r; - r = asprintf(&t, "/dev/block/%u:%u", major(dev), minor(dev)); - if (r < 0) - return -ENOMEM; - errno = 0; - b = blkid_new_probe_from_filename(t); + b = blkid_new_probe_from_filename(node); if (!b) return errno != 0 ? -errno : -ENOMEM; @@ -237,8 +232,7 @@ static int add_home(const char *path, const char *fstype) { return 0; } -static int enumerate_partitions(dev_t dev) { - struct udev *udev; +static int enumerate_partitions(struct udev *udev, dev_t dev) { struct udev_enumerate *e = NULL; struct udev_device *parent = NULL, *d = NULL; struct udev_list_entry *first, *item; @@ -246,10 +240,6 @@ static int enumerate_partitions(dev_t dev) { _cleanup_free_ char *home = NULL, *home_fstype = NULL; int r; - udev = udev_new(); - if (!udev) - return log_oom(); - e = udev_enumerate_new(udev); if (!e) { r = log_oom(); @@ -294,7 +284,6 @@ static int enumerate_partitions(dev_t dev) { struct udev_device *q; sd_id128_t type_id; unsigned nr; - dev_t sub; q = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item)); if (!q) { @@ -314,12 +303,10 @@ static int enumerate_partitions(dev_t dev) { goto finish; } - sub = udev_device_get_devnum(q); - - r = verify_gpt_partition(sub, &type_id, &nr, &fstype); + r = verify_gpt_partition(node, &type_id, &nr, &fstype); if (r < 0) { - log_error("Failed to verify GPT partition /dev/block/%u:%u: %s", - major(sub), minor(sub), strerror(-r)); + log_error("Failed to verify GPT partition %s: %s", + node, strerror(-r)); udev_device_unref(q); goto finish; } @@ -360,8 +347,6 @@ finish: if (e) udev_enumerate_unref(e); - if (udev) - udev_unref(udev); return r; } @@ -440,13 +425,50 @@ static int get_block_device(const char *path, dev_t *dev) { return 0; } +static int devno_to_devnode(struct udev *udev, dev_t devno, char **ret) { + struct udev_device *d = NULL; + const char *t; + char *n; + int r; + + d = udev_device_new_from_devnum(udev, 'b', devno); + if (!d) { + r = log_oom(); + goto finish; + } + + t = udev_device_get_devnode(d); + if (!t) { + r = -ENODEV; + goto finish; + } + + n = strdup(t); + if (!n) { + r = -ENOMEM; + goto finish; + } + + *ret = n; + r = 0; + +finish: + if (d) + udev_device_unref(d); + + return r; +} + int main(int argc, char *argv[]) { - dev_t dev; + _cleanup_free_ char *node = NULL; + struct udev *udev = NULL; + dev_t devno; int r; if (argc > 1 && argc != 4) { log_error("This program takes three or no arguments."); - return EXIT_FAILURE; + r = -EINVAL; + goto finish; } if (argc > 1) @@ -458,31 +480,48 @@ int main(int argc, char *argv[]) { umask(0022); - if (in_initrd()) - return EXIT_SUCCESS; + if (in_initrd()) { + r = 0; + goto finish; + } - r = get_block_device("/", &dev); + r = get_block_device("/", &devno); if (r < 0) { log_error("Failed to determine block device of root file system: %s", strerror(-r)); - return EXIT_FAILURE; + goto finish; } if (r == 0) { log_debug("Root file system not on a (single) block device."); - return EXIT_SUCCESS; + goto finish; + } + + udev = udev_new(); + if (!udev) { + r = log_oom(); + goto finish; + } + + r = devno_to_devnode(udev, devno, &node); + if (r < 0) { + log_error("Failed to determine block device node from major/minor: %s", strerror(-r)); + goto finish; } - log_debug("Root device /dev/block/%u:%u.", major(dev), minor(dev)); + log_debug("Root device %s.", node); - r = verify_gpt_partition(dev, NULL, NULL, NULL); + r = verify_gpt_partition(node, NULL, NULL, NULL); if (r < 0) { - log_error("Failed to verify GPT partition /dev/block/%u:%u: %s", - major(dev), minor(dev), strerror(-r)); - return EXIT_FAILURE; + log_error("Failed to verify GPT partition %s: %s", node, strerror(-r)); + goto finish; } if (r == 0) - return EXIT_SUCCESS; + goto finish; + + r = enumerate_partitions(udev, devno); - r = enumerate_partitions(dev); +finish: + if (udev) + udev_unref(udev); return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; } -- cgit v1.2.1 From 831dedef66dbf2650a9dc41263e624fe08f3bb7a Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Wed, 18 Sep 2013 01:00:02 +0200 Subject: logind: fix build for ARM with sizeof(dev_t) > sizeof(void*) Unfortunately on ARM-32 systems dev_t can be 64bit and thus we cannot store it easily in void* keys for hashtables. Fix that by passing a pointer to the dev_t variable instead. --- src/login/logind-session-dbus.c | 12 +++++++----- src/login/logind-session-device.c | 8 +++----- src/login/logind-session.c | 17 ++++++++++++++++- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c index f793f99b77..5f6bafbc6a 100644 --- a/src/login/logind-session-dbus.c +++ b/src/login/logind-session-dbus.c @@ -452,9 +452,7 @@ static DBusHandlerResult session_message_dispatch( return bus_send_error_reply(connection, message, &error, -EINVAL); dev = makedev(major, minor); - assert_cc(sizeof(unsigned long) >= sizeof(dev_t)); - - sd = hashmap_get(s->devices, ULONG_TO_PTR((unsigned long)dev)); + sd = hashmap_get(s->devices, &dev); if (sd) { /* We don't allow retrieving a device multiple times. * The related ReleaseDevice call is not ref-counted. @@ -487,6 +485,7 @@ static DBusHandlerResult session_message_dispatch( } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "ReleaseDevice")) { SessionDevice *sd; uint32_t major, minor; + dev_t dev; if (!session_is_controller(s, bus_message_get_sender_with_fallback(message))) return bus_send_error_reply(connection, message, NULL, -EPERM); @@ -499,7 +498,8 @@ static DBusHandlerResult session_message_dispatch( DBUS_TYPE_INVALID)) return bus_send_error_reply(connection, message, &error, -EINVAL); - sd = hashmap_get(s->devices, ULONG_TO_PTR((unsigned long)makedev(major, minor))); + dev = makedev(major, minor); + sd = hashmap_get(s->devices, &dev); if (!sd) return bus_send_error_reply(connection, message, NULL, -ENODEV); @@ -512,6 +512,7 @@ static DBusHandlerResult session_message_dispatch( } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "PauseDeviceComplete")) { SessionDevice *sd; uint32_t major, minor; + dev_t dev; if (!session_is_controller(s, bus_message_get_sender_with_fallback(message))) return bus_send_error_reply(connection, message, NULL, -EPERM); @@ -524,7 +525,8 @@ static DBusHandlerResult session_message_dispatch( DBUS_TYPE_INVALID)) return bus_send_error_reply(connection, message, &error, -EINVAL); - sd = hashmap_get(s->devices, ULONG_TO_PTR((unsigned long)makedev(major, minor))); + dev = makedev(major, minor); + sd = hashmap_get(s->devices, &dev); if (!sd) return bus_send_error_reply(connection, message, NULL, -ENODEV); diff --git a/src/login/logind-session-device.c b/src/login/logind-session-device.c index e92bb54fff..b45f9ebe0c 100644 --- a/src/login/logind-session-device.c +++ b/src/login/logind-session-device.c @@ -369,9 +369,7 @@ int session_device_new(Session *s, dev_t dev, SessionDevice **out) { if (r < 0) goto error; - assert_cc(sizeof(unsigned long) >= sizeof(dev_t)); - - r = hashmap_put(s->devices, ULONG_TO_PTR((unsigned long)sd->dev), sd); + r = hashmap_put(s->devices, &sd->dev, sd); if (r < 0) { r = -ENOMEM; goto error; @@ -392,7 +390,7 @@ int session_device_new(Session *s, dev_t dev, SessionDevice **out) { return 0; error: - hashmap_remove(s->devices, ULONG_TO_PTR((unsigned long)sd->dev)); + hashmap_remove(s->devices, &sd->dev); free(sd->node); free(sd); return r; @@ -407,7 +405,7 @@ void session_device_free(SessionDevice *sd) { LIST_REMOVE(SessionDevice, sd_by_device, sd->device->session_devices, sd); - hashmap_remove(sd->session->devices, ULONG_TO_PTR((unsigned long)sd->dev)); + hashmap_remove(sd->session->devices, &sd->dev); free(sd->node); free(sd); diff --git a/src/login/logind-session.c b/src/login/logind-session.c index eea0bfb85b..ce982efed4 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -36,6 +36,21 @@ #include "dbus-common.h" #include "logind-session.h" +static unsigned devt_hash_func(const void *p) { + uint64_t u = *(const dev_t*)p; + + return uint64_hash_func(&u); +} + +static int devt_compare_func(const void *_a, const void *_b) { + dev_t a, b; + + a = *(const dev_t*) _a; + b = *(const dev_t*) _b; + + return a < b ? -1 : (a > b ? 1 : 0); +} + Session* session_new(Manager *m, const char *id) { Session *s; @@ -53,7 +68,7 @@ Session* session_new(Manager *m, const char *id) { return NULL; } - s->devices = hashmap_new(trivial_hash_func, trivial_compare_func); + s->devices = hashmap_new(devt_hash_func, devt_compare_func); if (!s->devices) { free(s->state_file); free(s); -- cgit v1.2.1 From 1dc2ced4646a78b3dee9e3ea44130f938d6425bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 17 Sep 2013 17:30:47 -0500 Subject: Remove six unused variables and add annotation clang FTW! --- src/fstab-generator/fstab-generator.c | 4 ++-- src/journal/test-journal-interleaving.c | 2 +- src/login/logind-dbus.c | 1 - src/login/logind-session.c | 1 - src/machine/machined-dbus.c | 2 -- 5 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index b73dfa4899..9efccb983d 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -64,7 +64,7 @@ static int mount_find_pri(struct mntent *me, int *ret) { } static int add_swap(const char *what, struct mntent *me) { - _cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL, *device = NULL; + _cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL; _cleanup_fclose_ FILE *f = NULL; bool noauto; int r, pri = -1; @@ -159,7 +159,7 @@ static int add_mount( const char *post, const char *source) { _cleanup_free_ char - *name = NULL, *unit = NULL, *lnk = NULL, *device = NULL, + *name = NULL, *unit = NULL, *lnk = NULL, *automount_name = NULL, *automount_unit = NULL; _cleanup_fclose_ FILE *f = NULL; diff --git a/src/journal/test-journal-interleaving.c b/src/journal/test-journal-interleaving.c index 2b21523f57..1a058eaedd 100644 --- a/src/journal/test-journal-interleaving.c +++ b/src/journal/test-journal-interleaving.c @@ -36,7 +36,7 @@ static bool arg_keep = false; -static void log_assert_errno(const char *text, int eno, const char *file, int line, const char *func) { +_noreturn_ static void log_assert_errno(const char *text, int eno, const char *file, int line, const char *func) { log_meta(LOG_CRIT, file, line, func, "'%s' failed at %s:%u (%s): %s.", text, file, line, func, strerror(eno)); diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index fd8ee1b801..ec590c0c56 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -2395,7 +2395,6 @@ DBusHandlerResult bus_message_filter( } else if (dbus_message_is_signal(message, "org.freedesktop.DBus.Properties", "PropertiesChanged")) { - _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; _cleanup_free_ char *unit = NULL; const char *path; diff --git a/src/login/logind-session.c b/src/login/logind-session.c index ce982efed4..27aa335142 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -259,7 +259,6 @@ int session_load(Session *s) { *seat = NULL, *vtnr = NULL, *leader = NULL, - *audit_id = NULL, *type = NULL, *class = NULL, *uid = NULL, diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c index 5a016e76bc..a526a5243e 100644 --- a/src/machine/machined-dbus.c +++ b/src/machine/machined-dbus.c @@ -117,7 +117,6 @@ static bool valid_machine_name(const char *p) { static int bus_manager_create_machine(Manager *manager, DBusMessage *message) { const char *name, *service, *class, *root_directory; - _cleanup_free_ char *p = NULL; DBusMessageIter iter, sub; MachineClass c; uint32_t leader; @@ -560,7 +559,6 @@ DBusHandlerResult bus_message_filter( } else if (dbus_message_is_signal(message, "org.freedesktop.DBus.Properties", "PropertiesChanged")) { - _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; _cleanup_free_ char *unit = NULL; const char *path; -- cgit v1.2.1 From 0a7b53bdd2bb36c9543830c087954f184cd06535 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 17 Sep 2013 18:34:47 -0500 Subject: util: restore get_process_capeff behaviour 69ab8088 unified parsing of status files and removed the logic of skipping extra '0's when getting the effective capabilities. Restore that logic, so that the same capabilities are always mapped to the same strings in the journal. --- src/shared/fileio.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/shared/fileio.c b/src/shared/fileio.c index 4e2b4442db..23bc742e75 100644 --- a/src/shared/fileio.c +++ b/src/shared/fileio.c @@ -650,9 +650,9 @@ int executable_is_script(const char *path, char **interpreter) { } /** - * Retrieve one field from a file like /proc/self/status. - * pattern should start with '\n' and end with ':'. Whitespace - * after ':' will be skipped. field must be freed afterwards. + * Retrieve one field from a file like /proc/self/status. pattern + * should start with '\n' and end with a ':'. Whitespace and zeros + * after the ':' will be skipped. field must be freed afterwards. */ int get_status_field(const char *filename, const char *pattern, char **field) { _cleanup_free_ char *status = NULL; @@ -672,7 +672,12 @@ int get_status_field(const char *filename, const char *pattern, char **field) { return -ENOENT; t += strlen(pattern); - t += strspn(t, WHITESPACE); + /* Also skip zeros, because when this is used for capabilities, + * we don't want the zeros. This way the same cabality set + * always maps to the same string, irrespective of the total + * capability set size. For other numbers it shouldn't matter. + */ + t += strspn(t, WHITESPACE "0"); len = strcspn(t, WHITESPACE); -- cgit v1.2.1 From 00f117a59973f9c4e1a966252d668949f62a9265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 18 Sep 2013 08:36:27 -0500 Subject: logs-show.c: fix enum type in function declaration --- src/shared/logs-show.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index f50777c58d..2dd5025bc3 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -105,7 +105,7 @@ static bool shall_print(const char *p, size_t l, OutputFlags flags) { return true; } -static bool print_multiline(FILE *f, unsigned prefix, unsigned n_columns, OutputMode flags, int priority, const char* message, size_t message_len) { +static bool print_multiline(FILE *f, unsigned prefix, unsigned n_columns, OutputFlags flags, int priority, const char* message, size_t message_len) { const char *color_on = "", *color_off = ""; const char *pos, *end; bool ellipsized = false; -- cgit v1.2.1 From 72fd713962ca2c2450e23b01d9e22017a7e28fd4 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 22 Aug 2013 13:55:21 -0400 Subject: polkit: Avoid race condition in scraping /proc If a calling process execve()s a setuid program, it can appear to be uid 0. Since we're receiving requests over DBus, avoid this by simply passing system-bus-name as a subject. --- src/shared/polkit.c | 31 +++++-------------------------- 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/src/shared/polkit.c b/src/shared/polkit.c index cea7074ad3..1c5e9e3e0f 100644 --- a/src/shared/polkit.c +++ b/src/shared/polkit.c @@ -38,12 +38,8 @@ int verify_polkit( #ifdef ENABLE_POLKIT DBusMessage *m = NULL, *reply = NULL; - const char *unix_process = "unix-process", *pid = "pid", *starttime = "start-time", *cancel_id = ""; + const char *system_bus_name = "system-bus-name", *name = "name", *cancel_id = ""; uint32_t flags = interactive ? 1 : 0; - pid_t pid_raw; - uint32_t pid_u32; - unsigned long long starttime_raw; - uint64_t starttime_u64; DBusMessageIter iter_msg, iter_struct, iter_array, iter_dict, iter_variant; int r; dbus_bool_t authorized = FALSE, challenge = FALSE; @@ -68,14 +64,6 @@ int verify_polkit( #ifdef ENABLE_POLKIT - pid_raw = bus_get_unix_process_id(c, sender, error); - if (pid_raw == 0) - return -EINVAL; - - r = get_starttime_of_pid(pid_raw, &starttime_raw); - if (r < 0) - return r; - m = dbus_message_new_method_call( "org.freedesktop.PolicyKit1", "/org/freedesktop/PolicyKit1/Authority", @@ -86,22 +74,13 @@ int verify_polkit( dbus_message_iter_init_append(m, &iter_msg); - pid_u32 = (uint32_t) pid_raw; - starttime_u64 = (uint64_t) starttime_raw; - if (!dbus_message_iter_open_container(&iter_msg, DBUS_TYPE_STRUCT, NULL, &iter_struct) || - !dbus_message_iter_append_basic(&iter_struct, DBUS_TYPE_STRING, &unix_process) || + !dbus_message_iter_append_basic(&iter_struct, DBUS_TYPE_STRING, &system_bus_name) || !dbus_message_iter_open_container(&iter_struct, DBUS_TYPE_ARRAY, "{sv}", &iter_array) || !dbus_message_iter_open_container(&iter_array, DBUS_TYPE_DICT_ENTRY, NULL, &iter_dict) || - !dbus_message_iter_append_basic(&iter_dict, DBUS_TYPE_STRING, &pid) || - !dbus_message_iter_open_container(&iter_dict, DBUS_TYPE_VARIANT, "u", &iter_variant) || - !dbus_message_iter_append_basic(&iter_variant, DBUS_TYPE_UINT32, &pid_u32) || - !dbus_message_iter_close_container(&iter_dict, &iter_variant) || - !dbus_message_iter_close_container(&iter_array, &iter_dict) || - !dbus_message_iter_open_container(&iter_array, DBUS_TYPE_DICT_ENTRY, NULL, &iter_dict) || - !dbus_message_iter_append_basic(&iter_dict, DBUS_TYPE_STRING, &starttime) || - !dbus_message_iter_open_container(&iter_dict, DBUS_TYPE_VARIANT, "t", &iter_variant) || - !dbus_message_iter_append_basic(&iter_variant, DBUS_TYPE_UINT64, &starttime_u64) || + !dbus_message_iter_append_basic(&iter_dict, DBUS_TYPE_STRING, &name) || + !dbus_message_iter_open_container(&iter_dict, DBUS_TYPE_VARIANT, "s", &iter_variant) || + !dbus_message_iter_append_basic(&iter_variant, DBUS_TYPE_STRING, &sender) || !dbus_message_iter_close_container(&iter_dict, &iter_variant) || !dbus_message_iter_close_container(&iter_array, &iter_dict) || !dbus_message_iter_close_container(&iter_struct, &iter_array) || -- cgit v1.2.1 From 4ec29144ddc311d78baa6875631ed6968fd90817 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 18 Sep 2013 11:39:32 -0500 Subject: Fix capability logging when effective caps are 0 Shawn Landen> Doesn't this also skip the last '0' when it is all '0's? You need to keep the last one. --- src/shared/fileio.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/shared/fileio.c b/src/shared/fileio.c index 23bc742e75..8aa4cdbf05 100644 --- a/src/shared/fileio.c +++ b/src/shared/fileio.c @@ -677,7 +677,13 @@ int get_status_field(const char *filename, const char *pattern, char **field) { * always maps to the same string, irrespective of the total * capability set size. For other numbers it shouldn't matter. */ - t += strspn(t, WHITESPACE "0"); + if (*t) { + t += strspn(t, WHITESPACE "0"); + /* Back off one char if there's nothing but whitespace + and zeros */ + if (!*t) + t --; + } len = strcspn(t, WHITESPACE); -- cgit v1.2.1 From c22428fb73acab46a74c6ed069f03f4fd86c7ae2 Mon Sep 17 00:00:00 2001 From: David Strauss Date: Wed, 18 Sep 2013 15:46:51 -0500 Subject: Spelling fix from later revision of committed patch from Shawn Landden . --- src/shared/fileio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/fileio.c b/src/shared/fileio.c index 8aa4cdbf05..01b803c82f 100644 --- a/src/shared/fileio.c +++ b/src/shared/fileio.c @@ -673,7 +673,7 @@ int get_status_field(const char *filename, const char *pattern, char **field) { t += strlen(pattern); /* Also skip zeros, because when this is used for capabilities, - * we don't want the zeros. This way the same cabality set + * we don't want the zeros. This way the same capability set * always maps to the same string, irrespective of the total * capability set size. For other numbers it shouldn't matter. */ -- cgit v1.2.1 From f4d213c15b92c2a420a2f4fc13d4959071c22b82 Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Thu, 19 Sep 2013 15:52:31 +0400 Subject: clarify $ escaping in Exec* lines Explain that literal $ can be passed by doubling it. --- man/systemd.service.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/man/systemd.service.xml b/man/systemd.service.xml index 8eda85f62d..c06e14efc2 100644 --- a/man/systemd.service.xml +++ b/man/systemd.service.xml @@ -369,7 +369,8 @@ case it will be replaced by the value of the environment variable split up at whitespace, resulting in zero or - more arguments. Note that the first + more arguments. To pass literal dollar sign + use $$. Note that the first argument (i.e. the program to execute) may not be a variable, since it must be a literal and absolute path -- cgit v1.2.1 From 894a156de7cace3210a60c29cfa14934fdea41ea Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Thu, 19 Sep 2013 11:36:40 -0400 Subject: udev-builtin-blkid: export ID_PART_TABLE_UUID --- src/udev/udev-builtin-blkid.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/udev/udev-builtin-blkid.c b/src/udev/udev-builtin-blkid.c index bae429344f..b48dccc2fb 100644 --- a/src/udev/udev-builtin-blkid.c +++ b/src/udev/udev-builtin-blkid.c @@ -67,6 +67,9 @@ static void print_property(struct udev_device *dev, bool test, const char *name, } else if (streq(name, "PTTYPE")) { udev_builtin_add_property(dev, test, "ID_PART_TABLE_TYPE", value); + } else if (streq(name, "PTUUID")) { + udev_builtin_add_property(dev, test, "ID_PART_TABLE_UUID", value); + } else if (streq(name, "PART_ENTRY_NAME")) { blkid_encode_string(value, s, sizeof(s)); udev_builtin_add_property(dev, test, "ID_PART_ENTRY_NAME", s); -- cgit v1.2.1 From 7991ac34ab08421415b907e42775c5539a4a5bbb Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Wed, 18 Sep 2013 11:52:14 -0400 Subject: shared/utf8: merge implementations, remove cruft This unifies the utf8 handling code which was previously duplicated in udev and systemd. --- TODO | 1 - src/shared/utf8.c | 279 +++++++++++++-------------------------------------- src/shared/utf8.h | 3 +- src/test/test-utf8.c | 9 ++ 4 files changed, 81 insertions(+), 211 deletions(-) diff --git a/TODO b/TODO index c0f51de28e..01bc993e0f 100644 --- a/TODO +++ b/TODO @@ -602,7 +602,6 @@ Features: * udev: - remove src/udev/udev-builtin-firmware.c (CONFIG_FW_LOADER_USER_HELPER=n) - move to LGPL - - unify utf8 validator code with shared/ - kill scsi_id - add trigger --subsystem-match=usb/usb_device device diff --git a/src/shared/utf8.c b/src/shared/utf8.c index 1a68394a53..732f0f00ca 100644 --- a/src/shared/utf8.c +++ b/src/shared/utf8.c @@ -51,8 +51,6 @@ #include "utf8.h" #include "util.h" -#define FILTER_CHAR '_' - static inline bool is_unicode_valid(uint32_t ch) { if (ch >= 0x110000) /* End of unicode space */ @@ -67,17 +65,6 @@ static inline bool is_unicode_valid(uint32_t ch) { return true; } -static inline bool is_continuation_char(uint8_t ch) { - if ((ch & 0xc0) != 0x80) /* 10xxxxxx */ - return false; - return true; -} - -static inline void merge_continuation_char(uint32_t *u_ch, uint8_t ch) { - *u_ch <<= 6; - *u_ch |= ch & 0x3f; -} - static bool is_unicode_control(uint32_t ch) { /* @@ -90,163 +77,97 @@ static bool is_unicode_control(uint32_t ch) { (0x7F <= ch && ch <= 0x9F); } -bool utf8_is_printable(const char* str, size_t length) { - uint32_t val = 0; - uint32_t min = 0; - const uint8_t *p; +/* count of characters used to encode one unicode char */ +static int utf8_encoded_expected_len(const char *str) { + unsigned char c = (unsigned char)str[0]; - assert(str); + if (c < 0x80) + return 1; + if ((c & 0xe0) == 0xc0) + return 2; + if ((c & 0xf0) == 0xe0) + return 3; + if ((c & 0xf8) == 0xf0) + return 4; + if ((c & 0xfc) == 0xf8) + return 5; + if ((c & 0xfe) == 0xfc) + return 6; + return 0; +} - for (p = (const uint8_t*) str; length; p++, length--) { - if (*p < 128) { - val = *p; - } else { - if ((*p & 0xe0) == 0xc0) { /* 110xxxxx two-char seq. */ - min = 128; - val = (uint32_t) (*p & 0x1e); - goto ONE_REMAINING; - } else if ((*p & 0xf0) == 0xe0) { /* 1110xxxx three-char seq.*/ - min = (1 << 11); - val = (uint32_t) (*p & 0x0f); - goto TWO_REMAINING; - } else if ((*p & 0xf8) == 0xf0) { /* 11110xxx four-char seq */ - min = (1 << 16); - val = (uint32_t) (*p & 0x07); - } else - return false; - - p++; - length--; - if (!length || !is_continuation_char(*p)) - return false; - merge_continuation_char(&val, *p); - - TWO_REMAINING: - p++; - length--; - if (!is_continuation_char(*p)) - return false; - merge_continuation_char(&val, *p); - - ONE_REMAINING: - p++; - length--; - if (!is_continuation_char(*p)) - return false; - merge_continuation_char(&val, *p); - - if (val < min) - return false; - } +/* decode one unicode char */ +static int utf8_encoded_to_unichar(const char *str) { + int unichar; + int len; + int i; - if (is_unicode_control(val)) - return false; + len = utf8_encoded_expected_len(str); + switch (len) { + case 1: + return (int)str[0]; + case 2: + unichar = str[0] & 0x1f; + break; + case 3: + unichar = (int)str[0] & 0x0f; + break; + case 4: + unichar = (int)str[0] & 0x07; + break; + case 5: + unichar = (int)str[0] & 0x03; + break; + case 6: + unichar = (int)str[0] & 0x01; + break; + default: + return -1; } - return true; + for (i = 1; i < len; i++) { + if (((int)str[i] & 0xc0) != 0x80) + return -1; + unichar <<= 6; + unichar |= (int)str[i] & 0x3f; + } + + return unichar; } -static char* utf8_validate(const char *str, char *output) { - uint32_t val = 0; - uint32_t min = 0; - const uint8_t *p, *last; - int size; - uint8_t *o; +bool utf8_is_printable(const char* str, size_t length) { + const uint8_t *p; assert(str); - o = (uint8_t*) output; - for (p = (const uint8_t*) str; *p; p++) { - if (*p < 128) { - if (o) - *o = *p; - } else { - last = p; - - if ((*p & 0xe0) == 0xc0) { /* 110xxxxx two-char seq. */ - size = 2; - min = 128; - val = (uint32_t) (*p & 0x1e); - goto ONE_REMAINING; - } else if ((*p & 0xf0) == 0xe0) { /* 1110xxxx three-char seq.*/ - size = 3; - min = (1 << 11); - val = (uint32_t) (*p & 0x0f); - goto TWO_REMAINING; - } else if ((*p & 0xf8) == 0xf0) { /* 11110xxx four-char seq */ - size = 4; - min = (1 << 16); - val = (uint32_t) (*p & 0x07); - } else - goto error; - - p++; - if (!is_continuation_char(*p)) - goto error; - merge_continuation_char(&val, *p); - - TWO_REMAINING: - p++; - if (!is_continuation_char(*p)) - goto error; - merge_continuation_char(&val, *p); - - ONE_REMAINING: - p++; - if (!is_continuation_char(*p)) - goto error; - merge_continuation_char(&val, *p); - - if (val < min) - goto error; - - if (!is_unicode_valid(val)) - goto error; - - if (o) { - memcpy(o, last, (size_t) size); - o += size; - } - - continue; - - error: - if (o) { - *o = FILTER_CHAR; - p = last; /* We retry at the next character */ - } else - goto failure; - } + for (p = (const uint8_t*) str; length; p++) { + int encoded_len = utf8_encoded_valid_unichar((const char *)p); + int32_t val = utf8_encoded_to_unichar((const char*)p); - if (o) - o++; - } + if (encoded_len < 0 || val < 0 || is_unicode_control(val)) + return false; - if (o) { - *o = '\0'; - return output; + length -= encoded_len; } - return (char*) str; - -failure: - return NULL; -} - -char* utf8_is_valid (const char *str) { - return utf8_validate(str, NULL); + return true; } -char* utf8_filter (const char *str) { - char *new_str; +const char *utf8_is_valid(const char *str) { + const uint8_t *p; assert(str); - new_str = malloc(strlen(str) + 1); - if (!new_str) - return NULL; + for (p = (const uint8_t*) str; *p; ) { + int len = utf8_encoded_valid_unichar((const char *)p); + + if (len < 0) + return NULL; + + p += len; + } - return utf8_validate(str, new_str); + return str; } char *ascii_is_valid(const char *str) { @@ -318,64 +239,6 @@ char *utf16_to_utf8(const void *s, size_t length) { return r; } -/* count of characters used to encode one unicode char */ -static int utf8_encoded_expected_len(const char *str) { - unsigned char c = (unsigned char)str[0]; - - if (c < 0x80) - return 1; - if ((c & 0xe0) == 0xc0) - return 2; - if ((c & 0xf0) == 0xe0) - return 3; - if ((c & 0xf8) == 0xf0) - return 4; - if ((c & 0xfc) == 0xf8) - return 5; - if ((c & 0xfe) == 0xfc) - return 6; - return 0; -} - -/* decode one unicode char */ -static int utf8_encoded_to_unichar(const char *str) { - int unichar; - int len; - int i; - - len = utf8_encoded_expected_len(str); - switch (len) { - case 1: - return (int)str[0]; - case 2: - unichar = str[0] & 0x1f; - break; - case 3: - unichar = (int)str[0] & 0x0f; - break; - case 4: - unichar = (int)str[0] & 0x07; - break; - case 5: - unichar = (int)str[0] & 0x03; - break; - case 6: - unichar = (int)str[0] & 0x01; - break; - default: - return -1; - } - - for (i = 1; i < len; i++) { - if (((int)str[i] & 0xc0) != 0x80) - return -1; - unichar <<= 6; - unichar |= (int)str[i] & 0x3f; - } - - return unichar; -} - /* expected size used to encode one unicode char */ static int utf8_unichar_to_encoded_len(int unichar) { if (unichar < 0x80) diff --git a/src/shared/utf8.h b/src/shared/utf8.h index 7a5608c9ee..22e13461de 100644 --- a/src/shared/utf8.h +++ b/src/shared/utf8.h @@ -25,12 +25,11 @@ #include "macro.h" -char *utf8_is_valid(const char *s) _pure_; +const char *utf8_is_valid(const char *s) _pure_; char *ascii_is_valid(const char *s) _pure_; bool utf8_is_printable(const char* str, size_t length) _pure_; -char *utf8_filter(const char *s); char *ascii_filter(const char *s); char *utf16_to_utf8(const void *s, size_t length); diff --git a/src/test/test-utf8.c b/src/test/test-utf8.c index d2b9771f4b..26cc37bd6e 100644 --- a/src/test/test-utf8.c +++ b/src/test/test-utf8.c @@ -47,6 +47,12 @@ static void test_udev_encode_string(void) { assert_se(expect_encoded_as("s/ash/ng", "s\\x2fash\\x2fng")); } +static void test_utf8_is_printable(void) { + assert_se(utf8_is_printable("ascii is valid\tunicode", 22)); + assert_se(utf8_is_printable("\342\204\242", 3)); + assert_se(!utf8_is_printable("\341\204", 2)); +} + static void test_utf8_is_valid(void) { assert_se(utf8_is_valid("ascii is valid unicode")); assert_se(utf8_is_valid("\341\204\242")); @@ -55,5 +61,8 @@ static void test_utf8_is_valid(void) { int main(int argc, char *argv[]) { test_utf8_is_valid(); + test_utf8_is_printable(); test_udev_encode_string(); + + return 0; } -- cgit v1.2.1 From 8f6ce71fe79d897b67157d92869db87ee2042af6 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Wed, 18 Sep 2013 12:12:04 -0400 Subject: device-nodes: move device node specific code to own file In the process, rename udev_encode_string which is poorly named for what it does. It deals specifically with encoding names that udev creates and has its own rules: utf8 is valid but some ascii is not (e.g. path separators), and everything else is simply escaped. Rename it to encode_devnode_name. --- .gitignore | 1 + Makefile.am | 14 ++++++++- src/libudev/libudev-util.c | 5 +-- src/shared/device-nodes.c | 74 ++++++++++++++++++++++++++++++++++++++++++++ src/shared/device-nodes.h | 23 ++++++++++++++ src/shared/utf8.c | 46 --------------------------- src/shared/utf8.h | 2 -- src/shared/util.c | 4 +-- src/test/test-device-nodes.c | 55 ++++++++++++++++++++++++++++++++ src/test/test-utf8.c | 28 +---------------- 10 files changed, 172 insertions(+), 80 deletions(-) create mode 100644 src/shared/device-nodes.c create mode 100644 src/shared/device-nodes.h create mode 100644 src/test/test-device-nodes.c diff --git a/.gitignore b/.gitignore index deeee53182..8115d4d0e8 100644 --- a/.gitignore +++ b/.gitignore @@ -101,6 +101,7 @@ /test-cgroup-util /test-daemon /test-date +/test-device-nodes /test-efivars /test-engine /test-env-replace diff --git a/Makefile.am b/Makefile.am index 8d70ad3e5a..89a5c86357 100644 --- a/Makefile.am +++ b/Makefile.am @@ -642,6 +642,8 @@ libsystemd_shared_la_SOURCES = \ src/shared/list.h \ src/shared/macro.h \ src/shared/def.h \ + src/shared/device-nodes.c \ + src/shared/device-nodes.h \ src/shared/sparse-endian.h \ src/shared/util.c \ src/shared/util.h \ @@ -1137,7 +1139,8 @@ tests += \ test-time \ test-hashmap \ test-list \ - test-tables + test-tables \ + test-device-nodes EXTRA_DIST += \ test/sched_idle_bad.service \ @@ -1149,6 +1152,15 @@ EXTRA_DIST += \ EXTRA_DIST += \ src/test/test-helper.h +test_device_nodes_SOURCES = \ + src/test/test-device-nodes.c + +test_device_nodes_CFLAGS = \ + $(AM_CFLAGS) + +test_device_nodes_LDADD = \ + libsystemd-shared.la + test_engine_SOURCES = \ src/test/test-engine.c diff --git a/src/libudev/libudev-util.c b/src/libudev/libudev-util.c index d54430cad0..b5b9db67fc 100644 --- a/src/libudev/libudev-util.c +++ b/src/libudev/libudev-util.c @@ -32,6 +32,7 @@ #include #include +#include "device-nodes.h" #include "libudev.h" #include "libudev-private.h" #include "utf8.h" @@ -344,7 +345,7 @@ int util_replace_chars(char *str, const char *white) while (str[i] != '\0') { int len; - if (is_utf8_encoding_whitelisted(str[i], white)) { + if (whitelisted_char_for_devnode(str[i], white)) { i++; continue; } @@ -392,7 +393,7 @@ int util_replace_chars(char *str, const char *white) **/ _public_ int udev_util_encode_string(const char *str, char *str_enc, size_t len) { - return udev_encode_string(str, str_enc, len); + return encode_devnode_name(str, str_enc, len); } /* diff --git a/src/shared/device-nodes.c b/src/shared/device-nodes.c new file mode 100644 index 0000000000..986553e93f --- /dev/null +++ b/src/shared/device-nodes.c @@ -0,0 +1,74 @@ +/*-*- 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 Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include + +#include "device-nodes.h" +#include "utf8.h" + +int whitelisted_char_for_devnode(char c, const char *white) { + if ((c >= '0' && c <= '9') || + (c >= 'A' && c <= 'Z') || + (c >= 'a' && c <= 'z') || + strchr("#+-.:=@_", c) != NULL || + (white != NULL && strchr(white, c) != NULL)) + return 1; + return 0; +} + +int encode_devnode_name(const char *str, char *str_enc, size_t len) { + size_t i, j; + + if (str == NULL || str_enc == NULL) + return -1; + + for (i = 0, j = 0; str[i] != '\0'; i++) { + int seqlen; + + seqlen = utf8_encoded_valid_unichar(&str[i]); + if (seqlen > 1) { + if (len-j < (size_t)seqlen) + goto err; + memcpy(&str_enc[j], &str[i], seqlen); + j += seqlen; + i += (seqlen-1); + } else if (str[i] == '\\' || !whitelisted_char_for_devnode(str[i], NULL)) { + if (len-j < 4) + goto err; + sprintf(&str_enc[j], "\\x%02x", (unsigned char) str[i]); + j += 4; + } else { + if (len-j < 1) + goto err; + str_enc[j] = str[i]; + j++; + } + } + if (len-j < 1) + goto err; + str_enc[j] = '\0'; + return 0; +err: + return -1; +} diff --git a/src/shared/device-nodes.h b/src/shared/device-nodes.h new file mode 100644 index 0000000000..a98195afa9 --- /dev/null +++ b/src/shared/device-nodes.h @@ -0,0 +1,23 @@ +/*-*- 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 Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +int encode_devnode_name(const char *str, char *str_enc, size_t len); +int whitelisted_char_for_devnode(char c, const char *additional); diff --git a/src/shared/utf8.c b/src/shared/utf8.c index 732f0f00ca..c3d97cc783 100644 --- a/src/shared/utf8.c +++ b/src/shared/utf8.c @@ -285,49 +285,3 @@ int utf8_encoded_valid_unichar(const char *str) { return len; } - -int is_utf8_encoding_whitelisted(char c, const char *white) { - if ((c >= '0' && c <= '9') || - (c >= 'A' && c <= 'Z') || - (c >= 'a' && c <= 'z') || - strchr("#+-.:=@_", c) != NULL || - (white != NULL && strchr(white, c) != NULL)) - return 1; - return 0; -} - -int udev_encode_string(const char *str, char *str_enc, size_t len) { - size_t i, j; - - if (str == NULL || str_enc == NULL) - return -1; - - for (i = 0, j = 0; str[i] != '\0'; i++) { - int seqlen; - - seqlen = utf8_encoded_valid_unichar(&str[i]); - if (seqlen > 1) { - if (len-j < (size_t)seqlen) - goto err; - memcpy(&str_enc[j], &str[i], seqlen); - j += seqlen; - i += (seqlen-1); - } else if (str[i] == '\\' || !is_utf8_encoding_whitelisted(str[i], NULL)) { - if (len-j < 4) - goto err; - sprintf(&str_enc[j], "\\x%02x", (unsigned char) str[i]); - j += 4; - } else { - if (len-j < 1) - goto err; - str_enc[j] = str[i]; - j++; - } - } - if (len-j < 1) - goto err; - str_enc[j] = '\0'; - return 0; -err: - return -1; -} diff --git a/src/shared/utf8.h b/src/shared/utf8.h index 22e13461de..96a03ea7cb 100644 --- a/src/shared/utf8.h +++ b/src/shared/utf8.h @@ -35,5 +35,3 @@ char *ascii_filter(const char *s); char *utf16_to_utf8(const void *s, size_t length); int utf8_encoded_valid_unichar(const char *str); -int is_utf8_encoding_whitelisted(char c, const char *white); -int udev_encode_string(const char *str, char *str_enc, size_t len); diff --git a/src/shared/util.c b/src/shared/util.c index 2b76a5c885..200955376e 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -73,7 +73,7 @@ #include "hashmap.h" #include "env-util.h" #include "fileio.h" -#include "utf8.h" +#include "device-nodes.h" int saved_argc = 0; char **saved_argv = NULL; @@ -3509,7 +3509,7 @@ static char *tag_to_udev_node(const char *tagvalue, const char *by) { if (t == NULL) return NULL; - if (udev_encode_string(u, t, enc_len) < 0) + if (encode_devnode_name(u, t, enc_len) < 0) return NULL; if (asprintf(&dn, "/dev/disk/by-%s/%s", by, t) < 0) diff --git a/src/test/test-device-nodes.c b/src/test/test-device-nodes.c new file mode 100644 index 0000000000..2f3dedb90f --- /dev/null +++ b/src/test/test-device-nodes.c @@ -0,0 +1,55 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Dave Reisner + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include + +#include "device-nodes.h" +#include "util.h" + +/* helpers for test_encode_devnode_name */ +static char *do_encode_string(const char *in) { + size_t out_len = strlen(in) * 4; + char *out = malloc(out_len); + + assert_se(out); + assert_se(encode_devnode_name(in, out, out_len) >= 0); + puts(out); + + return out; +} + +static bool expect_encoded_as(const char *in, const char *expected) { + _cleanup_free_ char *encoded = do_encode_string(in); + return streq(encoded, expected); +} + +static void test_encode_devnode_name(void) { + assert_se(expect_encoded_as("systemd sucks", "systemd\\x20sucks")); + assert_se(expect_encoded_as("pinkiepie", "pinkiepie")); + assert_se(expect_encoded_as("valíd\\ųtf8", "valíd\\x5cųtf8")); + assert_se(expect_encoded_as("s/ash/ng", "s\\x2fash\\x2fng")); +} + +int main(int argc, char *argv[]) { + test_encode_devnode_name(); + + return 0; +} diff --git a/src/test/test-utf8.c b/src/test/test-utf8.c index 26cc37bd6e..b5a833e9e4 100644 --- a/src/test/test-utf8.c +++ b/src/test/test-utf8.c @@ -19,34 +19,9 @@ along with systemd; If not, see . ***/ - #include "utf8.h" #include "util.h" -/* helpers for test_udev_encode_string */ -static char *do_encode_string(const char *in) { - size_t out_len = strlen(in) * 4; - char *out = malloc(out_len); - - assert_se(out); - assert_se(udev_encode_string(in, out, out_len) >= 0); - puts(out); - - return out; -} - -static bool expect_encoded_as(const char *in, const char *expected) { - _cleanup_free_ char *encoded = do_encode_string(in); - return streq(encoded, expected); -} - -static void test_udev_encode_string(void) { - assert_se(expect_encoded_as("systemd sucks", "systemd\\x20sucks")); - assert_se(expect_encoded_as("pinkiepie", "pinkiepie")); - assert_se(expect_encoded_as("valíd\\ųtf8", "valíd\\x5cųtf8")); - assert_se(expect_encoded_as("s/ash/ng", "s\\x2fash\\x2fng")); -} - static void test_utf8_is_printable(void) { assert_se(utf8_is_printable("ascii is valid\tunicode", 22)); assert_se(utf8_is_printable("\342\204\242", 3)); @@ -55,14 +30,13 @@ static void test_utf8_is_printable(void) { static void test_utf8_is_valid(void) { assert_se(utf8_is_valid("ascii is valid unicode")); - assert_se(utf8_is_valid("\341\204\242")); + assert_se(utf8_is_valid("\342\204\242")); assert_se(!utf8_is_valid("\341\204")); } int main(int argc, char *argv[]) { test_utf8_is_valid(); test_utf8_is_printable(); - test_udev_encode_string(); return 0; } -- cgit v1.2.1 From e7363c59d69b71a4327429719e24cab9020e2796 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Wed, 18 Sep 2013 12:32:23 -0400 Subject: test-utf8: add more tests for public functions --- src/test/test-utf8.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/test/test-utf8.c b/src/test/test-utf8.c index b5a833e9e4..7bd0db173a 100644 --- a/src/test/test-utf8.c +++ b/src/test/test-utf8.c @@ -34,9 +34,43 @@ static void test_utf8_is_valid(void) { assert_se(!utf8_is_valid("\341\204")); } +static void test_ascii_is_valid(void) { + assert_se(ascii_is_valid("alsdjf\t\vbarr\nba z")); + assert_se(!ascii_is_valid("\342\204\242")); + assert_se(!ascii_is_valid("\341\204")); +} + +static void test_ascii_filter(void) { + char *f; + + f = ascii_filter("alsdjf\t\vbarr\nba z"); + assert_se(streq(f, "alsdjf\t\vbarr\nba z")); + free(f); + + f = ascii_filter("\342\204\242"); + assert_se(streq(f, "")); + free(f); + + f = ascii_filter("foo\341\204bar"); + assert_se(streq(f, "foobar")); + free(f); +} + +static void test_utf8_encoded_valid_unichar(void) { + assert_se(utf8_encoded_valid_unichar("\342\204\242") == 3); + assert_se(utf8_encoded_valid_unichar("\302\256") == 2); + assert_se(utf8_encoded_valid_unichar("a") == 1); + assert_se(utf8_encoded_valid_unichar("\341\204") < 0); + assert_se(utf8_encoded_valid_unichar("\341\204\341\204") < 0); + +} + int main(int argc, char *argv[]) { test_utf8_is_valid(); test_utf8_is_printable(); + test_ascii_is_valid(); + test_ascii_filter(); + test_utf8_encoded_valid_unichar(); return 0; } -- cgit v1.2.1 From d2421337f6e7d5a6730599e929232689acb09394 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Thu, 19 Sep 2013 14:30:07 -0400 Subject: nspawn: be less liberal about creating bind mount destinations Previously, if a file's bind mount destination didn't exist, nspawn would blindly create a directory, and the subsequent bind mount would fail. Examine the filetype of the source and ensure that, if the destination does not exist, that it is created appropriately. Also go one step further and ensure that the filetypes of the source and destination match. --- src/nspawn/nspawn.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index f8208607ce..a0809da743 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -411,12 +411,39 @@ static int mount_binds(const char *dest, char **l, unsigned long flags) { STRV_FOREACH_PAIR(x, y, l) { _cleanup_free_ char *where = NULL; + struct stat source_st, dest_st; + + if (stat(*x, &source_st) < 0) { + log_error("failed to stat %s: %m", *x); + return -errno; + } where = strjoin(dest, "/", *y, NULL); if (!where) return log_oom(); - mkdir_p_label(where, 0755); + if (stat(where, &dest_st) == 0) { + if ((source_st.st_mode & S_IFMT) != (dest_st.st_mode & S_IFMT)) { + log_error("The file types of %s and %s do not matching. Refusing bind mount", + *x, where); + return -EINVAL; + } + } else { + /* Create the mount point, but be conservative -- refuse to create block + * and char devices. */ + if (S_ISDIR(source_st.st_mode)) + mkdir_p_label(where, 0755); + else if (S_ISFIFO(source_st.st_mode)) + mkfifo(where, 0644); + else if (S_ISSOCK(source_st.st_mode)) + mknod(where, 0644 | S_IFSOCK, 0); + else if (S_ISREG(source_st.st_mode)) + touch(where); + else { + log_error("Refusing to create mountpoint for file: %s", *x); + return -ENOTSUP; + } + } if (mount(*x, where, "bind", MS_BIND, NULL) < 0) { log_error("mount(%s) failed: %m", where); -- cgit v1.2.1 From cecf24e7f0f3385e7ced3e97d78cc9cc4012a650 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Thu, 19 Sep 2013 14:55:35 -0400 Subject: fix grammatical error --- src/nspawn/nspawn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index a0809da743..eb9605c356 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -424,7 +424,7 @@ static int mount_binds(const char *dest, char **l, unsigned long flags) { if (stat(where, &dest_st) == 0) { if ((source_st.st_mode & S_IFMT) != (dest_st.st_mode & S_IFMT)) { - log_error("The file types of %s and %s do not matching. Refusing bind mount", + log_error("The file types of %s and %s do not match. Refusing bind mount", *x, where); return -EINVAL; } -- cgit v1.2.1 From 1864b0e39505cd44a98eee61c97916b86491c0b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 19 Sep 2013 14:53:38 -0400 Subject: build-sys: don't build python modules after --without-python The modules should build just fine, but AM_PATH_PYTHON sets pkgpyexecdir for us. Without that variable we don't know where to install modules. In addition libtool tries an empty rpath, breaking the build. Those issues could be fixed or worked around, but we probably don't have many people who want to avoid using python binary, but want to compile python modules. If such uses ever come up, this issue should be revisited. --- configure.ac | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index d3f853f30c..156cc96e07 100644 --- a/configure.ac +++ b/configure.ac @@ -175,9 +175,12 @@ AS_IF([test "x$PYTHON_BINARY" = "x"], [PYTHON_BINARY=/usr/bin/python])]) AC_ARG_VAR(PYTHON_BINARY, [Python binary used to launch installed scripts]) +AS_IF([test "x$have_python" != "xyes" -a "x$enable_python_devel" = "xyes"], + [AC_MSG_ERROR([*** python-devel support requires --with-python])]) + have_python_devel=no AC_ARG_ENABLE(python_devel, AS_HELP_STRING([--disable-python-devel], [Do not build python modules])) -AS_IF([test "x$enable_python_devel" != "xno"], [ +AS_IF([test "x$have_python" = "xyes" -a "x$enable_python_devel" != "xno"], [ PKG_CHECK_MODULES([PYTHON_DEVEL], [python-${PYTHON_VERSION}], [have_python_devel=yes], [PKG_CHECK_MODULES([PYTHON_DEVEL], [python], -- cgit v1.2.1 From 1e5413f74faa378172d556e5dec35ab55de16bbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 19 Sep 2013 16:22:59 -0500 Subject: Add more tests and fix capability logging --- src/login/test-login-shared.c | 3 +++ src/shared/fileio.c | 17 +++++++----- src/test/test-fileio.c | 62 ++++++++++++++++++++++++++++++++++--------- 3 files changed, 62 insertions(+), 20 deletions(-) diff --git a/src/login/test-login-shared.c b/src/login/test-login-shared.c index 2df60292bf..d29d7e7921 100644 --- a/src/login/test-login-shared.c +++ b/src/login/test-login-shared.c @@ -32,6 +32,9 @@ static void test_session_id_valid(void) { } int main(int argc, char* argv[]) { + log_parse_environment(); + log_open(); + test_session_id_valid(); return 0; diff --git a/src/shared/fileio.c b/src/shared/fileio.c index 01b803c82f..603a1c7b38 100644 --- a/src/shared/fileio.c +++ b/src/shared/fileio.c @@ -24,6 +24,7 @@ #include "util.h" #include "strv.h" #include "utf8.h" +#include "ctype.h" int write_string_to_file(FILE *f, const char *line) { errno = 0; @@ -672,16 +673,18 @@ int get_status_field(const char *filename, const char *pattern, char **field) { return -ENOENT; t += strlen(pattern); - /* Also skip zeros, because when this is used for capabilities, - * we don't want the zeros. This way the same capability set - * always maps to the same string, irrespective of the total - * capability set size. For other numbers it shouldn't matter. - */ if (*t) { - t += strspn(t, WHITESPACE "0"); + t += strspn(t, " \t"); + + /* Also skip zeros, because when this is used for + * capabilities, we don't want the zeros. This way the + * same capability set always maps to the same string, + * irrespective of the total capability set size. For + * other numbers it shouldn't matter. */ + t += strspn(t, "0"); /* Back off one char if there's nothing but whitespace and zeros */ - if (!*t) + if (!*t || isspace(*t)) t --; } diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c index 525354b9cb..06f3e28288 100644 --- a/src/test/test-fileio.c +++ b/src/test/test-fileio.c @@ -27,6 +27,8 @@ #include "fileio.h" #include "strv.h" #include "env-util.h" +#include "def.h" +#include "ctype.h" static void test_parse_env_file(void) { char t[] = "/tmp/test-fileio-in-XXXXXX", @@ -230,8 +232,8 @@ static void test_executable_is_script(void) { } static void test_status_field(void) { - _cleanup_free_ char *t = NULL, *p = NULL, *s = NULL; - unsigned long long total, buffers; + _cleanup_free_ char *t = NULL, *p = NULL, *s = NULL, *z = NULL; + unsigned long long total = 0, buffers = 0; int r; assert_se(get_status_field("/proc/self/status", "\nThreads:", &t) == 0); @@ -239,26 +241,60 @@ static void test_status_field(void) { assert_se(streq(t, "1")); r = get_status_field("/proc/meminfo", "MemTotal:", &p); - if (r == -ENOENT) - return; - assert(r == 0); - puts(p); - assert_se(safe_atollu(p, &total) == 0); + if (r != -ENOENT) { + assert(r == 0); + puts(p); + assert_se(safe_atollu(p, &total) == 0); + } r = get_status_field("/proc/meminfo", "\nBuffers:", &s); - if (r == -ENOENT) - return; - assert(r == 0); - puts(s); - assert_se(safe_atollu(s, &buffers) == 0); + if (r != -ENOENT) { + assert(r == 0); + puts(s); + assert_se(safe_atollu(s, &buffers) == 0); + } - assert(buffers < total); + if (p && t) + assert(buffers < total); + + /* Seccomp should be a good test for field full of zeros. */ + r = get_status_field("/proc/meminfo", "\nSeccomp:", &z); + if (r != -ENOENT) { + assert(r == 0); + puts(z); + assert_se(safe_atollu(z, &buffers) == 0); + } +} + +static void test_capeff(void) { + int pid, p; + + for (pid = 0; pid < 2; pid++) { + _cleanup_free_ char *capeff = NULL; + int r; + + r = get_process_capeff(0, &capeff); + log_info("capeff: '%s' (r=%d)", capeff, r); + + if (r == -ENOENT || r == -EPERM) + return; + + assert(r == 0); + assert(*capeff); + p = capeff[strspn(capeff, DIGITS "abcdefABCDEF")]; + assert(!p || isspace(p)); + } } int main(int argc, char *argv[]) { + log_parse_environment(); + log_open(); + test_parse_env_file(); test_parse_multiline_env_file(); test_executable_is_script(); test_status_field(); + test_capeff(); + return 0; } -- cgit v1.2.1 From 184ecaf79483bcaf818c7745c9e1c97bbb276111 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Thu, 19 Sep 2013 17:12:00 -0400 Subject: systemctl: Avoid ellipsizing when piping output --- src/systemctl/systemctl.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 62b5616d80..8b9183dcb3 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -72,6 +72,7 @@ static char **arg_types = NULL; static char **arg_states = NULL; static char **arg_properties = NULL; static bool arg_all = false; +static bool original_stdout_is_tty; static enum dependency { DEPENDENCY_FORWARD, DEPENDENCY_REVERSE, @@ -309,7 +310,7 @@ static void output_units_list(const struct unit_info *unit_infos, unsigned c) { } } - if (!arg_full) { + if (!arg_full && original_stdout_is_tty) { unsigned basic_len; id_len = MIN(max_id_len, 25u); basic_len = 5 + id_len + 5 + active_len + sub_len; @@ -376,7 +377,7 @@ static void output_units_list(const struct unit_info *unit_infos, unsigned c) { on_active, active_len, u->active_state, sub_len, u->sub_state, off_active, job_count ? job_len + 1 : 0, u->job_id ? u->job_type : ""); - if (!arg_full && arg_no_pager) + if (desc_len > 0) printf("%.*s\n", desc_len, u->description); else printf("%s\n", u->description); @@ -6177,6 +6178,11 @@ int main(int argc, char*argv[]) { log_parse_environment(); log_open(); + /* Explicitly not on_tty() to avoid setting cached value. + * This becomes relevant for piping output which might be + * ellipsized. */ + original_stdout_is_tty = isatty(STDOUT_FILENO); + r = parse_argv(argc, argv); if (r < 0) goto finish; -- cgit v1.2.1 From 42a9de1c2513aa348df369080cdd941ef4ab00ab Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Thu, 19 Sep 2013 16:42:10 -0500 Subject: keymap: Fix wrong assignments to F23 These days, F21/F22/F23 mean Touchpad toggle/on/off. Clean up other assignments to that from ancient times which belong to keys like "Auto Brightness" (which doesn't have a keycode and is usually hardwired) or some "launch vendor tool" key. https://bugs.freedesktop.org/show_bug.cgi?id=62953 --- hwdb/60-keyboard.hwdb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index 3862b4ca20..fe051a5c17 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -116,7 +116,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svneMachines:pneMachines*E725:pvr* KEYBOARD_KEY_f4=prog1 # "P1" programmable button KEYBOARD_KEY_f5=presentation KEYBOARD_KEY_f8=fn - KEYBOARD_KEY_f9=f23 # Launch NTI shadow + KEYBOARD_KEY_f9=prog1 # Launch NTI shadow # keyboard:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5210*:pvr* @@ -207,12 +207,12 @@ keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pn* KEYBOARD_KEY_89=ejectclosecd # Fn+F10 Eject CD KEYBOARD_KEY_8a=suspend # Fn+F1 hibernate KEYBOARD_KEY_8b=switchvideomode # Fn+F8 CRT/LCD (high keycode: "displaytoggle") - KEYBOARD_KEY_8c=f23 # Fn+Right Auto Brightness + KEYBOARD_KEY_8c=unknown # Fn+Right Auto Brightness KEYBOARD_KEY_8F=switchvideomode # Fn+F7 aspect ratio KEYBOARD_KEY_90=previoussong # Front panel previous song KEYBOARD_KEY_91=prog1 # Wi-Fi Catcher (Dell-specific) KEYBOARD_KEY_92=media # MediaDirect button (house icon) - KEYBOARD_KEY_93=f23 # FIXME Fn+Left Auto Brightness + KEYBOARD_KEY_93=unknown # FIXME Fn+Left Auto Brightness KEYBOARD_KEY_95=camera # Shutter button - Takes a picture if optional camera available KEYBOARD_KEY_97=email # Tablet email button KEYBOARD_KEY_98=f21 # FIXME: Tablet screen rotation @@ -252,7 +252,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnPrecision*:pvr* # Dell XPS keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnXPS*:pvr* - KEYBOARD_KEY_8c=!f23 + KEYBOARD_KEY_8c=!unknown ########################################################### # Everex @@ -363,7 +363,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*:pvr* KEYBOARD_KEY_8c=media # music KEYBOARD_KEY_8e=dvd KEYBOARD_KEY_b1=help - KEYBOARD_KEY_b3=f23 # FIXME: Auto brightness + KEYBOARD_KEY_b3=unknown # FIXME: Auto brightness KEYBOARD_KEY_d7=wlan KEYBOARD_KEY_92=brightnessdown # Fn+F7 (Fn+F9 on 6730b) KEYBOARD_KEY_97=brightnessup # Fn+F8 (Fn+F10 on 6730b) -- cgit v1.2.1 From 1bee43de64aadb700dcb32958372714ec56c97b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 19 Sep 2013 18:41:35 -0500 Subject: man: mention --runtime where appropriate https://bugzilla.redhat.com/show_bug.cgi?id=1009956 --- man/systemctl.xml | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/man/systemctl.xml b/man/systemctl.xml index b043581be0..32bcf03f2f 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -830,10 +830,11 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service case of socket units), and so on.
Depending on whether , - or is - specified, this enables the unit for the system, for the - calling user only or for all future logins of all - users. Note that in the last case, no systemd daemon + , , + or, is specified, this enables the unit + for the system, for the calling user only, for only this boot of + the system, or for all future logins of all users, or only this + boot. Note that in the last case, no systemd daemon configuration is reloaded. @@ -860,8 +861,9 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service This command honors , - , in a - similar way as enable. + , , + in a similar way as + enable. @@ -918,7 +920,9 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service start them. This is a stronger version of disable, since it prohibits all kinds of activation of the unit, including manual activation. Use - this option with care. + this option with care. This honors the + option, to only mask temporarily + until the next reoobt of the system. -- cgit v1.2.1 From 6c605695506cc55fd77241308540c5e1a15d807c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mantas=20Mikul=C4=97nas?= Date: Fri, 20 Sep 2013 18:14:02 +0300 Subject: logind: put correct user object paths in introspection data Sync with user_bus_path() in logind-user-dbus.c --- src/login/logind-dbus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index ec590c0c56..e76381b322 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -2256,7 +2256,7 @@ static DBusHandlerResult manager_message_handler( } HASHMAP_FOREACH(user, m->users, i) - fprintf(f, "", (unsigned long long) user->uid); + fprintf(f, "", (unsigned long long) user->uid); HASHMAP_FOREACH(session, m->sessions, i) { p = bus_path_escape(session->id); -- cgit v1.2.1 From d808ca6414cd29d56507bed78fce2d26c6b00f15 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Thu, 19 Sep 2013 18:00:36 -0400 Subject: completion/systemctl: add missing list-sockets verb --- shell-completion/bash/systemctl | 2 +- shell-completion/zsh/_systemctl | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/shell-completion/bash/systemctl b/shell-completion/bash/systemctl index 5346eef65b..e335ee871c 100644 --- a/shell-completion/bash/systemctl +++ b/shell-completion/bash/systemctl @@ -139,7 +139,7 @@ _systemctl () { [ENVS]='set-environment unset-environment' [STANDALONE]='daemon-reexec daemon-reload default dump emergency exit halt hibernate hybrid-sleep kexec list-jobs - list-units list-unit-files poweroff reboot rescue + list-sockets list-units list-unit-files poweroff reboot rescue show-environment suspend get-default' [NAME]='snapshot load' [FILE]='link' diff --git a/shell-completion/zsh/_systemctl b/shell-completion/zsh/_systemctl index 3d5f2ffeeb..298e97ed61 100644 --- a/shell-completion/zsh/_systemctl +++ b/shell-completion/zsh/_systemctl @@ -4,6 +4,7 @@ { local -a _systemctl_cmds _systemctl_cmds=( + "list-sockets:List sockets" "list-units:List units" "start:Start (activate) one or more units" "stop:Stop (deactivate) one or more units" -- cgit v1.2.1 From a0f708053ba42c8289caed1107f498bbf332e204 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sun, 22 Sep 2013 20:38:24 +0200 Subject: Fix obsolete references to systemd-random-seed-load.service This service was merged with systemd-random-seed-save.service in c35b956d34bbb8bb208e49e45de2c103ca11911c. --- src/cryptsetup/cryptsetup-generator.c | 2 +- units/systemd-random-seed.service.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c index ba6efa6fc3..8792e6b1f5 100644 --- a/src/cryptsetup/cryptsetup-generator.c +++ b/src/cryptsetup/cryptsetup-generator.c @@ -129,7 +129,7 @@ static int create_disk( if (streq(password, "/dev/urandom") || streq(password, "/dev/random") || streq(password, "/dev/hw_random")) - fputs("After=systemd-random-seed-load.service\n", f); + fputs("After=systemd-random-seed.service\n", f); else if (!streq(password, "-") && !streq(password, "none")) fprintf(f, diff --git a/units/systemd-random-seed.service.in b/units/systemd-random-seed.service.in index 0c21a04842..1879b2f24c 100644 --- a/units/systemd-random-seed.service.in +++ b/units/systemd-random-seed.service.in @@ -7,7 +7,7 @@ [Unit] Description=Load/Save Random Seed -Documentation=man:systemd-random-seed-load.service(8) man:random(4) +Documentation=man:systemd-random-seed.service(8) man:random(4) DefaultDependencies=no RequiresMountsFor=@RANDOM_SEED@ Conflicts=shutdown.target -- cgit v1.2.1 From e58cec11e6735583c0de7cba68fb68f669472305 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 23 Sep 2013 16:02:31 -0500 Subject: cgroup: always enable memory.use_hierarchy= for all cgroups in the memory hierarchy The non-hierarchial mode contradicts the whole idea of a cgroup tree so let's not support this. In the future the kernel will only support the hierarchial logic anyway. --- src/core/cgroup.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/cgroup.c b/src/core/cgroup.c index d10f205a2f..e66b8f4851 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -254,8 +254,9 @@ void cgroup_context_apply(CGroupContext *c, CGroupControllerMask mask, const cha } if (mask & CGROUP_MEMORY) { - char buf[DECIMAL_STR_MAX(uint64_t) + 1]; if (c->memory_limit != (uint64_t) -1) { + char buf[DECIMAL_STR_MAX(uint64_t) + 1]; + sprintf(buf, "%" PRIu64 "\n", c->memory_limit); r = cg_set_attribute("memory", path, "memory.limit_in_bytes", buf); } else @@ -666,6 +667,9 @@ int manager_setup_cgroup(Manager *m) { /* 6. Figure out which controllers are supported */ m->cgroup_supported = cg_mask_supported(); + /* 7. Always enable hierarchial support if it exists... */ + cg_set_attribute("memory", "/", "memory.use_hierarchy", "1"); + return 0; } -- cgit v1.2.1 From fb8f3f986991e2ee249ee0d0b303f6123b709f43 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 23 Sep 2013 16:52:58 -0500 Subject: TODO: update --- TODO | 4 ---- 1 file changed, 4 deletions(-) diff --git a/TODO b/TODO index 01bc993e0f..b79e265cc6 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,3 @@ -Bugfixes: -* the running hwdb seems not to pick up updated database files without - an explicit: udevadm control --reload - * enabling an instance unit creates pointless link, and the unit will be started with getty@getty.service: $ systemctl enable getty@.service -- cgit v1.2.1 From 036ae95ac4a425475b58e1a8e53d5c52b2c8a218 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 23 Sep 2013 16:53:19 -0500 Subject: shared: device-nodes - add include guard --- src/shared/device-nodes.c | 2 +- src/shared/device-nodes.h | 2 ++ src/shared/utf8.c | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/shared/device-nodes.c b/src/shared/device-nodes.c index 986553e93f..9837375099 100644 --- a/src/shared/device-nodes.c +++ b/src/shared/device-nodes.c @@ -3,7 +3,7 @@ /*** This file is part of systemd. - Copyright 2012 Lennart Poettering + Copyright 2008-2011 Kay Sievers systemd is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by diff --git a/src/shared/device-nodes.h b/src/shared/device-nodes.h index a98195afa9..04ba4897e5 100644 --- a/src/shared/device-nodes.h +++ b/src/shared/device-nodes.h @@ -1,5 +1,7 @@ /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ +#pragma once + /*** This file is part of systemd. diff --git a/src/shared/utf8.c b/src/shared/utf8.c index c3d97cc783..a8e28accd3 100644 --- a/src/shared/utf8.c +++ b/src/shared/utf8.c @@ -3,6 +3,7 @@ /*** This file is part of systemd. + Copyright 2008-2011 Kay Sievers Copyright 2012 Lennart Poettering systemd is free software; you can redistribute it and/or modify it @@ -19,7 +20,7 @@ along with systemd; If not, see . ***/ -/* This file is based on the GLIB utf8 validation functions. The +/* Parts of this file are based on the GLIB utf8 validation functions. The * original license text follows. */ /* gutf8.c - Operations on UTF-8 strings. -- cgit v1.2.1 From c51d84dc09476d9c06b8aac726220bf3c7d62e8d Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 23 Sep 2013 17:23:35 -0500 Subject: support acpi firmware performance data (FPDT) Prefer firmware-provided performance data over loader-exported ones; if ACPI data is available, always use it, otherwise try to read the loader data. The firmware-provided variables start at the time the first EFI image is executed and end when the operating system exits the boot services; the (loader) time calculated in systemd-analyze increases. --- .gitignore | 2 +- Makefile.am | 15 +-- src/boot/boot-efi.c | 2 +- src/core/manager.c | 4 +- src/efi-boot-generator/efi-boot-generator.c | 2 +- src/shared/acpi-fpdt.c | 155 ++++++++++++++++++++++++++++ src/shared/acpi-fpdt.h | 26 +++++ src/shared/boot-timestamps.c | 65 ++++++++++++ src/shared/boot-timestamps.h | 27 +++++ src/shared/efivars.c | 41 +------- src/shared/efivars.h | 5 +- src/test/test-boot-timestamps.c | 98 ++++++++++++++++++ src/test/test-efivars.c | 47 --------- 13 files changed, 389 insertions(+), 100 deletions(-) create mode 100644 src/shared/acpi-fpdt.c create mode 100644 src/shared/acpi-fpdt.h create mode 100644 src/shared/boot-timestamps.c create mode 100644 src/shared/boot-timestamps.h create mode 100644 src/test/test-boot-timestamps.c delete mode 100644 src/test/test-efivars.c diff --git a/.gitignore b/.gitignore index 8115d4d0e8..5b38c0b2e9 100644 --- a/.gitignore +++ b/.gitignore @@ -85,6 +85,7 @@ /systemd-user-sessions /systemd-vconsole-setup /tags +/test-boot-timestamp /test-bus-chat /test-bus-kernel /test-bus-kernel-bloom @@ -102,7 +103,6 @@ /test-daemon /test-date /test-device-nodes -/test-efivars /test-engine /test-env-replace /test-fileio diff --git a/Makefile.am b/Makefile.am index 89a5c86357..0eee1d93f0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -717,6 +717,10 @@ libsystemd_shared_la_SOURCES = \ src/shared/output-mode.h \ src/shared/MurmurHash3.c \ src/shared/MurmurHash3.h \ + src/shared/acpi-fpdt.h \ + src/shared/acpi-fpdt.c \ + src/shared/boot-timestamps.h \ + src/shared/boot-timestamps.c \ src/shared/refcnt.h #------------------------------------------------------------------------------- @@ -1155,9 +1159,6 @@ EXTRA_DIST += \ test_device_nodes_SOURCES = \ src/test/test-device-nodes.c -test_device_nodes_CFLAGS = \ - $(AM_CFLAGS) - test_device_nodes_LDADD = \ libsystemd-shared.la @@ -1209,12 +1210,12 @@ test_hostname_LDADD = \ if ENABLE_EFI manual_tests += \ - test-efivars + test-boot-timestamp -test_efivars_SOURCES = \ - src/test/test-efivars.c +test_boot_timestamp_SOURCES = \ + src/test/test-boot-timestamps.c -test_efivars_LDADD = \ +test_boot_timestamp_LDADD = \ libsystemd-shared.la endif diff --git a/src/boot/boot-efi.c b/src/boot/boot-efi.c index 9960c4d742..33840b6864 100644 --- a/src/boot/boot-efi.c +++ b/src/boot/boot-efi.c @@ -174,7 +174,7 @@ int boot_info_query(struct boot_info *info) { efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderFirmwareInfo", &info->fw_info); efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderImageIdentifier", &info->loader_image_path); tilt_slashes(info->loader_image_path); - efi_get_loader_device_part_uuid(&info->loader_part_uuid); + efi_loader_get_device_part_uuid(&info->loader_part_uuid); boot_loader_read_entries(info); efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderEntrySelected", &loader_active); diff --git a/src/core/manager.c b/src/core/manager.c index 079db4157b..f70ff03033 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -70,7 +70,7 @@ #include "cgroup-util.h" #include "path-util.h" #include "audit-fd.h" -#include "efivars.h" +#include "boot-timestamps.h" #include "env-util.h" /* As soon as 5s passed since a unit was added to our GC queue, make sure to run a gc sweep */ @@ -496,7 +496,7 @@ int manager_new(SystemdRunningAs running_as, bool reexecuting, Manager **_m) { #ifdef ENABLE_EFI if (detect_container(NULL) <= 0) - efi_get_boot_timestamps(&m->userspace_timestamp, &m->firmware_timestamp, &m->loader_timestamp); + boot_timestamps(&m->userspace_timestamp, &m->firmware_timestamp, &m->loader_timestamp); #endif m->running_as = running_as; diff --git a/src/efi-boot-generator/efi-boot-generator.c b/src/efi-boot-generator/efi-boot-generator.c index 4367c536b0..05b95ed455 100644 --- a/src/efi-boot-generator/efi-boot-generator.c +++ b/src/efi-boot-generator/efi-boot-generator.c @@ -55,7 +55,7 @@ int main(int argc, char *argv[]) { if (dir_is_empty("/boot") <= 0) return EXIT_SUCCESS; - r = efi_get_loader_device_part_uuid(&id); + r = efi_loader_get_device_part_uuid(&id); if (r == -ENOENT) return EXIT_SUCCESS; if (r < 0) { diff --git a/src/shared/acpi-fpdt.c b/src/shared/acpi-fpdt.c new file mode 100644 index 0000000000..b094f34a5f --- /dev/null +++ b/src/shared/acpi-fpdt.c @@ -0,0 +1,155 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Kay Sievers + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +struct acpi_table_header { + char signature[4]; + uint32_t length; + uint8_t revision; + uint8_t checksum; + char oem_id[6]; + char oem_table_id[8]; + uint32_t oem_revision; + char asl_compiler_id[4]; + uint32_t asl_compiler_revision; +}; + +enum { + ACPI_FPDT_TYPE_BOOT = 0, + ACPI_FPDT_TYPE_S3PERF = 1, +}; + +struct acpi_fpdt_header { + uint16_t type; + uint8_t length; + uint8_t revision; + uint8_t reserved[4]; + uint64_t ptr; +}; + +struct acpi_fpdt_boot_header { + char signature[4]; + uint32_t length; +}; + +enum { + ACPI_FPDT_S3PERF_RESUME_REC = 0, + ACPI_FPDT_S3PERF_SUSPEND_REC = 1, + ACPI_FPDT_BOOT_REC = 2, +}; + +struct acpi_fpdt_boot { + uint16_t type; + uint8_t length; + uint8_t revision; + uint8_t reserved[4]; + uint64_t reset_end; + uint64_t load_start; + uint64_t startup_start; + uint64_t exit_services_entry; + uint64_t exit_services_exit; +}; + +int acpi_get_boot_usec(usec_t *loader_start, usec_t *loader_exit) { + char *buf; + struct acpi_table_header *tbl; + size_t l; + struct acpi_fpdt_header *rec; + int r; + uint64_t ptr = 0; + _cleanup_close_ int fd = -1; + struct acpi_fpdt_boot_header hbrec; + struct acpi_fpdt_boot brec; + + r = read_full_file("/sys/firmware/acpi/tables/FPDT", &buf, &l); + if (r < 0) + return r; + + if (l < sizeof(struct acpi_table_header) + sizeof(struct acpi_fpdt_header)) + return -EINVAL; + + tbl = (struct acpi_table_header *)buf; + if (l != tbl->length) + return -EINVAL; + + if (memcmp(tbl->signature, "FPDT", 4) != 0) + return -EINVAL; + + /* find Firmware Basic Boot Performance Pointer Record */ + for (rec = (struct acpi_fpdt_header *)(buf + sizeof(struct acpi_table_header)); + (char *)rec < buf + l; + rec = (struct acpi_fpdt_header *)((char *)rec + rec->length)) { + if (rec->type != ACPI_FPDT_TYPE_BOOT) + continue; + if (rec->length != sizeof(struct acpi_fpdt_header)) + continue; + + ptr = rec->ptr; + break; + } + + if (ptr == 0) + return -EINVAL; + + /* read Firmware Basic Boot Performance Data Record */ + fd = open("/dev/mem", O_CLOEXEC|O_RDONLY); + if (fd < 0) + return -errno; + + l = pread(fd, &hbrec, sizeof(struct acpi_fpdt_boot_header), ptr); + if (l != sizeof(struct acpi_fpdt_boot_header)) + return -EINVAL; + + if (memcmp(hbrec.signature, "FBPT", 4) != 0) + return -EINVAL; + + if (hbrec.length < sizeof(struct acpi_fpdt_boot_header) + sizeof(struct acpi_fpdt_boot)) + return -EINVAL; + + l = pread(fd, &brec, sizeof(struct acpi_fpdt_boot), ptr + sizeof(struct acpi_fpdt_boot_header)); + if (l != sizeof(struct acpi_fpdt_boot)) + return -EINVAL; + + if (brec.length != sizeof(struct acpi_fpdt_boot)) + return -EINVAL; + + if (brec.type != ACPI_FPDT_BOOT_REC) + return -EINVAL; + + if (loader_start) + *loader_start = brec.startup_start / 1000; + if (loader_exit) + *loader_exit = brec.exit_services_exit / 1000; + + return 0; +} diff --git a/src/shared/acpi-fpdt.h b/src/shared/acpi-fpdt.h new file mode 100644 index 0000000000..fc4fe6f10f --- /dev/null +++ b/src/shared/acpi-fpdt.h @@ -0,0 +1,26 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2013 Kay Sievers + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include + +int acpi_get_boot_usec(usec_t *loader_start, usec_t *loader_exit); diff --git a/src/shared/boot-timestamps.c b/src/shared/boot-timestamps.c new file mode 100644 index 0000000000..944996582e --- /dev/null +++ b/src/shared/boot-timestamps.c @@ -0,0 +1,65 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 Lennart Poettering + Copyright 2013 Kay Sievers + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ +#include + +#include "boot-timestamps.h" +#include "acpi-fpdt.h" +#include "efivars.h" + +int boot_timestamps(const dual_timestamp *n, dual_timestamp *firmware, dual_timestamp *loader) { + usec_t x, y, a; + int r; + dual_timestamp _n; + + assert(firmware); + assert(loader); + + if (!n) { + dual_timestamp_get(&_n); + n = &_n; + } + + r = acpi_get_boot_usec(&x, &y); + if (r < 0) { + r = efi_loader_get_boot_usec(&x, &y); + if (r < 0) + return r; + } + + /* Let's convert this to timestamps where the firmware + * began/loader began working. To make this more confusing: + * since usec_t is unsigned and the kernel's monotonic clock + * begins at kernel initialization we'll actually initialize + * the monotonic timestamps here as negative of the actual + * value. */ + + firmware->monotonic = y; + loader->monotonic = y - x; + + a = n->monotonic + firmware->monotonic; + firmware->realtime = n->realtime > a ? n->realtime - a : 0; + + a = n->monotonic + loader->monotonic; + loader->realtime = n->realtime > a ? n->realtime - a : 0; + + return 0; +} diff --git a/src/shared/boot-timestamps.h b/src/shared/boot-timestamps.h new file mode 100644 index 0000000000..a3d2405b56 --- /dev/null +++ b/src/shared/boot-timestamps.h @@ -0,0 +1,27 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2012 Lennart Poettering + Copyright 2013 Kay Sievers + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include + +int boot_timestamps(const dual_timestamp *n, dual_timestamp *firmware, dual_timestamp *loader); diff --git a/src/shared/efivars.c b/src/shared/efivars.c index 8d004bad33..1d5b6f9e72 100644 --- a/src/shared/efivars.c +++ b/src/shared/efivars.c @@ -24,6 +24,7 @@ #include #include +#include "acpi-fpdt.h" #include "util.h" #include "utf8.h" #include "efivars.h" @@ -413,7 +414,7 @@ static int read_usec(sd_id128_t vendor, const char *name, usec_t *u) { return 0; } -static int get_boot_usec(usec_t *firmware, usec_t *loader) { +int efi_loader_get_boot_usec(usec_t *firmware, usec_t *loader) { uint64_t x, y; int r; @@ -440,43 +441,7 @@ static int get_boot_usec(usec_t *firmware, usec_t *loader) { return 0; } -int efi_get_boot_timestamps(const dual_timestamp *n, dual_timestamp *firmware, dual_timestamp *loader) { - usec_t x, y, a; - int r; - dual_timestamp _n; - - assert(firmware); - assert(loader); - - if (!n) { - dual_timestamp_get(&_n); - n = &_n; - } - - r = get_boot_usec(&x, &y); - if (r < 0) - return r; - - /* Let's convert this to timestamps where the firmware - * began/loader began working. To make this more confusing: - * since usec_t is unsigned and the kernel's monotonic clock - * begins at kernel initialization we'll actually initialize - * the monotonic timestamps here as negative of the actual - * value. */ - - firmware->monotonic = y; - loader->monotonic = y - x; - - a = n->monotonic + firmware->monotonic; - firmware->realtime = n->realtime > a ? n->realtime - a : 0; - - a = n->monotonic + loader->monotonic; - loader->realtime = n->realtime > a ? n->realtime - a : 0; - - return 0; -} - -int efi_get_loader_device_part_uuid(sd_id128_t *u) { +int efi_loader_get_device_part_uuid(sd_id128_t *u) { _cleanup_free_ char *p = NULL; int r, parsed[16]; unsigned i; diff --git a/src/shared/efivars.h b/src/shared/efivars.h index 2b88c6075c..7921bedc9f 100644 --- a/src/shared/efivars.h +++ b/src/shared/efivars.h @@ -42,6 +42,5 @@ int efi_get_boot_option(uint16_t nr, char **title, sd_id128_t *partuuid, char ** int efi_get_boot_order(uint16_t **order); int efi_get_boot_options(uint16_t **options); -int efi_get_boot_timestamps(const dual_timestamp *n, dual_timestamp *firmware, dual_timestamp *loader); - -int efi_get_loader_device_part_uuid(sd_id128_t *u); +int efi_loader_get_device_part_uuid(sd_id128_t *u); +int efi_loader_get_boot_usec(usec_t *firmware, usec_t *loader); diff --git a/src/test/test-boot-timestamps.c b/src/test/test-boot-timestamps.c new file mode 100644 index 0000000000..4ede318e38 --- /dev/null +++ b/src/test/test-boot-timestamps.c @@ -0,0 +1,98 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Lennart Poettering + Copyright 2013 Kay Sievers + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include "util.h" +#include "log.h" +#include "boot-timestamps.h" +#include "efivars.h" +#include "acpi-fpdt.h" + +static int test_acpi_fpdt(void) { + usec_t loader_start; + usec_t loader_exit; + char ts_start[FORMAT_TIMESPAN_MAX]; + char ts_exit[FORMAT_TIMESPAN_MAX]; + char ts_span[FORMAT_TIMESPAN_MAX]; + int r; + + r = acpi_get_boot_usec(&loader_start, &loader_exit); + if (r < 0) { + if (r != -ENOENT) + log_error("Failed to read ACPI FPDT: %s", strerror(-r)); + return r; + } + + log_info("ACPI FPDT: loader start=%s exit=%s duration=%s", + format_timespan(ts_start, sizeof(ts_start), loader_start, USEC_PER_MSEC), + format_timespan(ts_exit, sizeof(ts_exit), loader_exit, USEC_PER_MSEC), + format_timespan(ts_span, sizeof(ts_span), loader_exit - loader_start, USEC_PER_MSEC)); + + return 0; +} + +static int test_efi_loader(void) { + usec_t loader_start; + usec_t loader_exit; + char ts_start[FORMAT_TIMESPAN_MAX]; + char ts_exit[FORMAT_TIMESPAN_MAX]; + char ts_span[FORMAT_TIMESPAN_MAX]; + int r; + + r = efi_loader_get_boot_usec(&loader_start, &loader_exit); + if (r < 0) { + if (r != -ENOENT) + log_error("Failed to read EFI loader data: %s", strerror(-r)); + return r; + } + + log_info("EFI Loader: start=%s exit=%s duration=%s", + format_timespan(ts_start, sizeof(ts_start), loader_start, USEC_PER_MSEC), + format_timespan(ts_exit, sizeof(ts_exit), loader_exit, USEC_PER_MSEC), + format_timespan(ts_span, sizeof(ts_span), loader_exit - loader_start, USEC_PER_MSEC)); + + return 0; +} + +int main(int argc, char* argv[]) { + char s[MAX(FORMAT_TIMESPAN_MAX, FORMAT_TIMESTAMP_MAX)]; + int r; + dual_timestamp fw, l, k; + + test_acpi_fpdt(); + test_efi_loader(); + + dual_timestamp_from_monotonic(&k, 0); + + r = boot_timestamps(NULL, &fw, &l); + if (r < 0) { + log_error("Failed to read variables: %s", strerror(-r)); + return 1; + } + + log_info("Firmware began %s before kernel.", format_timespan(s, sizeof(s), fw.monotonic, 0)); + log_info("Loader began %s before kernel.", format_timespan(s, sizeof(s), l.monotonic, 0)); + log_info("Firmware began %s.", format_timestamp(s, sizeof(s), fw.realtime)); + log_info("Loader began %s.", format_timestamp(s, sizeof(s), l.realtime)); + log_info("Kernel began %s.", format_timestamp(s, sizeof(s), k.realtime)); + + return 0; +} diff --git a/src/test/test-efivars.c b/src/test/test-efivars.c deleted file mode 100644 index 43ea5917b6..0000000000 --- a/src/test/test-efivars.c +++ /dev/null @@ -1,47 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see . -***/ - -#include "util.h" -#include "log.h" -#include "efivars.h" - -int main(int argc, char* argv[]) { - char s[MAX(FORMAT_TIMESPAN_MAX, FORMAT_TIMESTAMP_MAX)]; - int r; - dual_timestamp fw, l, k; - - dual_timestamp_from_monotonic(&k, 0); - - r = efi_get_boot_timestamps(NULL, &fw, &l); - if (r < 0) { - log_error("Failed to read variables: %s", strerror(-r)); - return 1; - } - - log_info("Firmware began %s before kernel.", format_timespan(s, sizeof(s), fw.monotonic, 0)); - log_info("Loader began %s before kernel.", format_timespan(s, sizeof(s), l.monotonic, 0)); - - log_info("Firmware began %s.", format_timestamp(s, sizeof(s), fw.realtime)); - log_info("Loader began %s.", format_timestamp(s, sizeof(s), l.realtime)); - log_info("Kernel began %s.", format_timestamp(s, sizeof(s), k.realtime)); - - return 0; -} -- cgit v1.2.1 From 540fd137af627bb002a016637bf87e517e62f86c Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 24 Sep 2013 15:47:12 +0200 Subject: hwdb: update --- hwdb/20-OUI.hwdb | 201 +++++++++++++++++++++++++- hwdb/20-pci-vendor-model.hwdb | 322 ++++++++++++++++++++++++++---------------- 2 files changed, 392 insertions(+), 131 deletions(-) diff --git a/hwdb/20-OUI.hwdb b/hwdb/20-OUI.hwdb index 463397744a..e913b28203 100644 --- a/hwdb/20-OUI.hwdb +++ b/hwdb/20-OUI.hwdb @@ -2519,7 +2519,7 @@ OUI:0050C2351* ID_OUI_FROM_DATABASE=Finesystem Co., Ltd OUI:0050C2352* - ID_OUI_FROM_DATABASE=edixia + ID_OUI_FROM_DATABASE=LUCEO OUI:0050C2353* ID_OUI_FROM_DATABASE=Crossing Informationssysteme GmbH @@ -10565,7 +10565,7 @@ OUI:0050C2DDA* ID_OUI_FROM_DATABASE=rbz robot design s.l. OUI:0050C2DDB* - ID_OUI_FROM_DATABASE=EDIXIA + ID_OUI_FROM_DATABASE=LUCEO OUI:0050C2DDC* ID_OUI_FROM_DATABASE=Vision & Control GmbH @@ -13291,6 +13291,39 @@ OUI:40D855170* OUI:40D855171* ID_OUI_FROM_DATABASE=Sicon srl +OUI:40D855172* + ID_OUI_FROM_DATABASE=YAWATA ELECTRIC INDUSTRIAL CO.,LTD. + +OUI:40D855173* + ID_OUI_FROM_DATABASE=Contec Steuerungstechnik & Automation GmbH + +OUI:40D855174* + ID_OUI_FROM_DATABASE=EcoGuard AB + +OUI:40D855175* + ID_OUI_FROM_DATABASE=AHB Systeme GmbH + +OUI:40D855176* + ID_OUI_FROM_DATABASE=Schneider Electric Motion, Inc. USA + +OUI:40D855177* + ID_OUI_FROM_DATABASE=TRI Engineering co.,ltd. + +OUI:40D855178* + ID_OUI_FROM_DATABASE=REDER Domotic GmbH + +OUI:40D855179* + ID_OUI_FROM_DATABASE=Servo-Robot Inc. + +OUI:40D85517A* + ID_OUI_FROM_DATABASE=ARGUS-SPECTRUM + +OUI:40D85517B* + ID_OUI_FROM_DATABASE=LUCEO + +OUI:40D85517C* + ID_OUI_FROM_DATABASE=Critical Link + OUI:000000* ID_OUI_FROM_DATABASE=XEROX CORPORATION @@ -32510,7 +32543,7 @@ OUI:001934* ID_OUI_FROM_DATABASE=TRENDON TOUCH TECHNOLOGY CORP. OUI:001935* - ID_OUI_FROM_DATABASE=DÜRR DENTAL AG + ID_OUI_FROM_DATABASE=DUERR DENTAL AG OUI:001936* ID_OUI_FROM_DATABASE=STERLITE OPTICAL TECHNOLOGIES LIMITED @@ -36530,7 +36563,7 @@ OUI:001E70* ID_OUI_FROM_DATABASE=Cobham Defence Communications Ltd OUI:001E71* - ID_OUI_FROM_DATABASE=Igeacare Solutions Inc. + ID_OUI_FROM_DATABASE=MIrcom Group of Companies OUI:001E72* ID_OUI_FROM_DATABASE=PCS @@ -46598,7 +46631,7 @@ OUI:008063* ID_OUI_FROM_DATABASE=Hirschmann Automation and Control GmbH OUI:008064* - ID_OUI_FROM_DATABASE=Tattile SRL + ID_OUI_FROM_DATABASE=WYSE TECHNOLOGY LLC OUI:008065* ID_OUI_FROM_DATABASE=CYBERGRAPHIC SYSTEMS PTY LTD. @@ -51346,6 +51379,9 @@ OUI:043604* OUI:043D98* ID_OUI_FROM_DATABASE=ChongQing QingJia Electronics CO.,LTD +OUI:0444A1* + ID_OUI_FROM_DATABASE=TELECON GALICIA,S.A. + OUI:044665* ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. @@ -52078,6 +52114,9 @@ OUI:083E0C* OUI:083E8E* ID_OUI_FROM_DATABASE=Hon Hai Precision Ind.Co.Ltd +OUI:084027* + ID_OUI_FROM_DATABASE=Gridstore Inc. + OUI:08482C* ID_OUI_FROM_DATABASE=Raycore Taiwan Co., LTD. @@ -52444,6 +52483,9 @@ OUI:0CAF5A* OUI:0CB4EF* ID_OUI_FROM_DATABASE=Digience Co.,Ltd. +OUI:0CBD51* + ID_OUI_FROM_DATABASE=TCT Mobile Limited + OUI:0CBF15* ID_OUI_FROM_DATABASE=Genetec @@ -52750,6 +52792,9 @@ OUI:109FA9* OUI:10A13B* ID_OUI_FROM_DATABASE=FUJIKURA RUBBER LTD. +OUI:10A5D0* + ID_OUI_FROM_DATABASE=Murata Manufacturing Co.,Ltd. + OUI:10A743* ID_OUI_FROM_DATABASE=SK Mtek Limited @@ -53041,6 +53086,9 @@ OUI:14E6E4* OUI:14EB33* ID_OUI_FROM_DATABASE=BSMediasoft Co., Ltd. +OUI:14EDA5* + ID_OUI_FROM_DATABASE=Wächter GmbH Sicherheitssysteme + OUI:14EE9D* ID_OUI_FROM_DATABASE=AirNav Systems LLC @@ -53110,6 +53158,9 @@ OUI:181BEB* OUI:181EB0* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +OUI:182012* + ID_OUI_FROM_DATABASE=Aztech Associates Inc. + OUI:182032* ID_OUI_FROM_DATABASE=Apple @@ -53248,6 +53299,9 @@ OUI:1897FF* OUI:189A67* ID_OUI_FROM_DATABASE=CSE-Servelec Limited +OUI:189C5D* + ID_OUI_FROM_DATABASE=Cisco + OUI:189EFC* ID_OUI_FROM_DATABASE=Apple @@ -53258,7 +53312,7 @@ OUI:18A99B* ID_OUI_FROM_DATABASE=Dell Inc PCBA Test OUI:18AA45* - ID_OUI_FROM_DATABASE=Fon Japan K. K. + ID_OUI_FROM_DATABASE=Fon Technology OUI:18ABF5* ID_OUI_FROM_DATABASE=Ultra Electronics - Electrics @@ -53479,6 +53533,9 @@ OUI:1C7508* OUI:1C76CA* ID_OUI_FROM_DATABASE=Terasic Technologies Inc. +OUI:1C7839* + ID_OUI_FROM_DATABASE=Shenzhen Tencent Computer System Co., Ltd. + OUI:1C7B21* ID_OUI_FROM_DATABASE=Sony Mobile Communications AB @@ -53788,6 +53845,9 @@ OUI:20BFDB* OUI:20C1AF* ID_OUI_FROM_DATABASE=i Wit Digital Co., Limited +OUI:20C60D* + ID_OUI_FROM_DATABASE=Shanghai annijie Information technology Co.,LTD + OUI:20C6EB* ID_OUI_FROM_DATABASE=Panasonic Corporation AVC Networks Company @@ -54910,6 +54970,9 @@ OUI:3429EA* OUI:342F6E* ID_OUI_FROM_DATABASE=Anywire corporation +OUI:343111* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:3440B5* ID_OUI_FROM_DATABASE=IBM @@ -54979,6 +55042,9 @@ OUI:34862A* OUI:34885D* ID_OUI_FROM_DATABASE=Logitech Far East +OUI:348AAE* + ID_OUI_FROM_DATABASE=SAGEMCOM SAS + OUI:3495DB* ID_OUI_FROM_DATABASE=Logitec Corporation @@ -55066,6 +55132,9 @@ OUI:34BDF9* OUI:34BDFA* ID_OUI_FROM_DATABASE=Cisco SPVTG +OUI:34BE00* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:34BF90* ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Tech.Co.,Ltd. @@ -55150,6 +55219,9 @@ OUI:380A0A* OUI:380A94* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +OUI:380B40* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:380DD4* ID_OUI_FROM_DATABASE=Primax Electronics LTD. @@ -55303,6 +55375,9 @@ OUI:38BB23* OUI:38BC1A* ID_OUI_FROM_DATABASE=Meizu technology co.,ltd +OUI:38BF2F* + ID_OUI_FROM_DATABASE=Espec Corp. + OUI:38BF33* ID_OUI_FROM_DATABASE=NEC CASIO Mobile Communications @@ -55315,6 +55390,9 @@ OUI:38C7BA* OUI:38C85C* ID_OUI_FROM_DATABASE=Cisco SPVTG +OUI:38CA97* + ID_OUI_FROM_DATABASE=Contour Design LLC + OUI:38D135* ID_OUI_FROM_DATABASE=EasyIO Corporation Sdn. Bhd. @@ -55423,6 +55501,9 @@ OUI:3C2DB7* OUI:3C2F3A* ID_OUI_FROM_DATABASE=SFORZATO Corp. +OUI:3C300C* + ID_OUI_FROM_DATABASE=Dewar Electronics Pty Ltd + OUI:3C363D* ID_OUI_FROM_DATABASE=Nokia Corporation @@ -55975,6 +56056,9 @@ OUI:443839* OUI:4439C4* ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co.,Ltd +OUI:443C9C* + ID_OUI_FROM_DATABASE=Pintsch Tiefenbach GmbH + OUI:443D21* ID_OUI_FROM_DATABASE=Nuvolt @@ -56263,6 +56347,9 @@ OUI:489D24* OUI:48A22D* ID_OUI_FROM_DATABASE=Shenzhen Huaxuchang Telecom Technology Co.,Ltd +OUI:48A2B7* + ID_OUI_FROM_DATABASE=Kodofon JSC + OUI:48A6D2* ID_OUI_FROM_DATABASE=GJsun Optical Science and Tech Co.,Ltd. @@ -56845,6 +56932,9 @@ OUI:50FAAB* OUI:50FC30* ID_OUI_FROM_DATABASE=Treehouse Labs +OUI:50FC9F* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:5403F5* ID_OUI_FROM_DATABASE=EBN Technology Corp. @@ -57559,6 +57649,9 @@ OUI:5CFFFF* OUI:6002B4* ID_OUI_FROM_DATABASE=Wistron NeWeb Corp. +OUI:600347* + ID_OUI_FROM_DATABASE=Billion Electric Co. Ltd. + OUI:600F77* ID_OUI_FROM_DATABASE=SilverPlus, Inc @@ -57742,6 +57835,9 @@ OUI:60BC4C* OUI:60BD91* ID_OUI_FROM_DATABASE=Move Innovation +OUI:60BEB5* + ID_OUI_FROM_DATABASE=Motorola Mobility LLC + OUI:60C397* ID_OUI_FROM_DATABASE=2Wire Inc @@ -59446,9 +59542,15 @@ OUI:78ABBB* OUI:78ACC0* ID_OUI_FROM_DATABASE=Hewlett-Packard Company +OUI:78AE0C* + ID_OUI_FROM_DATABASE=Far South Networks + OUI:78B3CE* ID_OUI_FROM_DATABASE=Elo touch solutions +OUI:78B5D2* + ID_OUI_FROM_DATABASE=Ever Treasure Industrial Limited + OUI:78B6C1* ID_OUI_FROM_DATABASE=AOBO Telecom Co.,Ltd @@ -59482,6 +59584,9 @@ OUI:78CA04* OUI:78CA39* ID_OUI_FROM_DATABASE=Apple +OUI:78CA5E* + ID_OUI_FROM_DATABASE=ELNO + OUI:78CB33* ID_OUI_FROM_DATABASE=DHC Software Co.,Ltd @@ -59611,6 +59716,9 @@ OUI:7C1E52* OUI:7C1EB3* ID_OUI_FROM_DATABASE=2N TELEKOMUNIKACE a.s. +OUI:7C2048* + ID_OUI_FROM_DATABASE=KoamTac + OUI:7C2064* ID_OUI_FROM_DATABASE=Alcatel Lucent IPD @@ -59704,6 +59812,9 @@ OUI:7C6F06* OUI:7C6FF8* ID_OUI_FROM_DATABASE=ShenZhen ACTO Digital Video Technology Co.,Ltd. +OUI:7C72E4* + ID_OUI_FROM_DATABASE=Unikey Technologies + OUI:7C7673* ID_OUI_FROM_DATABASE=ENMAS GmbH @@ -59731,6 +59842,9 @@ OUI:7C94B2* OUI:7C95F3* ID_OUI_FROM_DATABASE=Cisco +OUI:7C9763* + ID_OUI_FROM_DATABASE=Openmatics s.r.o. + OUI:7C9A9B* ID_OUI_FROM_DATABASE=VSE valencia smart energy @@ -60217,6 +60331,9 @@ OUI:844F03* OUI:845181* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +OUI:84569C* + ID_OUI_FROM_DATABASE=Coho Data, Inc., + OUI:845787* ID_OUI_FROM_DATABASE=DVR C&C Co., Ltd. @@ -60286,6 +60403,9 @@ OUI:849DC5* OUI:84A6C8* ID_OUI_FROM_DATABASE=Intel Corporate +OUI:84A783* + ID_OUI_FROM_DATABASE=Alcatel Lucent + OUI:84A8E4* ID_OUI_FROM_DATABASE=Shenzhen Huawei Communication Technologies Co., Ltd @@ -60589,6 +60709,9 @@ OUI:88F490* OUI:88FD15* ID_OUI_FROM_DATABASE=LINEEYE CO., LTD +OUI:88FED6* + ID_OUI_FROM_DATABASE=ShangHai WangYong Software Co., Ltd. + OUI:8C006D* ID_OUI_FROM_DATABASE=Apple @@ -61159,6 +61282,9 @@ OUI:940070* OUI:940149* ID_OUI_FROM_DATABASE=AutoHotBox +OUI:9401C2* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:940B2D* ID_OUI_FROM_DATABASE=NetView Technologies(Shenzhen) Co., Ltd @@ -61654,6 +61780,9 @@ OUI:98FE03* OUI:98FE94* ID_OUI_FROM_DATABASE=Apple +OUI:98FFD0* + ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd. + OUI:9C0111* ID_OUI_FROM_DATABASE=Shenzhen Newabel Electronic Co., Ltd. @@ -62167,6 +62296,9 @@ OUI:A0CEC8* OUI:A0CF5B* ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. +OUI:A0D3C1* + ID_OUI_FROM_DATABASE=Hewlett Packard + OUI:A0DC04* ID_OUI_FROM_DATABASE=Becker-Antriebe GmbH @@ -62233,6 +62365,9 @@ OUI:A40130* OUI:A4059E* ID_OUI_FROM_DATABASE=STA Infinity LLP +OUI:A409CB* + ID_OUI_FROM_DATABASE=Alfred Kaercher GmbH & Co KG + OUI:A40BED* ID_OUI_FROM_DATABASE=Carry Technology Co.,Ltd @@ -62326,6 +62461,9 @@ OUI:A46706* OUI:A46E79* ID_OUI_FROM_DATABASE=DFT System Co.Ltd +OUI:A47760* + ID_OUI_FROM_DATABASE=Nokia Corporation + OUI:A479E4* ID_OUI_FROM_DATABASE=KLINFO Corp @@ -62599,6 +62737,9 @@ OUI:A870A5* OUI:A875D6* ID_OUI_FROM_DATABASE=FreeTek International Co., Ltd. +OUI:A875E2* + ID_OUI_FROM_DATABASE=Aventura Technologies, Inc. + OUI:A8776F* ID_OUI_FROM_DATABASE=Zonoff @@ -63541,6 +63682,9 @@ OUI:B82410* OUI:B8241A* ID_OUI_FROM_DATABASE=SWEDA INFORMATICA LTDA +OUI:B8266C* + ID_OUI_FROM_DATABASE=ANOV France + OUI:B826D4* ID_OUI_FROM_DATABASE=Furukawa Industrial S.A. Produtos Elétricos @@ -63871,6 +64015,9 @@ OUI:BC2BD7* OUI:BC2C55* ID_OUI_FROM_DATABASE=Bear Flag Design, Inc. +OUI:BC2D98* + ID_OUI_FROM_DATABASE=ThinGlobal LLC + OUI:BC305B* ID_OUI_FROM_DATABASE=Dell Inc. @@ -64063,6 +64210,9 @@ OUI:BCEA2B* OUI:BCF2AF* ID_OUI_FROM_DATABASE=devolo AG +OUI:BCF5AC* + ID_OUI_FROM_DATABASE=LG Electronics + OUI:BCF685* ID_OUI_FROM_DATABASE=D-Link International @@ -64135,6 +64285,9 @@ OUI:C03F0E* OUI:C03F2A* ID_OUI_FROM_DATABASE=Biscotti, Inc. +OUI:C03FD5* + ID_OUI_FROM_DATABASE=Elitegroup Computer Systems Co., LTD + OUI:C041F6* ID_OUI_FROM_DATABASE=LG Electronics Inc @@ -64183,6 +64336,9 @@ OUI:C06C0F* OUI:C06C6D* ID_OUI_FROM_DATABASE=MagneMotion, Inc. +OUI:C07BBC* + ID_OUI_FROM_DATABASE=Cisco + OUI:C07E40* ID_OUI_FROM_DATABASE=SHENZHEN XDK COMMUNICATION EQUIPMENT CO.,LTD @@ -64309,6 +64465,9 @@ OUI:C0EAE4* OUI:C0F8DA* ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. +OUI:C0F991* + ID_OUI_FROM_DATABASE=GME Standard Communications P/L + OUI:C40142* ID_OUI_FROM_DATABASE=MaxMedia Technology Limited @@ -64390,6 +64549,9 @@ OUI:C4438F* OUI:C44567* ID_OUI_FROM_DATABASE=SAMBON PRECISON and ELECTRONICS +OUI:C445EC* + ID_OUI_FROM_DATABASE=Shanghai Yali Electron Co.,LTD + OUI:C44619* ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. @@ -64654,6 +64816,9 @@ OUI:C84C75* OUI:C85645* ID_OUI_FROM_DATABASE=Intermas France +OUI:C85663* + ID_OUI_FROM_DATABASE=Sunflex Europe GmbH + OUI:C86000* ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. @@ -66277,6 +66442,9 @@ OUI:E0469A* OUI:E05597* ID_OUI_FROM_DATABASE=Emergent Vision Technologies Inc. +OUI:E056F4* + ID_OUI_FROM_DATABASE=AxesNetwork Solutions inc. + OUI:E0589E* ID_OUI_FROM_DATABASE=Laerdal Medical @@ -66451,6 +66619,9 @@ OUI:E0DB55* OUI:E0DCA0* ID_OUI_FROM_DATABASE=Siemens Electrical Apparatus Ltd., Suzhou Chengdu Branch +OUI:E0E631* + ID_OUI_FROM_DATABASE=SNB TECHNOLOGIES LIMITED + OUI:E0E751* ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. @@ -66970,6 +67141,9 @@ OUI:E8E5D6* OUI:E8E732* ID_OUI_FROM_DATABASE=Alcatel-Lucent +OUI:E8E770* + ID_OUI_FROM_DATABASE=Warp9 Tech Design, Inc. + OUI:E8E776* ID_OUI_FROM_DATABASE=Shenzhen Kootion Technology Co., Ltd @@ -67087,6 +67261,9 @@ OUI:EC66D1* OUI:EC6C9F* ID_OUI_FROM_DATABASE=Chengdu Volans Technology CO.,LTD +OUI:EC71DB* + ID_OUI_FROM_DATABASE=Shenzhen Baichuan Digital Technology Co., Ltd. + OUI:EC7C74* ID_OUI_FROM_DATABASE=Justone Technologies Co., Ltd. @@ -67456,6 +67633,9 @@ OUI:F0E5C3* OUI:F0E77E* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +OUI:F0EBD0* + ID_OUI_FROM_DATABASE=Shanghai Feixun Communication Co.,Ltd. + OUI:F0EC39* ID_OUI_FROM_DATABASE=Essec @@ -67765,6 +67945,9 @@ OUI:F81654* OUI:F81A67* ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD. +OUI:F81CE5* + ID_OUI_FROM_DATABASE=Telefonbau Behnke GmbH + OUI:F81D93* ID_OUI_FROM_DATABASE=Longdhua(Beijing) Controls Technology Co.,Ltd @@ -67846,6 +68029,9 @@ OUI:F852DF* OUI:F854AF* ID_OUI_FROM_DATABASE=ECI Telecom Ltd. +OUI:F8572E* + ID_OUI_FROM_DATABASE=Core Brands, LLC + OUI:F85BC9* ID_OUI_FROM_DATABASE=M-Cube Spa @@ -67924,6 +68110,9 @@ OUI:F8A03D* OUI:F8A45F* ID_OUI_FROM_DATABASE=Beijing Xiaomi communications co.,ltd +OUI:F8A963* + ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD. + OUI:F8A9DE* ID_OUI_FROM_DATABASE=PUISSANCE PLUS diff --git a/hwdb/20-pci-vendor-model.hwdb b/hwdb/20-pci-vendor-model.hwdb index f94f54af18..fdb534d7e8 100644 --- a/hwdb/20-pci-vendor-model.hwdb +++ b/hwdb/20-pci-vendor-model.hwdb @@ -4212,7 +4212,7 @@ pci:v00001002d00006651* ID_MODEL_FROM_DATABASE=Bonaire pci:v00001002d00006658* - ID_MODEL_FROM_DATABASE=Bonaire + ID_MODEL_FROM_DATABASE=Bonaire XTX [Radeon R7 260X] pci:v00001002d0000665C* ID_MODEL_FROM_DATABASE=Bonaire XT [Radeon HD 7790/8770] @@ -4245,13 +4245,13 @@ pci:v00001002d00006663* ID_MODEL_FROM_DATABASE=Sun PRO [Radeon HD 8500M Series] pci:v00001002d00006664* - ID_MODEL_FROM_DATABASE=Sun [Radeon R5 M200 Series] + ID_MODEL_FROM_DATABASE=Jet XT [Radeon R5 M200 Series] pci:v00001002d00006665* - ID_MODEL_FROM_DATABASE=Sun [Radeon R5 M200 Series] + ID_MODEL_FROM_DATABASE=Jet PRO [Radeon R5 M200 Series] pci:v00001002d00006667* - ID_MODEL_FROM_DATABASE=Sun [Radeon R5 M200 Series] + ID_MODEL_FROM_DATABASE=Jet ULT [Radeon R5 M200 Series] pci:v00001002d0000666F* ID_MODEL_FROM_DATABASE=Sun [Radeon HD 8500M] @@ -5787,10 +5787,10 @@ pci:v00001002d000067A2* ID_MODEL_FROM_DATABASE=Hawaii GL pci:v00001002d000067B0* - ID_MODEL_FROM_DATABASE=Hawaii XT [Radeon HD 8970] + ID_MODEL_FROM_DATABASE=Hawaii XT [Radeon R9 290X] pci:v00001002d000067B1* - ID_MODEL_FROM_DATABASE=Hawaii PRO + ID_MODEL_FROM_DATABASE=Hawaii PRO [Radeon R9 290] pci:v00001002d000067B9* ID_MODEL_FROM_DATABASE=Vesuvius @@ -5838,10 +5838,10 @@ pci:v00001002d00006809* ID_MODEL_FROM_DATABASE=Pitcairn LE GL [FirePro W5000] pci:v00001002d00006810* - ID_MODEL_FROM_DATABASE=Pitcairn + ID_MODEL_FROM_DATABASE=Curacao XT [Radeon R9 270X] pci:v00001002d00006811* - ID_MODEL_FROM_DATABASE=Pitcairn [Radeon R9 200 Series] + ID_MODEL_FROM_DATABASE=Curacao PRO [Radeon R9 270] pci:v00001002d00006816* ID_MODEL_FROM_DATABASE=Pitcairn @@ -25658,6 +25658,9 @@ pci:v000010DEd00001026* pci:v000010DEd00001028* ID_MODEL_FROM_DATABASE=GK110GL [Tesla K20m] +pci:v000010DEd0000103A* + ID_MODEL_FROM_DATABASE=GK110GL [Quadro K6000] + pci:v000010DEd00001040* ID_MODEL_FROM_DATABASE=GF119 [GeForce GT 520] @@ -26189,6 +26192,9 @@ pci:v000010DEd00001140sv0000152Dsd00000983* pci:v000010DEd00001140sv0000152Dsd00001030* ID_MODEL_FROM_DATABASE=GeForce GT 630M +pci:v000010DEd00001140sv0000152Dsd00001055* + ID_MODEL_FROM_DATABASE=GeForce 710M + pci:v000010DEd00001140sv000017AAsd00002200* ID_MODEL_FROM_DATABASE=NVS 5200M @@ -26384,6 +26390,9 @@ pci:v000010DEd000011B0sv000010DEsd0000101B* pci:v000010DEd000011B1* ID_MODEL_FROM_DATABASE=GK104GL [Tesla K2 USM] +pci:v000010DEd000011B6* + ID_MODEL_FROM_DATABASE=GK104GLM [Quadro K3100M] + pci:v000010DEd000011B7* ID_MODEL_FROM_DATABASE=GK104GLM [Quadro K4100M] @@ -26645,6 +26654,9 @@ pci:v000010DEd00001294* pci:v000010DEd00001295* ID_MODEL_FROM_DATABASE=GK208M [GeForce 710M] +pci:v000010DEd00001298* + ID_MODEL_FROM_DATABASE=GK208M [GeForce GT 720M] + pci:v000010DEd000012A0* ID_MODEL_FROM_DATABASE=GK208 @@ -46280,6 +46292,12 @@ pci:v000015B3d00001015* pci:v000015B3d00001016* ID_MODEL_FROM_DATABASE=MT27631 Family +pci:v000015B3d00001017* + ID_MODEL_FROM_DATABASE=MT27640 Family + +pci:v000015B3d00001018* + ID_MODEL_FROM_DATABASE=MT27641 Family + pci:v000015B3d00005274* ID_MODEL_FROM_DATABASE=MT21108 InfiniBridge @@ -48155,6 +48173,12 @@ pci:v0000175E* pci:v00001760* ID_VENDOR_FROM_DATABASE=TEDIA spol. s r. o. +pci:v00001760d00000101* + ID_MODEL_FROM_DATABASE=PCD-7004 Digital Bi-Directional Ports PCI Card + +pci:v00001760d00000102* + ID_MODEL_FROM_DATABASE=PCD-7104 Digital Input & Output PCI Card + pci:v00001771* ID_VENDOR_FROM_DATABASE=InnoVISION Multimedia Ltd. @@ -51138,7 +51162,7 @@ pci:v00001B4Bd00009192* ID_MODEL_FROM_DATABASE=88SE9172 SATA III 6Gb/s RAID Controller pci:v00001B4Bd000091A0* - ID_MODEL_FROM_DATABASE=88SE91A0 SATA 6Gb/s Controller + ID_MODEL_FROM_DATABASE=88SE912x SATA 6Gb/s Controller [IDE mode] pci:v00001B4Bd000091A4* ID_MODEL_FROM_DATABASE=88SE912x IDE Controller @@ -51149,6 +51173,9 @@ pci:v00001B4Bd00009230* pci:v00001B4Bd00009480* ID_MODEL_FROM_DATABASE=88SE9480 SAS/SATA 6Gb/s RAID controller +pci:v00001B4Bd00009485* + ID_MODEL_FROM_DATABASE=88SE9485 SAS/SATA 6Gb/s controller + pci:v00001B55* ID_VENDOR_FROM_DATABASE=NetUP Inc. @@ -54354,352 +54381,397 @@ pci:v00008086d00000D36* ID_MODEL_FROM_DATABASE=Crystal Well Integrated Graphics Controller pci:v00008086d00000E00* - ID_MODEL_FROM_DATABASE=Ivytown DMI2 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DMI2 pci:v00008086d00000E01* - ID_MODEL_FROM_DATABASE=Ivytown PCI Express Root Port in DMI2 Mode + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 PCI Express Root Port in DMI2 Mode pci:v00008086d00000E02* - ID_MODEL_FROM_DATABASE=Ivytown PCI Express Root Port 1a + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 PCI Express Root Port 1a pci:v00008086d00000E03* - ID_MODEL_FROM_DATABASE=Ivytown PCI Express Root Port 1b + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 PCI Express Root Port 1b pci:v00008086d00000E04* - ID_MODEL_FROM_DATABASE=Ivytown PCI Express Root Port 2a + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 PCI Express Root Port 2a pci:v00008086d00000E05* - ID_MODEL_FROM_DATABASE=Ivytown PCI Express Root Port 2b + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 PCI Express Root Port 2b pci:v00008086d00000E06* - ID_MODEL_FROM_DATABASE=Ivytown PCI Express Root Port 2c + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 PCI Express Root Port 2c pci:v00008086d00000E07* - ID_MODEL_FROM_DATABASE=Ivytown PCI Express Root Port 2d + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 PCI Express Root Port 2d pci:v00008086d00000E08* - ID_MODEL_FROM_DATABASE=Ivytown PCI Express Root Port 3a + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 PCI Express Root Port 3a pci:v00008086d00000E09* - ID_MODEL_FROM_DATABASE=Ivytown PCI Express Root Port 3b + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 PCI Express Root Port 3b pci:v00008086d00000E0A* - ID_MODEL_FROM_DATABASE=Ivytown PCI Express Root Port 3c + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 PCI Express Root Port 3c pci:v00008086d00000E0B* - ID_MODEL_FROM_DATABASE=Ivytown PCI Express Root Port 3d + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 PCI Express Root Port 3d + +pci:v00008086d00000E10* + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 IIO Configuration Registers + +pci:v00008086d00000E13* + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 IIO Configuration Registers + +pci:v00008086d00000E17* + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 IIO Configuration Registers + +pci:v00008086d00000E18* + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 IIO Configuration Registers pci:v00008086d00000E1C* - ID_MODEL_FROM_DATABASE=Ivytown Debug and Error Injection Related Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 IIO Configuration Registers pci:v00008086d00000E1D* - ID_MODEL_FROM_DATABASE=Ivytown R2PCIe + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 R2PCIe pci:v00008086d00000E1E* - ID_MODEL_FROM_DATABASE=Ivytown Semaphore and Scratchpad Configuration Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 UBOX Registers pci:v00008086d00000E1F* - ID_MODEL_FROM_DATABASE=Ivytown Semaphore and Scratchpad Configuration Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 UBOX Registers pci:v00008086d00000E20* - ID_MODEL_FROM_DATABASE=Ivytown Crystal Beach DMA Channel 0 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Crystal Beach DMA Channel 0 pci:v00008086d00000E21* - ID_MODEL_FROM_DATABASE=Ivytown Crystal Beach DMA Channel 1 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Crystal Beach DMA Channel 1 pci:v00008086d00000E22* - ID_MODEL_FROM_DATABASE=Ivytown Crystal Beach DMA Channel 2 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Crystal Beach DMA Channel 2 pci:v00008086d00000E23* - ID_MODEL_FROM_DATABASE=Ivytown Crystal Beach DMA Channel 3 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Crystal Beach DMA Channel 3 pci:v00008086d00000E24* - ID_MODEL_FROM_DATABASE=Ivytown Crystal Beach DMA Channel 4 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Crystal Beach DMA Channel 4 pci:v00008086d00000E25* - ID_MODEL_FROM_DATABASE=Ivytown Crystal Beach DMA Channel 5 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Crystal Beach DMA Channel 5 pci:v00008086d00000E26* - ID_MODEL_FROM_DATABASE=Ivytown Crystal Beach DMA Channel 6 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Crystal Beach DMA Channel 6 pci:v00008086d00000E27* - ID_MODEL_FROM_DATABASE=Ivytown Crystal Beach DMA Channel 7 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Crystal Beach DMA Channel 7 pci:v00008086d00000E28* - ID_MODEL_FROM_DATABASE=Ivytown VTd/Memory Map/Misc + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 VTd/Memory Map/Misc pci:v00008086d00000E29* - ID_MODEL_FROM_DATABASE=Ivytown Memory Hotplug + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Memory Hotplug pci:v00008086d00000E2A* - ID_MODEL_FROM_DATABASE=Ivytown IIO RAS + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 IIO RAS pci:v00008086d00000E2C* - ID_MODEL_FROM_DATABASE=Ivytown IOAPIC + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 IOAPIC pci:v00008086d00000E2E* - ID_MODEL_FROM_DATABASE=Ivytown CBDMA + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 CBDMA pci:v00008086d00000E2F* - ID_MODEL_FROM_DATABASE=Ivytown CBDMA + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 CBDMA pci:v00008086d00000E30* - ID_MODEL_FROM_DATABASE=Ivytown Home Agent 0 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Home Agent 0 pci:v00008086d00000E32* - ID_MODEL_FROM_DATABASE=Ivytown QPI Link 0 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Link 0 pci:v00008086d00000E33* - ID_MODEL_FROM_DATABASE=Ivytown QPI Link 1 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Link 1 pci:v00008086d00000E34* - ID_MODEL_FROM_DATABASE=Ivytown PCI Express Ring Performance Monitoring + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 R2PCIe pci:v00008086d00000E36* - ID_MODEL_FROM_DATABASE=Ivytown QPI Ring Performance Ring Monitoring + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Ring Performance Ring Monitoring pci:v00008086d00000E37* - ID_MODEL_FROM_DATABASE=Ivytown QPI Ring Performance Ring Monitoring + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Ring Performance Ring Monitoring pci:v00008086d00000E38* - ID_MODEL_FROM_DATABASE=Ivytown Home Agent 1 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Home Agent 1 pci:v00008086d00000E3A* - ID_MODEL_FROM_DATABASE=Ivytown QPI Link 2 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Link 2 pci:v00008086d00000E3E* - ID_MODEL_FROM_DATABASE=Ivytown QPI Ring Performance Ring Monitoring + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Ring Performance Ring Monitoring pci:v00008086d00000E3F* - ID_MODEL_FROM_DATABASE=Ivytown QPI Ring Performance Ring Monitoring + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Ring Performance Ring Monitoring pci:v00008086d00000E40* - ID_MODEL_FROM_DATABASE=Ivytown QPI Link 2 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Link 2 pci:v00008086d00000E41* - ID_MODEL_FROM_DATABASE=Ivytown QPI Ring Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Ring Registers pci:v00008086d00000E43* - ID_MODEL_FROM_DATABASE=Ivytown QPI Link Reut 2 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Link Reut 2 pci:v00008086d00000E44* - ID_MODEL_FROM_DATABASE=Ivytown QPI Link Reut 2 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Link Reut 2 pci:v00008086d00000E60* - ID_MODEL_FROM_DATABASE=Ivytown Home Agent 1 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Home Agent 1 pci:v00008086d00000E68* - ID_MODEL_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Target Address/Thermal Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 1 Target Address/Thermal Registers pci:v00008086d00000E6A* - ID_MODEL_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel Target Address Decoder Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel Target Address Decoder Registers pci:v00008086d00000E6B* - ID_MODEL_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel Target Address Decoder Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel Target Address Decoder Registers pci:v00008086d00000E6C* - ID_MODEL_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel Target Address Decoder Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel Target Address Decoder Registers pci:v00008086d00000E6D* - ID_MODEL_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel Target Address Decoder Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel Target Address Decoder Registers pci:v00008086d00000E71* - ID_MODEL_FROM_DATABASE=Ivytown Integrated Memory Controller 0 RAS Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 0 RAS Registers + +pci:v00008086d00000E74* + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 R2PCIe + +pci:v00008086d00000E75* + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 R2PCIe + +pci:v00008086d00000E77* + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Ring Registers pci:v00008086d00000E79* - ID_MODEL_FROM_DATABASE=Ivytown Integrated Memory Controller 1 RAS Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 1 RAS Registers + +pci:v00008086d00000E7D* + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 UBOX Registers + +pci:v00008086d00000E7F* + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Ring Registers pci:v00008086d00000E80* - ID_MODEL_FROM_DATABASE=Ivytown QPI Link 0 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Link 0 pci:v00008086d00000E81* - ID_MODEL_FROM_DATABASE=Ivytown QPI Ring Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Ring Registers pci:v00008086d00000E83* - ID_MODEL_FROM_DATABASE=Ivytown QPI Link Reut 0 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Link Reut 0 pci:v00008086d00000E84* - ID_MODEL_FROM_DATABASE=Ivytown QPI Link Reut 0 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Link Reut 0 + +pci:v00008086d00000E87* + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Registers pci:v00008086d00000E90* - ID_MODEL_FROM_DATABASE=Ivytown QPI Link 1 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Link 1 pci:v00008086d00000E93* - ID_MODEL_FROM_DATABASE=Ivytown QPI Link 1 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Link 1 pci:v00008086d00000E94* - ID_MODEL_FROM_DATABASE=Ivytown QPI Link Reut 1 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Link Reut 1 pci:v00008086d00000EA0* - ID_MODEL_FROM_DATABASE=Ivytown Home Agent 0 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Home Agent 0 pci:v00008086d00000EA8* - ID_MODEL_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Target Address/Thermal Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 0 Target Address/Thermal Registers pci:v00008086d00000EAA* - ID_MODEL_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel Target Address Decoder Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel Target Address Decoder Registers pci:v00008086d00000EAB* - ID_MODEL_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel Target Address Decoder Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel Target Address Decoder Registers pci:v00008086d00000EAC* - ID_MODEL_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel Target Address Decoder Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel Target Address Decoder Registers pci:v00008086d00000EAD* - ID_MODEL_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel Target Address Decoder Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel Target Address Decoder Registers + +pci:v00008086d00000EAE* + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO Registers + +pci:v00008086d00000EAF* + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO Registers pci:v00008086d00000EB0* - ID_MODEL_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel 0-3 Thermal Control 0 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel 0-3 Thermal Control 0 pci:v00008086d00000EB1* - ID_MODEL_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel 0-3 Thermal Control 1 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel 0-3 Thermal Control 1 pci:v00008086d00000EB2* - ID_MODEL_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel 0-3 ERROR Registers 0 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel 0-3 ERROR Registers 0 pci:v00008086d00000EB3* - ID_MODEL_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel 0-3 ERROR Registers 1 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel 0-3 ERROR Registers 1 pci:v00008086d00000EB4* - ID_MODEL_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel 0-3 Thermal Control 2 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel 0-3 Thermal Control 2 pci:v00008086d00000EB5* - ID_MODEL_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel 0-3 Thermal Control 3 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel 0-3 Thermal Control 3 pci:v00008086d00000EB6* - ID_MODEL_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel 0-3 ERROR Registers 2 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel 0-3 ERROR Registers 2 pci:v00008086d00000EB7* - ID_MODEL_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel 0-3 ERROR Registers 3 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel 0-3 ERROR Registers 3 + +pci:v00008086d00000EBC* + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO Registers + +pci:v00008086d00000EBE* + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO Registers + +pci:v00008086d00000EBF* + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO Registers pci:v00008086d00000EC0* - ID_MODEL_FROM_DATABASE=Ivytown Power Control Unit 0 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Power Control Unit 0 pci:v00008086d00000EC1* - ID_MODEL_FROM_DATABASE=Ivytown Power Control Unit 1 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Power Control Unit 1 pci:v00008086d00000EC2* - ID_MODEL_FROM_DATABASE=Ivytown Power Control Unit 2 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Power Control Unit 2 pci:v00008086d00000EC3* - ID_MODEL_FROM_DATABASE=Ivytown Power Control Unit 3 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Power Control Unit 3 pci:v00008086d00000EC4* - ID_MODEL_FROM_DATABASE=Ivytown Power Control Unit 4 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Power Control Unit 4 pci:v00008086d00000EC8* - ID_MODEL_FROM_DATABASE=Ivytown System Address Decoder + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 System Address Decoder pci:v00008086d00000EC9* - ID_MODEL_FROM_DATABASE=Ivytown Broadcast Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Broadcast Registers pci:v00008086d00000ECA* - ID_MODEL_FROM_DATABASE=Ivytown Broadcast Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Broadcast Registers pci:v00008086d00000ED8* - ID_MODEL_FROM_DATABASE=Ivytown DDRIO + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO pci:v00008086d00000ED9* - ID_MODEL_FROM_DATABASE=Ivytown DDRIO + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO pci:v00008086d00000EDC* - ID_MODEL_FROM_DATABASE=Ivytown DDRIO + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO pci:v00008086d00000EDD* - ID_MODEL_FROM_DATABASE=Ivytown DDRIO + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO pci:v00008086d00000EDE* - ID_MODEL_FROM_DATABASE=Ivytown DDRIO + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO pci:v00008086d00000EDF* - ID_MODEL_FROM_DATABASE=Ivytown DDRIO + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO pci:v00008086d00000EE0* - ID_MODEL_FROM_DATABASE=Ivytown Unicast Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers pci:v00008086d00000EE1* - ID_MODEL_FROM_DATABASE=Ivytown Unicast Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers pci:v00008086d00000EE2* - ID_MODEL_FROM_DATABASE=Ivytown Unicast Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers pci:v00008086d00000EE3* - ID_MODEL_FROM_DATABASE=Ivytown Unicast Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers pci:v00008086d00000EE4* - ID_MODEL_FROM_DATABASE=Ivytown Unicast Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers pci:v00008086d00000EE5* - ID_MODEL_FROM_DATABASE=Ivytown Unicast Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers pci:v00008086d00000EE6* - ID_MODEL_FROM_DATABASE=Ivytown Unicast Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers pci:v00008086d00000EE7* - ID_MODEL_FROM_DATABASE=Ivytown Unicast Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers pci:v00008086d00000EE8* - ID_MODEL_FROM_DATABASE=Ivytown Unicast Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers pci:v00008086d00000EE9* - ID_MODEL_FROM_DATABASE=Ivytown Unicast Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers pci:v00008086d00000EEA* - ID_MODEL_FROM_DATABASE=Ivytown Unicast Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers pci:v00008086d00000EEB* - ID_MODEL_FROM_DATABASE=Ivytown Unicast Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers pci:v00008086d00000EEC* - ID_MODEL_FROM_DATABASE=Ivytown Unicast Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers pci:v00008086d00000EED* - ID_MODEL_FROM_DATABASE=Ivytown Unicast Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers pci:v00008086d00000EEE* - ID_MODEL_FROM_DATABASE=Ivytown Unicast Registers + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers pci:v00008086d00000EF0* - ID_MODEL_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel 0-3 Thermal Control 0 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel 0-3 Thermal Control 0 pci:v00008086d00000EF1* - ID_MODEL_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel 0-3 Thermal Control 1 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel 0-3 Thermal Control 1 pci:v00008086d00000EF2* - ID_MODEL_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel 0-3 ERROR Registers 0 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel 0-3 ERROR Registers 0 pci:v00008086d00000EF3* - ID_MODEL_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel 0-3 ERROR Registers 1 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel 0-3 ERROR Registers 1 pci:v00008086d00000EF4* - ID_MODEL_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel 0-3 Thermal Control 2 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel 0-3 Thermal Control 2 pci:v00008086d00000EF5* - ID_MODEL_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel 0-3 Thermal Control 3 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel 0-3 Thermal Control 3 pci:v00008086d00000EF6* - ID_MODEL_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel 0-3 ERROR Registers 2 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel 0-3 ERROR Registers 2 pci:v00008086d00000EF7* - ID_MODEL_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel 0-3 ERROR Registers 3 + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel 0-3 ERROR Registers 3 pci:v00008086d00000EF8* - ID_MODEL_FROM_DATABASE=Ivytown DDRIO + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO pci:v00008086d00000EF9* - ID_MODEL_FROM_DATABASE=Ivytown DDRIO + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO pci:v00008086d00000EFA* - ID_MODEL_FROM_DATABASE=Ivytown DDRIO + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO pci:v00008086d00000EFB* - ID_MODEL_FROM_DATABASE=Ivytown DDRIO + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO pci:v00008086d00000EFC* - ID_MODEL_FROM_DATABASE=Ivytown DDRIO + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO pci:v00008086d00000EFD* - ID_MODEL_FROM_DATABASE=Ivytown DDRIO + ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO pci:v00008086d00000F00* ID_MODEL_FROM_DATABASE=ValleyView SSA-CUnit -- cgit v1.2.1 From ee9c9500ab13c1093fc3feaf2aa5a0d330d0bfad Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 24 Sep 2013 15:47:42 +0200 Subject: TODO: add header back --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index b79e265cc6..0f2398a7ab 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,5 @@ +Bugfixes: + * enabling an instance unit creates pointless link, and the unit will be started with getty@getty.service: $ systemctl enable getty@.service -- cgit v1.2.1 From a6dbecc4e2a1b52daef5ba3b8e5ecf322352ffdb Mon Sep 17 00:00:00 2001 From: Lukas Nykryn Date: Tue, 24 Sep 2013 16:27:20 +0200 Subject: logind: return -EINVAL when PID is wrong dbus-send --print-reply --system --dest=org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager.GetUserByPID uint32:0 causes systemd-logind[29843]: Assertion 'pid >= 1' failed at src/login/logind.c:938, function manager_get_user_by_pid(). Aborting. --- src/login/logind.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/login/logind.c b/src/login/logind.c index 702382acff..8bf520a2db 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -993,9 +993,11 @@ int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) { int r; assert(m); - assert(pid >= 1); assert(session); + if (pid < 1) + return -EINVAL; + r = cg_pid_get_unit(pid, &unit); if (r < 0) return r; @@ -1014,9 +1016,11 @@ int manager_get_user_by_pid(Manager *m, pid_t pid, User **user) { int r; assert(m); - assert(pid >= 1); assert(user); + if (pid < 1) + return -EINVAL; + r = cg_pid_get_slice(pid, &unit); if (r < 0) return r; -- cgit v1.2.1 From 8bd94f7a03032ac9218e88e8e099e974627a3bcb Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Tue, 24 Sep 2013 14:39:40 -0400 Subject: journalctl(1): s/adm/systemd-journal/ --- man/journalctl.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/journalctl.xml b/man/journalctl.xml index a5778bf369..b5a0c539ca 100644 --- a/man/journalctl.xml +++ b/man/journalctl.xml @@ -104,7 +104,7 @@ All users are granted access to their private per-user journals. However, by default, only root and - users who are members of the adm + users who are members of the systemd-journal group get access to the system journal and the journals of other users. -- cgit v1.2.1 From 13b84ec7df103ce388910a2b868fe1668c1e27ef Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 23 Sep 2013 21:56:05 -0500 Subject: cgroup: if we do a cgroup operation then do something on all supported controllers Previously we did operations like attach, trim or migrate only on the controllers that were enabled for a specific unit. With this changes we will now do them for all supproted controllers, and fall back to all possible prefix paths if the specified paths do not exist. This fixes issues if a controller is being disabled for a unit where it was previously enabled, and makes sure that all processes stay as "far down" the tree as groups exist. --- src/core/cgroup.c | 8 +-- src/core/execute.c | 4 +- src/core/mount.c | 2 +- src/core/scope.c | 2 +- src/core/service.c | 2 +- src/core/socket.c | 2 +- src/core/swap.c | 2 +- src/shared/cgroup-util.c | 154 ++++++++++++++++++++++++++++++----------------- src/shared/cgroup-util.h | 12 ++-- 9 files changed, 118 insertions(+), 70 deletions(-) diff --git a/src/core/cgroup.c b/src/core/cgroup.c index e66b8f4851..8bf4d896de 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -397,13 +397,13 @@ static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) { } /* First, create our own group */ - r = cg_create_with_mask(mask, path); + r = cg_create_everywhere(u->manager->cgroup_supported, mask, path); if (r < 0) log_error("Failed to create cgroup %s: %s", path, strerror(-r)); /* Then, possibly move things over */ - if (u->cgroup_path && !streq(path, u->cgroup_path)) { - r = cg_migrate_with_mask(mask, u->cgroup_path, path); + if (u->cgroup_path) { + r = cg_migrate_everywhere(u->manager->cgroup_supported, u->cgroup_path, path); if (r < 0) log_error("Failed to migrate cgroup %s: %s", path, strerror(-r)); } @@ -537,7 +537,7 @@ void unit_destroy_cgroup(Unit *u) { if (!u->cgroup_path) return; - r = cg_trim_with_mask(u->cgroup_mask, u->cgroup_path, !unit_has_name(u, SPECIAL_ROOT_SLICE)); + r = cg_trim_everywhere(u->manager->cgroup_supported, u->cgroup_path, !unit_has_name(u, SPECIAL_ROOT_SLICE)); if (r < 0) log_debug("Failed to destroy cgroup %s: %s", u->cgroup_path, strerror(-r)); diff --git a/src/core/execute.c b/src/core/execute.c index f840642d14..0bfa41836a 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -1017,7 +1017,7 @@ int exec_spawn(ExecCommand *command, bool apply_chroot, bool apply_tty_stdin, bool confirm_spawn, - CGroupControllerMask cgroup_mask, + CGroupControllerMask cgroup_supported, const char *cgroup_path, const char *unit_id, int idle_pipe[4], @@ -1198,7 +1198,7 @@ int exec_spawn(ExecCommand *command, } if (cgroup_path) { - err = cg_attach_with_mask(cgroup_mask, cgroup_path, 0); + err = cg_attach_everywhere(cgroup_supported, cgroup_path, 0); if (err < 0) { r = EXIT_CGROUP; goto fail_child; diff --git a/src/core/mount.c b/src/core/mount.c index 5c18d4e463..78c5c1e6d6 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -888,7 +888,7 @@ static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) { true, true, UNIT(m)->manager->confirm_spawn, - UNIT(m)->cgroup_mask, + UNIT(m)->manager->cgroup_supported, UNIT(m)->cgroup_path, UNIT(m)->id, NULL, diff --git a/src/core/scope.c b/src/core/scope.c index b94f3ff7ba..50e5dbacb4 100644 --- a/src/core/scope.c +++ b/src/core/scope.c @@ -257,7 +257,7 @@ static int scope_start(Unit *u) { return r; } - r = cg_attach_many_with_mask(u->cgroup_mask, u->cgroup_path, s->pids); + r = cg_attach_many_everywhere(u->manager->cgroup_supported, u->cgroup_path, s->pids); if (r < 0) return r; diff --git a/src/core/service.c b/src/core/service.c index cc61b546fc..24b7bef287 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -1820,7 +1820,7 @@ static int service_spawn( apply_chroot, apply_tty_stdin, UNIT(s)->manager->confirm_spawn, - UNIT(s)->cgroup_mask, + UNIT(s)->manager->cgroup_supported, path, UNIT(s)->id, s->type == SERVICE_IDLE ? UNIT(s)->manager->idle_pipe : NULL, diff --git a/src/core/socket.c b/src/core/socket.c index 46a73e0108..190b36c3ca 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -1239,7 +1239,7 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) { true, true, UNIT(s)->manager->confirm_spawn, - UNIT(s)->cgroup_mask, + UNIT(s)->manager->cgroup_supported, UNIT(s)->cgroup_path, UNIT(s)->id, NULL, diff --git a/src/core/swap.c b/src/core/swap.c index 82bfad187e..dc6731ab30 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -625,7 +625,7 @@ static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) { true, true, UNIT(s)->manager->confirm_spawn, - UNIT(s)->cgroup_mask, + UNIT(s)->manager->cgroup_supported, UNIT(s)->cgroup_path, UNIT(s)->id, NULL, diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index 0bffebdac8..2e630d4708 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -435,6 +435,46 @@ int cg_migrate_recursive( return ret; } +int cg_migrate_recursive_fallback( + const char *cfrom, + const char *pfrom, + const char *cto, + const char *pto, + bool ignore_self, + bool rem) { + + int r; + + assert(cfrom); + assert(pfrom); + assert(cto); + assert(pto); + + r = cg_migrate_recursive(cfrom, pfrom, cto, pto, ignore_self, rem); + if (r < 0) { + char prefix[strlen(pto) + 1]; + + /* This didn't work? Then let's try all prefixes of the destination */ + + strcpy(prefix, pto); + for (;;) { + char *slash; + + slash = strrchr(prefix, '/'); + if (!slash) + break; + + *slash = 0; + + r = cg_migrate_recursive(cfrom, pfrom, cto, prefix, ignore_self, rem); + if (r >= 0) + break; + } + } + + return r; +} + static const char *normalize_controller(const char *controller) { assert(controller); @@ -607,6 +647,39 @@ int cg_attach(const char *controller, const char *path, pid_t pid) { return write_string_file(fs, c); } +int cg_attach_fallback(const char *controller, const char *path, pid_t pid) { + int r; + + assert(controller); + assert(path); + assert(pid >= 0); + + r = cg_attach(controller, path, pid); + if (r < 0) { + char prefix[strlen(path) + 1]; + + /* This didn't work? Then let's try all prefixes of + * the destination */ + + strcpy(prefix, path); + for (;;) { + char *slash; + + slash = strrchr(prefix, '/'); + if (!slash) + break; + + *slash = 0; + + r = cg_attach(controller, prefix, pid); + if (r >= 0) + break; + } + } + + return r; +} + int cg_set_group_access( const char *controller, const char *path, @@ -1607,7 +1680,7 @@ static const char mask_names[] = "memory\0" "devices\0"; -int cg_create_with_mask(CGroupControllerMask mask, const char *path) { +int cg_create_everywhere(CGroupControllerMask supported, CGroupControllerMask mask, const char *path) { CGroupControllerMask bit = 1; const char *n; int r; @@ -1623,102 +1696,75 @@ int cg_create_with_mask(CGroupControllerMask mask, const char *path) { /* Then, do the same in the other hierarchies */ NULSTR_FOREACH(n, mask_names) { - if (bit & mask) + if (mask & bit) cg_create(n, path); - else + else if (supported & bit) cg_trim(n, path, true); bit <<= 1; } - return r; + return 0; } -int cg_attach_with_mask(CGroupControllerMask mask, const char *path, pid_t pid) { +int cg_attach_everywhere(CGroupControllerMask supported, const char *path, pid_t pid) { CGroupControllerMask bit = 1; const char *n; int r; r = cg_attach(SYSTEMD_CGROUP_CONTROLLER, path, pid); + if (r < 0) + return r; NULSTR_FOREACH(n, mask_names) { - if (bit & mask) - cg_attach(n, path, pid); - else { - char prefix[strlen(path) + 1], *slash; - - /* OK, this one is a bit harder... Now we need - * to add to the closest parent cgroup we - * can find */ - strcpy(prefix, path); - while ((slash = strrchr(prefix, '/'))) { - int q; - *slash = 0; - - q = cg_attach(n, prefix, pid); - if (q >= 0) - break; - } - } + if (supported & bit) + cg_attach_fallback(n, path, pid); bit <<= 1; } - return r; + return 0; } -int cg_attach_many_with_mask(CGroupControllerMask mask, const char *path, Set* pids) { +int cg_attach_many_everywhere(CGroupControllerMask supported, const char *path, Set* pids) { Iterator i; void *pidp; int r = 0; SET_FOREACH(pidp, pids, i) { pid_t pid = PTR_TO_LONG(pidp); - int k; + int q; - k = cg_attach_with_mask(mask, path, pid); - if (k < 0) - r = k; + q = cg_attach_everywhere(supported, path, pid); + if (q < 0) + r = q; } return r; } -int cg_migrate_with_mask(CGroupControllerMask mask, const char *from, const char *to) { +int cg_migrate_everywhere(CGroupControllerMask supported, const char *from, const char *to) { CGroupControllerMask bit = 1; const char *n; int r; - if (path_equal(from, to)) - return 0; - - r = cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, from, SYSTEMD_CGROUP_CONTROLLER, to, false, true); + if (!path_equal(from, to)) { + r = cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, from, SYSTEMD_CGROUP_CONTROLLER, to, false, true); + if (r < 0) + return r; + } NULSTR_FOREACH(n, mask_names) { - if (bit & mask) - cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, to, n, to, false, false); - else { - char prefix[strlen(to) + 1], *slash; - - strcpy(prefix, to); - while ((slash = strrchr(prefix, '/'))) { - int q; - - *slash = 0; - - q = cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, to, n, prefix, false, false); - if (q >= 0) - break; - } - } + if (supported & bit) + cg_migrate_recursive_fallback(SYSTEMD_CGROUP_CONTROLLER, to, n, to, false, false); bit <<= 1; } - return r; + return 0; } -int cg_trim_with_mask(CGroupControllerMask mask, const char *path, bool delete_root) { +int cg_trim_everywhere(CGroupControllerMask supported, const char *path, bool delete_root) { CGroupControllerMask bit = 1; const char *n; int r; @@ -1728,13 +1774,13 @@ int cg_trim_with_mask(CGroupControllerMask mask, const char *path, bool delete_r return r; NULSTR_FOREACH(n, mask_names) { - if (bit & mask) + if (supported & bit) cg_trim(n, path, delete_root); bit <<= 1; } - return r; + return 0; } CGroupControllerMask cg_mask_supported(void) { diff --git a/src/shared/cgroup-util.h b/src/shared/cgroup-util.h index 0fc93c12c8..0963450b08 100644 --- a/src/shared/cgroup-util.h +++ b/src/shared/cgroup-util.h @@ -64,6 +64,7 @@ int cg_kill_recursive_and_wait(const char *controller, const char *path, bool re int cg_migrate(const char *cfrom, const char *pfrom, const char *cto, const char *pto, bool ignore_self); int cg_migrate_recursive(const char *cfrom, const char *pfrom, const char *cto, const char *pto, bool ignore_self, bool remove); +int cg_migrate_recursive_fallback(const char *cfrom, const char *pfrom, const char *cto, const char *pto, bool ignore_self, bool rem); int cg_split_spec(const char *spec, char **controller, char **path); int cg_join_spec(const char *controller, const char *path, char **spec); @@ -81,6 +82,7 @@ int cg_delete(const char *controller, const char *path); int cg_create(const char *controller, const char *path); int cg_attach(const char *controller, const char *path, pid_t pid); +int cg_attach_fallback(const char *controller, const char *path, pid_t pid); int cg_create_and_attach(const char *controller, const char *path, pid_t pid); int cg_set_attribute(const char *controller, const char *path, const char *attribute, const char *value); @@ -126,10 +128,10 @@ bool cg_controller_is_valid(const char *p, bool allow_named); int cg_slice_to_path(const char *unit, char **ret); -int cg_create_with_mask(CGroupControllerMask mask, const char *path); -int cg_attach_with_mask(CGroupControllerMask mask, const char *path, pid_t pid); -int cg_attach_many_with_mask(CGroupControllerMask mask, const char *path, Set* pids); -int cg_migrate_with_mask(CGroupControllerMask mask, const char *from, const char *to); -int cg_trim_with_mask(CGroupControllerMask mask, const char *path, bool delete_root); +int cg_create_everywhere(CGroupControllerMask supported, CGroupControllerMask mask, const char *path); +int cg_attach_everywhere(CGroupControllerMask supported, const char *path, pid_t pid); +int cg_attach_many_everywhere(CGroupControllerMask supported, const char *path, Set* pids); +int cg_migrate_everywhere(CGroupControllerMask supported, const char *from, const char *to); +int cg_trim_everywhere(CGroupControllerMask supported, const char *path, bool delete_root); CGroupControllerMask cg_mask_supported(void); -- cgit v1.2.1 From bc5fb0809e6f5784888f30057708548f14dcb459 Mon Sep 17 00:00:00 2001 From: Jimmie Tauriainen Date: Wed, 25 Sep 2013 07:30:23 +0200 Subject: keymap: Add Samsung Ativ 9 Plus https://launchpad.net/bugs/1229936 --- hwdb/60-keyboard.hwdb | 1 + 1 file changed, 1 insertion(+) diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index fe051a5c17..20d398f7d9 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -904,6 +904,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*550P*:pvr* KEYBOARD_KEY_a9=! # Fn Lock - Function lock off keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700Z*:pvr* +keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*940X3G*:pvr* KEYBOARD_KEY_ce=!prog1 # Fn+F1 launch settings KEYBOARD_KEY_a0=!mute # Fn+F6 mute KEYBOARD_KEY_ae=!volumedown # Fn+F7 -- cgit v1.2.1 From fecffe5d0a1bd66d80e5a8728ff8a89673be0df7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 25 Sep 2013 20:58:23 +0200 Subject: util: add macro for iterating through all prefixes of a path Syntactic sugar in a macro PATH_FOREACH_PREFIX. --- src/shared/cgroup-util.c | 26 ++++---------------------- src/shared/path-util.h | 3 +++ src/test/test-path-util.c | 27 +++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 22 deletions(-) diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index 2e630d4708..dc0fe85ee2 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -456,23 +456,14 @@ int cg_migrate_recursive_fallback( /* This didn't work? Then let's try all prefixes of the destination */ - strcpy(prefix, pto); - for (;;) { - char *slash; - - slash = strrchr(prefix, '/'); - if (!slash) - break; - - *slash = 0; - + PATH_FOREACH_PREFIX(prefix, pto) { r = cg_migrate_recursive(cfrom, pfrom, cto, prefix, ignore_self, rem); if (r >= 0) break; } } - return r; + return 0; } static const char *normalize_controller(const char *controller) { @@ -661,23 +652,14 @@ int cg_attach_fallback(const char *controller, const char *path, pid_t pid) { /* This didn't work? Then let's try all prefixes of * the destination */ - strcpy(prefix, path); - for (;;) { - char *slash; - - slash = strrchr(prefix, '/'); - if (!slash) - break; - - *slash = 0; - + PATH_FOREACH_PREFIX(prefix, path) { r = cg_attach(controller, prefix, pid); if (r >= 0) break; } } - return r; + return 0; } int cg_set_group_access( diff --git a/src/shared/path-util.h b/src/shared/path-util.h index 9452931586..03f2cf273c 100644 --- a/src/shared/path-util.h +++ b/src/shared/path-util.h @@ -51,3 +51,6 @@ int path_is_read_only_fs(const char *path); int path_is_os_tree(const char *path); int find_binary(const char *name, char **filename); + +#define PATH_FOREACH_PREFIX(prefix, path) \ + for (char *_slash = strrchr(path_kill_slashes(strcpy(prefix, path)), '/'); _slash && !(*_slash = 0); _slash = strrchr((prefix), '/')) diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c index b0aeb11a63..e303e488e2 100644 --- a/src/test/test-path-util.c +++ b/src/test/test-path-util.c @@ -106,8 +106,35 @@ static void test_find_binary(void) { assert(find_binary("xxxx-xxxx", &p) == -ENOENT); } +static void test_prefixes(void) { + static const char* values[] = { "/a/b/c", "/a/b", "/a", "", NULL}; + unsigned i = 0; + char s[PATH_MAX]; + + PATH_FOREACH_PREFIX(s, "/a/b/c/d") { + log_error("---%s---", s); + assert_se(streq(s, values[i++])); + } + + assert_se(values[i] == NULL); + + i = 0; + PATH_FOREACH_PREFIX(s, "////a////b////c///d///////") + assert_se(streq(s, values[i++])); + + assert_se(values[i] == NULL); + + PATH_FOREACH_PREFIX(s, "////") + assert_se(streq(s, "")); + + PATH_FOREACH_PREFIX(s, "") + assert_not_reached("wut?"); + +} + int main(void) { test_path(); test_find_binary(); + test_prefixes(); return 0; } -- cgit v1.2.1 From f546241b6dd82d20ff915f618d143a19db8a4574 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 28 Aug 2013 07:54:43 -0400 Subject: execute.c: little modernization --- src/core/execute.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/core/execute.c b/src/core/execute.c index 0bfa41836a..a53ef48ef8 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -760,24 +760,30 @@ static int setup_pam( * daemon. We do things this way to ensure that the main PID * of the daemon is the one we initially fork()ed. */ - if ((pam_code = pam_start(name, user, &conv, &handle)) != PAM_SUCCESS) { + pam_code = pam_start(name, user, &conv, &handle); + if (pam_code != PAM_SUCCESS) { handle = NULL; goto fail; } - if (tty) - if ((pam_code = pam_set_item(handle, PAM_TTY, tty)) != PAM_SUCCESS) + if (tty) { + pam_code = pam_set_item(handle, PAM_TTY, tty); + if (pam_code != PAM_SUCCESS) goto fail; + } - if ((pam_code = pam_acct_mgmt(handle, PAM_SILENT)) != PAM_SUCCESS) + pam_code = pam_acct_mgmt(handle, PAM_SILENT); + if (pam_code != PAM_SUCCESS) goto fail; - if ((pam_code = pam_open_session(handle, PAM_SILENT)) != PAM_SUCCESS) + pam_code = pam_open_session(handle, PAM_SILENT); + if (pam_code != PAM_SUCCESS) goto fail; close_session = true; - if ((!(e = pam_getenvlist(handle)))) { + e = pam_getenvlist(handle); + if (!e) { pam_code = PAM_BUF_ERR; goto fail; } @@ -791,7 +797,8 @@ static int setup_pam( parent_pid = getpid(); - if ((pam_pid = fork()) < 0) + pam_pid = fork(); + if (pam_pid < 0) goto fail; if (pam_pid == 0) { @@ -842,9 +849,11 @@ static int setup_pam( } /* If our parent died we'll end the session */ - if (getppid() != parent_pid) - if ((pam_code = pam_close_session(handle, PAM_DATA_SILENT)) != PAM_SUCCESS) + if (getppid() != parent_pid) { + pam_code = pam_close_session(handle, PAM_DATA_SILENT); + if (pam_code != PAM_SUCCESS) goto child_finish; + } r = 0; -- cgit v1.2.1 From 8097ab4f0cf7a52ac6ca45cb2b2dfe4850a2dee5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 25 Sep 2013 17:52:43 +0200 Subject: test-hashmap: fix access to uninitialized memory --- src/test/test-hashmap.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/test/test-hashmap.c b/src/test/test-hashmap.c index 2aead79bb1..2c27d08670 100644 --- a/src/test/test-hashmap.c +++ b/src/test/test-hashmap.c @@ -468,9 +468,11 @@ static void test_hashmap_get(void) { } static void test_uint64_compare_func(void) { - assert_se(uint64_compare_func("a", "a") == 0); - assert_se(uint64_compare_func("a", "b") == -1); - assert_se(uint64_compare_func("b", "a") == 1); + const uint64_t a = 0x100, b = 0x101; + + assert_se(uint64_compare_func(&a, &a) == 0); + assert_se(uint64_compare_func(&a, &b) == -1); + assert_se(uint64_compare_func(&b, &a) == 1); } static void test_trivial_compare_func(void) { -- cgit v1.2.1 From 5843c5ebb4341382ae9c87e93c2c87467e573548 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 19 Sep 2013 16:57:57 -0500 Subject: journald: accept EPOLLERR from /dev/kmsg Also print out unexpected epoll events explictly. --- src/journal/journald-server.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index cc8ce0dc0d..e888480284 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -1060,7 +1060,8 @@ int process_event(Server *s, struct epoll_event *ev) { ssize_t n; if (ev->events != EPOLLIN) { - log_error("Got invalid event from epoll."); + log_error("Got invalid event from epoll for %s: %"PRIx32, + "signal fd", ev->events); return -EIO; } @@ -1113,8 +1114,12 @@ int process_event(Server *s, struct epoll_event *ev) { } else if (ev->data.fd == s->dev_kmsg_fd) { int r; - if (ev->events != EPOLLIN) { - log_error("Got invalid event from epoll."); + if (ev->events & EPOLLERR) + log_warning("/dev/kmsg buffer overrun, some messages lost."); + + if (!(ev->events & EPOLLIN)) { + log_error("Got invalid event from epoll for %s: %"PRIx32, + "/dev/kmsg", ev->events); return -EIO; } @@ -1128,7 +1133,9 @@ int process_event(Server *s, struct epoll_event *ev) { ev->data.fd == s->syslog_fd) { if (ev->events != EPOLLIN) { - log_error("Got invalid event from epoll."); + log_error("Got invalid event from epoll for %s: %"PRIx32, + ev->data.fd == s->native_fd ? "native fd" : "syslog fd", + ev->events); return -EIO; } @@ -1249,7 +1256,8 @@ int process_event(Server *s, struct epoll_event *ev) { } else if (ev->data.fd == s->stdout_fd) { if (ev->events != EPOLLIN) { - log_error("Got invalid event from epoll."); + log_error("Got invalid event from epoll for %s: %"PRIx32, + "stdout fd", ev->events); return -EIO; } @@ -1260,6 +1268,8 @@ int process_event(Server *s, struct epoll_event *ev) { StdoutStream *stream; if ((ev->events|EPOLLIN|EPOLLHUP) != (EPOLLIN|EPOLLHUP)) { + log_error("Got invalid event from epoll for %s: %"PRIx32, + "stdout stream", ev->events); log_error("Got invalid event from epoll."); return -EIO; } -- cgit v1.2.1 From 732bfe09aeffc3cd78b80ee9e20c9c3babd944d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 26 Sep 2013 10:31:44 +0200 Subject: build-sys: add ./configure --enable-address-sanitizer Enabling address sanitizer seems like a useful thing, but is quite tricky. Proper flags have to be passed to CPPFLAGS, CFLAGS and LDFLAGS, but passing them on the commandline doesn't work because we tests are done with ld directly, and not with libtool like in real linking. We might want to fix this, but let's add a handy way to enable address checking anyway. --- configure.ac | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 156cc96e07..af0dbbeeee 100644 --- a/configure.ac +++ b/configure.ac @@ -101,6 +101,20 @@ if test -z "$GPERF" ; then AC_MSG_ERROR([*** gperf not found]) fi +# ------------------------------------------------------------------------------ +address_sanitizer_cflags= +address_sanitizer_cppflags= +address_sanitizer_ldflags= +AC_ARG_ENABLE(address-sanitizer, AS_HELP_STRING([--enable-address-sanitizer], [enable -fsanitize=address])) +AS_IF([test "x$enable_address_sanitizer" = "xyes"], [ + CC_CHECK_FLAG_APPEND([with_as_cflags], [CFLAGS], [-fsanitize=address]) + AS_IF([test -z "$with_as_cflags"], + [AC_MSG_ERROR([*** -fsanitize=address is not supported])]) + address_sanitizer_cflags="$with_as_cflags -fno-omit-frame-pointer -DVALGRIND=1" + address_sanitizer_cppflags="-DVALGRIND=1" + address_sanitizer_ldflags="-Wc,-fsanitize=address" + ]) + CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [\ -pipe \ -Wall \ @@ -142,13 +156,13 @@ CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [\ -fdata-sections \ -fstack-protector \ --param=ssp-buffer-size=4]) -AC_SUBST([OUR_CFLAGS], $with_cflags) +AC_SUBST([OUR_CFLAGS], "$with_cflags $address_sanitizer_cflags") AS_CASE([$CFLAGS], [*-O[[12345g\ ]]*], [CC_CHECK_FLAGS_APPEND([with_cppflags], [CPPFLAGS], [\ -Wp,-D_FORTIFY_SOURCE=2])], [AC_MSG_RESULT([skipping -D_FORTIFY_SOURCE, optimization not enabled])]) -AC_SUBST([OUR_CPPFLAGS], $with_cppflags) +AC_SUBST([OUR_CPPFLAGS], "$with_cppflags $address_sanitizer_cppflags") CC_CHECK_FLAGS_APPEND([with_ldflags], [LDFLAGS], [\ -Wl,--as-needed \ @@ -156,7 +170,7 @@ CC_CHECK_FLAGS_APPEND([with_ldflags], [LDFLAGS], [\ -Wl,--gc-sections \ -Wl,-z,relro \ -Wl,-z,now]) -AC_SUBST([OUR_LDFLAGS], $with_ldflags) +AC_SUBST([OUR_LDFLAGS], "$with_ldflags $address_sanitizer_ldflags") # ------------------------------------------------------------------------------ # we use python to build the man page index, and for systemd-python -- cgit v1.2.1 From bd16acf35e13a19cd2ded0a0c2ef774a98f73808 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 25 Sep 2013 13:26:08 +0200 Subject: Move functions around to fix underlinking in test-machine-tables --- src/machine/machined-dbus.c | 46 +++++++++++++++++++++++++++++++++++++++++++++ src/machine/machined.c | 46 --------------------------------------------- 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c index a526a5243e..22caadfceb 100644 --- a/src/machine/machined-dbus.c +++ b/src/machine/machined-dbus.c @@ -40,6 +40,7 @@ #include "unit-name.h" #include "bus-errors.h" #include "virt.h" +#include "cgroup-util.h" #define BUS_MANAGER_INTERFACE \ " \n" \ @@ -994,3 +995,48 @@ int manager_unit_is_active(Manager *manager, const char *unit) { return !streq(state, "inactive") && !streq(state, "failed"); } + +int manager_add_machine(Manager *m, const char *name, Machine **_machine) { + Machine *machine; + + assert(m); + assert(name); + + machine = hashmap_get(m->machines, name); + if (machine) { + if (_machine) + *_machine = machine; + + return 0; + } + + machine = machine_new(m, name); + if (!machine) + return -ENOMEM; + + if (_machine) + *_machine = machine; + + return 0; +} + +int manager_get_machine_by_pid(Manager *m, pid_t pid, Machine **machine) { + _cleanup_free_ char *unit = NULL; + Machine *mm; + int r; + + assert(m); + assert(pid >= 1); + assert(machine); + + r = cg_pid_get_unit(pid, &unit); + if (r < 0) + return r; + + mm = hashmap_get(m->machine_units, unit); + if (!mm) + return 0; + + *machine = mm; + return 1; +} diff --git a/src/machine/machined.c b/src/machine/machined.c index 3ce51da90d..ad804a1e14 100644 --- a/src/machine/machined.c +++ b/src/machine/machined.c @@ -34,7 +34,6 @@ #include "strv.h" #include "conf-parser.h" #include "mkdir.h" -#include "cgroup-util.h" Manager *manager_new(void) { Manager *m; @@ -83,30 +82,6 @@ void manager_free(Manager *m) { free(m); } -int manager_add_machine(Manager *m, const char *name, Machine **_machine) { - Machine *machine; - - assert(m); - assert(name); - - machine = hashmap_get(m->machines, name); - if (machine) { - if (_machine) - *_machine = machine; - - return 0; - } - - machine = machine_new(m, name); - if (!machine) - return -ENOMEM; - - if (_machine) - *_machine = machine; - - return 0; -} - int manager_enumerate_machines(Manager *m) { _cleanup_closedir_ DIR *d = NULL; struct dirent *de; @@ -149,27 +124,6 @@ int manager_enumerate_machines(Manager *m) { return r; } -int manager_get_machine_by_pid(Manager *m, pid_t pid, Machine **machine) { - _cleanup_free_ char *unit = NULL; - Machine *mm; - int r; - - assert(m); - assert(pid >= 1); - assert(machine); - - r = cg_pid_get_unit(pid, &unit); - if (r < 0) - return r; - - mm = hashmap_get(m->machine_units, unit); - if (!mm) - return 0; - - *machine = mm; - return 1; -} - static int manager_connect_bus(Manager *m) { DBusError error; int r; -- cgit v1.2.1 From 2b3ab29de466ae6bd7c3243a5a48c7291cc2af0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 25 Sep 2013 17:04:41 +0200 Subject: Move part of logind.c into a separate file liblogind-core.la was underlinked, missing a few functions defined in logind.c. They are moved to a new file, logind-core.c, and this file is linked into liblogind-core.la. In addition, logind-acl.c is attached to the liblogind-core.la, instead of systemd-logind directly. --- Makefile.am | 17 +- src/login/logind-core.c | 514 ++++++++++++++++++++++++++++++++++++++++++++++++ src/login/logind.c | 484 --------------------------------------------- 3 files changed, 523 insertions(+), 492 deletions(-) create mode 100644 src/login/logind-core.c diff --git a/Makefile.am b/Makefile.am index 0eee1d93f0..92de1630b4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3761,15 +3761,8 @@ systemd_logind_LDADD = \ libsystemd-logind-core.la \ $(libsystemd_logind_core_la_LIBADD) -if HAVE_ACL -systemd_logind_SOURCES += \ - src/login/logind-acl.c - -systemd_logind_LDADD += \ - libsystemd-acl.la -endif - libsystemd_logind_core_la_SOURCES = \ + src/login/logind-core.c \ src/login/logind-dbus.c \ src/login/logind-device.c \ src/login/logind-device.h \ @@ -3807,6 +3800,14 @@ libsystemd_logind_core_la_LIBADD = \ libsystemd-id128-internal.la \ libudev.la +if HAVE_ACL +libsystemd_logind_core_la_SOURCES += \ + src/login/logind-acl.c + +libsystemd_logind_core_la_LIBADD += \ + libsystemd-acl.la +endif + noinst_LTLIBRARIES += \ libsystemd-logind-core.la diff --git a/src/login/logind-core.c b/src/login/logind-core.c new file mode 100644 index 0000000000..36999ace40 --- /dev/null +++ b/src/login/logind-core.c @@ -0,0 +1,514 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include "logind.h" +#include "dbus-common.h" +#include "strv.h" + +int manager_add_device(Manager *m, const char *sysfs, bool master, Device **_device) { + Device *d; + + assert(m); + assert(sysfs); + + d = hashmap_get(m->devices, sysfs); + if (d) { + if (_device) + *_device = d; + + /* we support adding master-flags, but not removing them */ + d->master = d->master || master; + + return 0; + } + + d = device_new(m, sysfs, master); + if (!d) + return -ENOMEM; + + if (_device) + *_device = d; + + return 0; +} + +int manager_add_seat(Manager *m, const char *id, Seat **_seat) { + Seat *s; + + assert(m); + assert(id); + + s = hashmap_get(m->seats, id); + if (s) { + if (_seat) + *_seat = s; + + return 0; + } + + s = seat_new(m, id); + if (!s) + return -ENOMEM; + + if (_seat) + *_seat = s; + + return 0; +} + +int manager_add_session(Manager *m, const char *id, Session **_session) { + Session *s; + + assert(m); + assert(id); + + s = hashmap_get(m->sessions, id); + if (s) { + if (_session) + *_session = s; + + return 0; + } + + s = session_new(m, id); + if (!s) + return -ENOMEM; + + if (_session) + *_session = s; + + return 0; +} + +int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **_user) { + User *u; + + assert(m); + assert(name); + + u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid)); + if (u) { + if (_user) + *_user = u; + + return 0; + } + + u = user_new(m, uid, gid, name); + if (!u) + return -ENOMEM; + + if (_user) + *_user = u; + + return 0; +} + +int manager_add_user_by_name(Manager *m, const char *name, User **_user) { + uid_t uid; + gid_t gid; + int r; + + assert(m); + assert(name); + + r = get_user_creds(&name, &uid, &gid, NULL, NULL); + if (r < 0) + return r; + + return manager_add_user(m, uid, gid, name, _user); +} + +int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user) { + struct passwd *p; + + assert(m); + + errno = 0; + p = getpwuid(uid); + if (!p) + return errno ? -errno : -ENOENT; + + return manager_add_user(m, uid, p->pw_gid, p->pw_name, _user); +} + +int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **_inhibitor) { + Inhibitor *i; + + assert(m); + assert(id); + + i = hashmap_get(m->inhibitors, id); + if (i) { + if (_inhibitor) + *_inhibitor = i; + + return 0; + } + + i = inhibitor_new(m, id); + if (!i) + return -ENOMEM; + + if (_inhibitor) + *_inhibitor = i; + + return 0; +} + +int manager_add_button(Manager *m, const char *name, Button **_button) { + Button *b; + + assert(m); + assert(name); + + b = hashmap_get(m->buttons, name); + if (b) { + if (_button) + *_button = b; + + return 0; + } + + b = button_new(m, name); + if (!b) + return -ENOMEM; + + if (_button) + *_button = b; + + return 0; +} + +int manager_watch_busname(Manager *m, const char *name) { + char *n; + int r; + + assert(m); + assert(name); + + if (hashmap_get(m->busnames, name)) + return 0; + + n = strdup(name); + if (!n) + return -ENOMEM; + + r = hashmap_put(m->busnames, n, n); + if (r < 0) { + free(n); + return r; + } + + return 0; +} + +void manager_drop_busname(Manager *m, const char *name) { + Session *session; + Iterator i; + char *key; + + assert(m); + assert(name); + + if (!hashmap_get(m->busnames, name)) + return; + + /* keep it if the name still owns a controller */ + HASHMAP_FOREACH(session, m->sessions, i) + if (session_is_controller(session, name)) + return; + + key = hashmap_remove(m->busnames, name); + if (key) + free(key); +} + +int manager_process_seat_device(Manager *m, struct udev_device *d) { + Device *device; + int r; + + assert(m); + + if (streq_ptr(udev_device_get_action(d), "remove")) { + + device = hashmap_get(m->devices, udev_device_get_syspath(d)); + if (!device) + return 0; + + seat_add_to_gc_queue(device->seat); + device_free(device); + + } else { + const char *sn; + Seat *seat = NULL; + bool master; + + sn = udev_device_get_property_value(d, "ID_SEAT"); + if (isempty(sn)) + sn = "seat0"; + + if (!seat_name_is_valid(sn)) { + log_warning("Device with invalid seat name %s found, ignoring.", sn); + return 0; + } + + /* ignore non-master devices for unknown seats */ + master = udev_device_has_tag(d, "master-of-seat"); + if (!master && !(seat = hashmap_get(m->seats, sn))) + return 0; + + r = manager_add_device(m, udev_device_get_syspath(d), master, &device); + if (r < 0) + return r; + + if (!seat) { + r = manager_add_seat(m, sn, &seat); + if (r < 0) { + if (!device->seat) + device_free(device); + + return r; + } + } + + device_attach(device, seat); + seat_start(seat); + } + + return 0; +} + +int manager_process_button_device(Manager *m, struct udev_device *d) { + Button *b; + + int r; + + assert(m); + + if (streq_ptr(udev_device_get_action(d), "remove")) { + + b = hashmap_get(m->buttons, udev_device_get_sysname(d)); + if (!b) + return 0; + + button_free(b); + + } else { + const char *sn; + + r = manager_add_button(m, udev_device_get_sysname(d), &b); + if (r < 0) + return r; + + sn = udev_device_get_property_value(d, "ID_SEAT"); + if (isempty(sn)) + sn = "seat0"; + + button_set_seat(b, sn); + button_open(b); + } + + return 0; +} + +int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) { + _cleanup_free_ char *unit = NULL; + Session *s; + int r; + + assert(m); + assert(session); + + if (pid < 1) + return -EINVAL; + + r = cg_pid_get_unit(pid, &unit); + if (r < 0) + return r; + + s = hashmap_get(m->session_units, unit); + if (!s) + return 0; + + *session = s; + return 1; +} + +int manager_get_user_by_pid(Manager *m, pid_t pid, User **user) { + _cleanup_free_ char *unit = NULL; + User *u; + int r; + + assert(m); + assert(user); + + if (pid < 1) + return -EINVAL; + + r = cg_pid_get_slice(pid, &unit); + if (r < 0) + return r; + + u = hashmap_get(m->user_units, unit); + if (!u) + return 0; + + *user = u; + return 1; +} + +int manager_get_idle_hint(Manager *m, dual_timestamp *t) { + Session *s; + bool idle_hint; + dual_timestamp ts = { 0, 0 }; + Iterator i; + + assert(m); + + idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t, false, false, 0); + + HASHMAP_FOREACH(s, m->sessions, i) { + dual_timestamp k; + int ih; + + ih = session_get_idle_hint(s, &k); + if (ih < 0) + return ih; + + if (!ih) { + if (!idle_hint) { + if (k.monotonic < ts.monotonic) + ts = k; + } else { + idle_hint = false; + ts = k; + } + } else if (idle_hint) { + + if (k.monotonic > ts.monotonic) + ts = k; + } + } + + if (t) + *t = ts; + + return idle_hint; +} + +bool manager_shall_kill(Manager *m, const char *user) { + assert(m); + assert(user); + + if (!m->kill_user_processes) + return false; + + if (strv_contains(m->kill_exclude_users, user)) + return false; + + if (strv_isempty(m->kill_only_users)) + return true; + + return strv_contains(m->kill_only_users, user); +} + +static int vt_is_busy(int vtnr) { + struct vt_stat vt_stat; + int r = 0, fd; + + assert(vtnr >= 1); + + /* We explicitly open /dev/tty1 here instead of /dev/tty0. If + * we'd open the latter we'd open the foreground tty which + * hence would be unconditionally busy. By opening /dev/tty1 + * we avoid this. Since tty1 is special and needs to be an + * explicitly loaded getty or DM this is safe. */ + + fd = open_terminal("/dev/tty1", O_RDWR|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return -errno; + + if (ioctl(fd, VT_GETSTATE, &vt_stat) < 0) + r = -errno; + else + r = !!(vt_stat.v_state & (1 << vtnr)); + + close_nointr_nofail(fd); + + return r; +} + +int manager_spawn_autovt(Manager *m, int vtnr) { + int r; + char *name = NULL; + const char *mode = "fail"; + + assert(m); + assert(vtnr >= 1); + + if ((unsigned) vtnr > m->n_autovts && + (unsigned) vtnr != m->reserve_vt) + return 0; + + if ((unsigned) vtnr != m->reserve_vt) { + /* If this is the reserved TTY, we'll start the getty + * on it in any case, but otherwise only if it is not + * busy. */ + + r = vt_is_busy(vtnr); + if (r < 0) + return r; + else if (r > 0) + return -EBUSY; + } + + if (asprintf(&name, "autovt@tty%i.service", vtnr) < 0) { + log_error("Could not allocate service name."); + r = -ENOMEM; + goto finish; + } + + r = bus_method_call_with_reply ( + m->bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "StartUnit", + NULL, + NULL, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &mode, + DBUS_TYPE_INVALID); + +finish: + free(name); + + return r; +} diff --git a/src/login/logind.c b/src/login/logind.c index 8bf520a2db..0628032ae5 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -20,13 +20,11 @@ ***/ #include -#include #include #include #include #include #include -#include #include #include @@ -192,313 +190,6 @@ void manager_free(Manager *m) { free(m); } -int manager_add_device(Manager *m, const char *sysfs, bool master, Device **_device) { - Device *d; - - assert(m); - assert(sysfs); - - d = hashmap_get(m->devices, sysfs); - if (d) { - if (_device) - *_device = d; - - /* we support adding master-flags, but not removing them */ - d->master = d->master || master; - - return 0; - } - - d = device_new(m, sysfs, master); - if (!d) - return -ENOMEM; - - if (_device) - *_device = d; - - return 0; -} - -int manager_add_seat(Manager *m, const char *id, Seat **_seat) { - Seat *s; - - assert(m); - assert(id); - - s = hashmap_get(m->seats, id); - if (s) { - if (_seat) - *_seat = s; - - return 0; - } - - s = seat_new(m, id); - if (!s) - return -ENOMEM; - - if (_seat) - *_seat = s; - - return 0; -} - -int manager_add_session(Manager *m, const char *id, Session **_session) { - Session *s; - - assert(m); - assert(id); - - s = hashmap_get(m->sessions, id); - if (s) { - if (_session) - *_session = s; - - return 0; - } - - s = session_new(m, id); - if (!s) - return -ENOMEM; - - if (_session) - *_session = s; - - return 0; -} - -int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **_user) { - User *u; - - assert(m); - assert(name); - - u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid)); - if (u) { - if (_user) - *_user = u; - - return 0; - } - - u = user_new(m, uid, gid, name); - if (!u) - return -ENOMEM; - - if (_user) - *_user = u; - - return 0; -} - -int manager_add_user_by_name(Manager *m, const char *name, User **_user) { - uid_t uid; - gid_t gid; - int r; - - assert(m); - assert(name); - - r = get_user_creds(&name, &uid, &gid, NULL, NULL); - if (r < 0) - return r; - - return manager_add_user(m, uid, gid, name, _user); -} - -int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user) { - struct passwd *p; - - assert(m); - - errno = 0; - p = getpwuid(uid); - if (!p) - return errno ? -errno : -ENOENT; - - return manager_add_user(m, uid, p->pw_gid, p->pw_name, _user); -} - -int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **_inhibitor) { - Inhibitor *i; - - assert(m); - assert(id); - - i = hashmap_get(m->inhibitors, id); - if (i) { - if (_inhibitor) - *_inhibitor = i; - - return 0; - } - - i = inhibitor_new(m, id); - if (!i) - return -ENOMEM; - - if (_inhibitor) - *_inhibitor = i; - - return 0; -} - -int manager_add_button(Manager *m, const char *name, Button **_button) { - Button *b; - - assert(m); - assert(name); - - b = hashmap_get(m->buttons, name); - if (b) { - if (_button) - *_button = b; - - return 0; - } - - b = button_new(m, name); - if (!b) - return -ENOMEM; - - if (_button) - *_button = b; - - return 0; -} - -int manager_watch_busname(Manager *m, const char *name) { - char *n; - int r; - - assert(m); - assert(name); - - if (hashmap_get(m->busnames, name)) - return 0; - - n = strdup(name); - if (!n) - return -ENOMEM; - - r = hashmap_put(m->busnames, n, n); - if (r < 0) { - free(n); - return r; - } - - return 0; -} - -void manager_drop_busname(Manager *m, const char *name) { - Session *session; - Iterator i; - char *key; - - assert(m); - assert(name); - - if (!hashmap_get(m->busnames, name)) - return; - - /* keep it if the name still owns a controller */ - HASHMAP_FOREACH(session, m->sessions, i) - if (session_is_controller(session, name)) - return; - - key = hashmap_remove(m->busnames, name); - if (key) - free(key); -} - -int manager_process_seat_device(Manager *m, struct udev_device *d) { - Device *device; - int r; - - assert(m); - - if (streq_ptr(udev_device_get_action(d), "remove")) { - - device = hashmap_get(m->devices, udev_device_get_syspath(d)); - if (!device) - return 0; - - seat_add_to_gc_queue(device->seat); - device_free(device); - - } else { - const char *sn; - Seat *seat = NULL; - bool master; - - sn = udev_device_get_property_value(d, "ID_SEAT"); - if (isempty(sn)) - sn = "seat0"; - - if (!seat_name_is_valid(sn)) { - log_warning("Device with invalid seat name %s found, ignoring.", sn); - return 0; - } - - /* ignore non-master devices for unknown seats */ - master = udev_device_has_tag(d, "master-of-seat"); - if (!master && !(seat = hashmap_get(m->seats, sn))) - return 0; - - r = manager_add_device(m, udev_device_get_syspath(d), master, &device); - if (r < 0) - return r; - - if (!seat) { - r = manager_add_seat(m, sn, &seat); - if (r < 0) { - if (!device->seat) - device_free(device); - - return r; - } - } - - device_attach(device, seat); - seat_start(seat); - } - - return 0; -} - -int manager_process_button_device(Manager *m, struct udev_device *d) { - Button *b; - - int r; - - assert(m); - - if (streq_ptr(udev_device_get_action(d), "remove")) { - - b = hashmap_get(m->buttons, udev_device_get_sysname(d)); - if (!b) - return 0; - - button_free(b); - - } else { - const char *sn; - - r = manager_add_button(m, udev_device_get_sysname(d), &b); - if (r < 0) - return r; - - sn = udev_device_get_property_value(d, "ID_SEAT"); - if (isempty(sn)) - sn = "seat0"; - - button_set_seat(b, sn); - button_open(b); - } - - return 0; -} - int manager_enumerate_devices(Manager *m) { struct udev_list_entry *item = NULL, *first = NULL; struct udev_enumerate *e; @@ -890,80 +581,6 @@ int manager_dispatch_console(Manager *m) { return 0; } -static int vt_is_busy(int vtnr) { - struct vt_stat vt_stat; - int r = 0, fd; - - assert(vtnr >= 1); - - /* We explicitly open /dev/tty1 here instead of /dev/tty0. If - * we'd open the latter we'd open the foreground tty which - * hence would be unconditionally busy. By opening /dev/tty1 - * we avoid this. Since tty1 is special and needs to be an - * explicitly loaded getty or DM this is safe. */ - - fd = open_terminal("/dev/tty1", O_RDWR|O_NOCTTY|O_CLOEXEC); - if (fd < 0) - return -errno; - - if (ioctl(fd, VT_GETSTATE, &vt_stat) < 0) - r = -errno; - else - r = !!(vt_stat.v_state & (1 << vtnr)); - - close_nointr_nofail(fd); - - return r; -} - -int manager_spawn_autovt(Manager *m, int vtnr) { - int r; - char *name = NULL; - const char *mode = "fail"; - - assert(m); - assert(vtnr >= 1); - - if ((unsigned) vtnr > m->n_autovts && - (unsigned) vtnr != m->reserve_vt) - return 0; - - if ((unsigned) vtnr != m->reserve_vt) { - /* If this is the reserved TTY, we'll start the getty - * on it in any case, but otherwise only if it is not - * busy. */ - - r = vt_is_busy(vtnr); - if (r < 0) - return r; - else if (r > 0) - return -EBUSY; - } - - if (asprintf(&name, "autovt@tty%i.service", vtnr) < 0) { - log_error("Could not allocate service name."); - r = -ENOMEM; - goto finish; - } - - r = bus_method_call_with_reply ( - m->bus, - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - "StartUnit", - NULL, - NULL, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_STRING, &mode, - DBUS_TYPE_INVALID); - -finish: - free(name); - - return r; -} - static int manager_reserve_vt(Manager *m) { _cleanup_free_ char *p = NULL; @@ -987,52 +604,6 @@ static int manager_reserve_vt(Manager *m) { return 0; } -int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) { - _cleanup_free_ char *unit = NULL; - Session *s; - int r; - - assert(m); - assert(session); - - if (pid < 1) - return -EINVAL; - - r = cg_pid_get_unit(pid, &unit); - if (r < 0) - return r; - - s = hashmap_get(m->session_units, unit); - if (!s) - return 0; - - *session = s; - return 1; -} - -int manager_get_user_by_pid(Manager *m, pid_t pid, User **user) { - _cleanup_free_ char *unit = NULL; - User *u; - int r; - - assert(m); - assert(user); - - if (pid < 1) - return -EINVAL; - - r = cg_pid_get_slice(pid, &unit); - if (r < 0) - return r; - - u = hashmap_get(m->user_units, unit); - if (!u) - return 0; - - *user = u; - return 1; -} - static void manager_dispatch_other(Manager *m, int fd) { Session *s; Inhibitor *i; @@ -1390,61 +961,6 @@ void manager_gc(Manager *m, bool drop_not_started) { } } -int manager_get_idle_hint(Manager *m, dual_timestamp *t) { - Session *s; - bool idle_hint; - dual_timestamp ts = { 0, 0 }; - Iterator i; - - assert(m); - - idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t, false, false, 0); - - HASHMAP_FOREACH(s, m->sessions, i) { - dual_timestamp k; - int ih; - - ih = session_get_idle_hint(s, &k); - if (ih < 0) - return ih; - - if (!ih) { - if (!idle_hint) { - if (k.monotonic < ts.monotonic) - ts = k; - } else { - idle_hint = false; - ts = k; - } - } else if (idle_hint) { - - if (k.monotonic > ts.monotonic) - ts = k; - } - } - - if (t) - *t = ts; - - return idle_hint; -} - -bool manager_shall_kill(Manager *m, const char *user) { - assert(m); - assert(user); - - if (!m->kill_user_processes) - return false; - - if (strv_contains(m->kill_exclude_users, user)) - return false; - - if (strv_isempty(m->kill_only_users)) - return true; - - return strv_contains(m->kill_only_users, user); -} - int manager_dispatch_idle_action(Manager *m) { struct dual_timestamp since; struct itimerspec its = {}; -- cgit v1.2.1 From baa89da40a1d42242c9c62603501ada7e9e52613 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 26 Sep 2013 19:57:58 +0200 Subject: cgroup: when referencing cgroup controller trees allow omission of the path --- TODO | 2 ++ src/cgls/cgls.c | 4 +++- src/shared/cgroup-util.c | 33 +++++++++++++++++++++------------ 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/TODO b/TODO index 0f2398a7ab..474532164b 100644 --- a/TODO +++ b/TODO @@ -56,6 +56,8 @@ CGroup Rework Completion: Features: +* move config_parse_path_strv() out of conf-parser.c + * libdsystemd-bus should expose utf8 validation calls * When using "systemd status" on a slice unit also show all messages diff --git a/src/cgls/cgls.c b/src/cgls/cgls.c index c3229ad2d3..c689b5c471 100644 --- a/src/cgls/cgls.c +++ b/src/cgls/cgls.c @@ -156,7 +156,9 @@ int main(int argc, char *argv[]) { for (i = optind; i < argc; i++) { int q; - printf("%s:\n", argv[i]); + + fprintf(stdout, "%s:\n", argv[i]); + fflush(stdout); if (arg_machine) root = strjoin("machine/", arg_machine, "/", argv[i], NULL); diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index dc0fe85ee2..f57f2b2c42 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -1003,19 +1003,28 @@ int cg_split_spec(const char *spec, char **controller, char **path) { return -EINVAL; } - u = strdup(e+1); - if (!u) { - free(t); - return -ENOMEM; - } - if (!path_is_safe(u) || - !path_is_absolute(u)) { - free(t); - free(u); - return -EINVAL; - } + if (streq(e+1, "")) { + u = strdup("/"); + if (!u) { + free(t); + return -ENOMEM; + } + } else { + u = strdup(e+1); + if (!u) { + free(t); + return -ENOMEM; + } - path_kill_slashes(u); + if (!path_is_safe(u) || + !path_is_absolute(u)) { + free(t); + free(u); + return -EINVAL; + } + + path_kill_slashes(u); + } if (controller) *controller = t; -- cgit v1.2.1 From e203f7c3ad6a95dfa6179e30904ce0432ea0de91 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 26 Sep 2013 19:58:33 +0200 Subject: util: properly handle the root dir in PATH_FOREACH_PREFIX Also add PATH_FOREACH_PREFIX_MORE which includes the specified dir itself in the iteration --- src/shared/path-util.h | 9 ++++++++- src/test/test-path-util.c | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/shared/path-util.h b/src/shared/path-util.h index 03f2cf273c..0a42de7e27 100644 --- a/src/shared/path-util.h +++ b/src/shared/path-util.h @@ -52,5 +52,12 @@ int path_is_os_tree(const char *path); int find_binary(const char *name, char **filename); +/* Iterates through the path prefixes of the specified path, going up + * the tree, to root. Also returns "" (and not "/"!) for the root + * directory. Excludes the specified directory itself */ #define PATH_FOREACH_PREFIX(prefix, path) \ - for (char *_slash = strrchr(path_kill_slashes(strcpy(prefix, path)), '/'); _slash && !(*_slash = 0); _slash = strrchr((prefix), '/')) + for (char *_slash = ({ path_kill_slashes(strcpy(prefix, path)); streq(prefix, "/") ? NULL : strrchr(prefix, '/'); }); _slash && !(*_slash = 0); _slash = strrchr((prefix), '/')) + +/* Same as PATH_FOREACH_PREFIX but also includes the specified path itself */ +#define PATH_FOREACH_PREFIX_MORE(prefix, path) \ + for (char *_slash = ({ path_kill_slashes(strcpy(prefix, path)); if (streq(prefix, "/")) prefix[0] = 0; strrchr(prefix, 0); }); _slash && !(*_slash = 0); _slash = strrchr((prefix), '/')) diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c index e303e488e2..ed3b315a61 100644 --- a/src/test/test-path-util.c +++ b/src/test/test-path-util.c @@ -107,29 +107,55 @@ static void test_find_binary(void) { } static void test_prefixes(void) { - static const char* values[] = { "/a/b/c", "/a/b", "/a", "", NULL}; - unsigned i = 0; + static const char* values[] = { "/a/b/c/d", "/a/b/c", "/a/b", "/a", "", NULL}; + unsigned i; char s[PATH_MAX]; + bool b; - PATH_FOREACH_PREFIX(s, "/a/b/c/d") { + i = 0; + PATH_FOREACH_PREFIX_MORE(s, "/a/b/c/d") { log_error("---%s---", s); assert_se(streq(s, values[i++])); } + assert_se(values[i] == NULL); + i = 1; + PATH_FOREACH_PREFIX(s, "/a/b/c/d") { + log_error("---%s---", s); + assert_se(streq(s, values[i++])); + } assert_se(values[i] == NULL); i = 0; - PATH_FOREACH_PREFIX(s, "////a////b////c///d///////") + PATH_FOREACH_PREFIX_MORE(s, "////a////b////c///d///////") assert_se(streq(s, values[i++])); + assert_se(values[i] == NULL); + i = 1; + PATH_FOREACH_PREFIX(s, "////a////b////c///d///////") + assert_se(streq(s, values[i++])); assert_se(values[i] == NULL); PATH_FOREACH_PREFIX(s, "////") + assert_not_reached("Wut?"); + + b = false; + PATH_FOREACH_PREFIX_MORE(s, "////") { + assert_se(!b); assert_se(streq(s, "")); + b = true; + } + assert_se(b); PATH_FOREACH_PREFIX(s, "") assert_not_reached("wut?"); + b = false; + PATH_FOREACH_PREFIX_MORE(s, "") { + assert(!b); + assert(streq(s, "")); + b = true; + } } int main(void) { -- cgit v1.2.1 From 6270c1bd8f83e9985458c63688f452be7626766f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 26 Sep 2013 20:03:20 +0200 Subject: unit-name: when escaping a path consider the empty path identical to the root dir --- src/shared/unit-name.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/unit-name.c b/src/shared/unit-name.c index 8f6c28e86a..bc8094d112 100644 --- a/src/shared/unit-name.c +++ b/src/shared/unit-name.c @@ -301,7 +301,7 @@ char *unit_name_path_escape(const char *f) { path_kill_slashes(p); - if (streq(p, "/")) { + if (streq(p, "/") || streq(p, "")) { free(p); return strdup("-"); } -- cgit v1.2.1 From a57f7e2c828b852eb32fd810dcea041bb2975501 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 26 Sep 2013 20:14:24 +0200 Subject: core: rework how we match mount units against each other Previously to automatically create dependencies between mount units we matched every mount unit agains all others resulting in O(n^2) complexity. On setups with large amounts of mount units this might make things slow. This change replaces the matching code to use a hashtable that is keyed by a path prefix, and points to a set of units that require that path to be around. When a new mount unit is installed it is hence sufficient to simply look up this set of units via its own file system paths to know which units to order after itself. This patch also changes all unit types to only create automatic mount dependencies via the RequiresMountsFor= logic, and this is exposed to the outside to make things more transparent. With this change we still have some O(n) complexities in place when handling mounts, but that's currently unavoidable due to kernel APIs, and still substantially better than O(n^2) as before. https://bugs.freedesktop.org/show_bug.cgi?id=69740 --- src/core/automount.c | 33 +---- src/core/automount.h | 2 - src/core/load-fragment-gperf.gperf.m4 | 2 +- src/core/load-fragment.c | 47 ++++--- src/core/manager.c | 44 +++++- src/core/manager.h | 12 +- src/core/mount.c | 255 +++++++++------------------------- src/core/path.c | 32 +---- src/core/path.h | 4 - src/core/socket.c | 49 ++----- src/core/socket.h | 4 - src/core/swap.c | 40 +----- src/core/swap.h | 2 - src/core/unit.c | 162 +++++++++++++++++---- src/core/unit.h | 6 +- src/shared/socket-util.c | 8 +- src/shared/socket-util.h | 2 +- 17 files changed, 309 insertions(+), 395 deletions(-) diff --git a/src/core/automount.c b/src/core/automount.c index 67623929c9..d1379e0913 100644 --- a/src/core/automount.c +++ b/src/core/automount.c @@ -117,42 +117,17 @@ static void automount_done(Unit *u) { a->tokens = NULL; } -int automount_add_one_mount_link(Automount *a, Mount *m) { +static int automount_add_mount_links(Automount *a) { + _cleanup_free_ char *parent = NULL; int r; assert(a); - assert(m); - - if (UNIT(a)->load_state != UNIT_LOADED || - UNIT(m)->load_state != UNIT_LOADED) - return 0; - - if (!path_startswith(a->where, m->where)) - return 0; - if (path_equal(a->where, m->where)) - return 0; - - r = unit_add_two_dependencies(UNIT(a), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true); + r = path_get_parent(a->where, &parent); if (r < 0) return r; - return 0; -} - -static int automount_add_mount_links(Automount *a) { - Unit *other; - int r; - - assert(a); - - LIST_FOREACH(units_by_type, other, UNIT(a)->manager->units_by_type[UNIT_MOUNT]) { - r = automount_add_one_mount_link(a, MOUNT(other)); - if (r < 0) - return r; - } - - return 0; + return unit_require_mounts_for(UNIT(a), parent); } static int automount_add_default_dependencies(Automount *a) { diff --git a/src/core/automount.h b/src/core/automount.h index 0c6b8a72e9..a7a25d34e0 100644 --- a/src/core/automount.h +++ b/src/core/automount.h @@ -62,8 +62,6 @@ extern const UnitVTable automount_vtable; int automount_send_ready(Automount *a, int status); -int automount_add_one_mount_link(Automount *a, Mount *m); - const char* automount_state_to_string(AutomountState i) _const_; AutomountState automount_state_from_string(const char *s) _pure_; diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index 25bd3aae47..31fb7bcd3f 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -116,7 +116,7 @@ Unit.PropagateReloadTo, config_parse_unit_deps, UNIT_PROPAG Unit.ReloadPropagatedFrom, config_parse_unit_deps, UNIT_RELOAD_PROPAGATED_FROM, 0 Unit.PropagateReloadFrom, config_parse_unit_deps, UNIT_RELOAD_PROPAGATED_FROM, 0 Unit.PartOf, config_parse_unit_deps, UNIT_PART_OF, 0 -Unit.RequiresMountsFor, config_parse_unit_requires_mounts_for, 0, offsetof(Unit, requires_mounts_for) +Unit.RequiresMountsFor, config_parse_unit_requires_mounts_for, 0, 0 Unit.StopWhenUnneeded, config_parse_bool, 0, offsetof(Unit, stop_when_unneeded) Unit.RefuseManualStart, config_parse_bool, 0, offsetof(Unit, refuse_manual_start) Unit.RefuseManualStop, config_parse_bool, 0, offsetof(Unit, refuse_manual_stop) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 74454abe49..70ea13aa80 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -1773,33 +1773,48 @@ int config_parse_unit_condition_null(const char *unit, DEFINE_CONFIG_PARSE_ENUM(config_parse_notify_access, notify_access, NotifyAccess, "Failed to parse notify access specifier"); DEFINE_CONFIG_PARSE_ENUM(config_parse_start_limit_action, start_limit_action, StartLimitAction, "Failed to parse start limit action specifier"); -int config_parse_unit_requires_mounts_for(const char *unit, - const char *filename, - unsigned line, - const char *section, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { +int config_parse_unit_requires_mounts_for( + const char *unit, + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { Unit *u = userdata; + char *state; + size_t l; + char *w; int r; - bool empty_before; assert(filename); assert(lvalue); assert(rvalue); assert(data); - empty_before = !u->requires_mounts_for; + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + _cleanup_free_ char *n; + + n = strndup(w, l); + if (!n) + return log_oom(); - r = config_parse_path_strv(unit, filename, line, section, lvalue, ltype, - rvalue, data, userdata); + if (!utf8_is_valid(n)) { + log_syntax(unit, LOG_ERR, filename, line, EINVAL, + "Path is not UTF-8 clean, ignoring assignment: %s", rvalue); + continue; + } - /* Make it easy to find units with requires_mounts set */ - if (empty_before && u->requires_mounts_for) - LIST_PREPEND(Unit, has_requires_mounts_for, u->manager->has_requires_mounts_for, u); + r = unit_require_mounts_for(u, n); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to add required mount for, ignoring: %s", rvalue); + continue; + } + } return r; } diff --git a/src/core/manager.c b/src/core/manager.c index f70ff03033..bc57e4a1fd 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -770,6 +770,9 @@ void manager_free(Manager *m) { for (i = 0; i < RLIMIT_NLIMITS; i++) free(m->rlimit[i]); + assert(hashmap_isempty(m->units_requiring_mounts_for)); + hashmap_free(m->units_requiring_mounts_for); + free(m); } @@ -782,9 +785,11 @@ int manager_enumerate(Manager *m) { /* Let's ask every type to load all units from disk/kernel * that it might know */ for (c = 0; c < _UNIT_TYPE_MAX; c++) - if (unit_vtable[c]->enumerate) - if ((q = unit_vtable[c]->enumerate(m)) < 0) + if (unit_vtable[c]->enumerate) { + q = unit_vtable[c]->enumerate(m); + if (q < 0) r = q; + } manager_dispatch_load_queue(m); return r; @@ -2764,6 +2769,41 @@ void manager_status_printf(Manager *m, bool ephemeral, const char *status, const va_end(ap); } +int manager_get_unit_by_path(Manager *m, const char *path, const char *suffix, Unit **_found) { + _cleanup_free_ char *p = NULL; + Unit *found; + + assert(m); + assert(path); + assert(suffix); + assert(_found); + + p = unit_name_from_path(path, suffix); + if (!p) + return -ENOMEM; + + found = manager_get_unit(m, p); + if (!found) { + *_found = NULL; + return 0; + } + + *_found = found; + return 1; +} + +Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path) { + char p[strlen(path)+1]; + + assert(m); + assert(path); + + strcpy(p, path); + path_kill_slashes(p); + + return hashmap_get(m->units_requiring_mounts_for, streq(p, "/") ? "" : p); +} + void watch_init(Watch *w) { assert(w); diff --git a/src/core/manager.h b/src/core/manager.h index 3969553e3e..a3049b5e5b 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -103,9 +103,6 @@ struct Manager { * type we maintain a per type linked list */ LIST_HEAD(Unit, units_by_type[_UNIT_TYPE_MAX]); - /* To optimize iteration of units that have requires_mounts_for set */ - LIST_HEAD(Unit, has_requires_mounts_for); - /* Units that need to be loaded */ LIST_HEAD(Unit, load_queue); /* this is actually more a stack than a queue, but uh. */ @@ -251,6 +248,11 @@ struct Manager { char *switch_root; char *switch_root_init; + + /* This maps all possible path prefixes to the units needing + * them. It's a hashmap with a path string as key and a Set as + * value where Unit objects are contained. */ + Hashmap *units_requiring_mounts_for; }; int manager_new(SystemdRunningAs running_as, bool reexecuting, Manager **m); @@ -263,6 +265,8 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds); Job *manager_get_job(Manager *m, uint32_t id); Unit *manager_get_unit(Manager *m, const char *name); +int manager_get_unit_by_path(Manager *m, const char *path, const char *suffix, Unit **_found); + int manager_get_job_from_dbus_path(Manager *m, const char *s, Job **_j); int manager_load_unit_prepare(Manager *m, const char *name, const char *path, DBusError *e, Unit **_ret); @@ -316,4 +320,6 @@ void manager_recheck_journal(Manager *m); void manager_set_show_status(Manager *m, bool b); void manager_status_printf(Manager *m, bool ephemeral, const char *status, const char *format, ...) _printf_attr_(4,5); +Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path); + void watch_init(Watch *w); diff --git a/src/core/mount.c b/src/core/mount.c index 78c5c1e6d6..3d46557fb1 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -157,138 +157,58 @@ _pure_ static MountParameters* get_mount_parameters(Mount *m) { } static int mount_add_mount_links(Mount *m) { - Unit *other; - int r; + _cleanup_free_ char *parent = NULL; MountParameters *pm; - - assert(m); - - pm = get_mount_parameters_fragment(m); - - /* Adds in links to other mount points that might lie below or - * above us in the hierarchy */ - - LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_MOUNT]) { - Mount *n = MOUNT(other); - MountParameters *pn; - - if (n == m) - continue; - - if (UNIT(n)->load_state != UNIT_LOADED) - continue; - - pn = get_mount_parameters_fragment(n); - - if (path_startswith(m->where, n->where)) { - - if ((r = unit_add_dependency(UNIT(m), UNIT_AFTER, UNIT(n), true)) < 0) - return r; - - if (pn) - if ((r = unit_add_dependency(UNIT(m), UNIT_REQUIRES, UNIT(n), true)) < 0) - return r; - - } else if (path_startswith(n->where, m->where)) { - - if ((r = unit_add_dependency(UNIT(n), UNIT_AFTER, UNIT(m), true)) < 0) - return r; - - if (pm) - if ((r = unit_add_dependency(UNIT(n), UNIT_REQUIRES, UNIT(m), true)) < 0) - return r; - - } else if (pm && pm->what && path_startswith(pm->what, n->where)) { - - if ((r = unit_add_dependency(UNIT(m), UNIT_AFTER, UNIT(n), true)) < 0) - return r; - - if ((r = unit_add_dependency(UNIT(m), UNIT_REQUIRES, UNIT(n), true)) < 0) - return r; - - } else if (pn && pn->what && path_startswith(pn->what, m->where)) { - - if ((r = unit_add_dependency(UNIT(n), UNIT_AFTER, UNIT(m), true)) < 0) - return r; - - if ((r = unit_add_dependency(UNIT(n), UNIT_REQUIRES, UNIT(m), true)) < 0) - return r; - } - } - - return 0; -} - -static int mount_add_swap_links(Mount *m) { Unit *other; + Iterator i; + Set *s; int r; assert(m); - LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_SWAP]) { - r = swap_add_one_mount_link(SWAP(other), m); + if (!path_equal(m->where, "/")) { + /* Adds in links to other mount points that might lie further + * up in the hierarchy */ + r = path_get_parent(m->where, &parent); if (r < 0) return r; - } - return 0; -} - -static int mount_add_path_links(Mount *m) { - Unit *other; - int r; - - assert(m); - - LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_PATH]) { - r = path_add_one_mount_link(PATH(other), m); + r = unit_require_mounts_for(UNIT(m), parent); if (r < 0) return r; } - return 0; -} - -static int mount_add_automount_links(Mount *m) { - Unit *other; - int r; - - assert(m); - - LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_AUTOMOUNT]) { - r = automount_add_one_mount_link(AUTOMOUNT(other), m); + /* Adds in links to other mount points that might be needed + * for the source path (if this is a bind mount) to be + * available. */ + pm = get_mount_parameters_fragment(m); + if (pm && path_is_absolute(pm->what)) { + r = unit_require_mounts_for(UNIT(m), pm->what); if (r < 0) return r; } - return 0; -} + /* Adds in links to other units that use this path or paths + * further down in the hierarchy */ + s = manager_get_units_requiring_mounts_for(UNIT(m)->manager, m->where); + SET_FOREACH(other, s, i) { -static int mount_add_socket_links(Mount *m) { - Unit *other; - int r; + if (other->load_state != UNIT_LOADED) + continue; - assert(m); + if (other == UNIT(m)) + continue; - LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_SOCKET]) { - r = socket_add_one_mount_link(SOCKET(other), m); + r = unit_add_dependency(other, UNIT_AFTER, UNIT(m), true); if (r < 0) return r; - } - return 0; -} - -static int mount_add_requires_mounts_links(Mount *m) { - Unit *other; - int r; - - assert(m); - - LIST_FOREACH(has_requires_mounts_for, other, UNIT(m)->manager->has_requires_mounts_for) { - r = unit_add_one_mount_link(other, m); - if (r < 0) - return r; + if (UNIT(m)->fragment_path) { + /* If we have fragment configuration, then make this dependency required */ + r = unit_add_dependency(other, UNIT_REQUIRES, UNIT(m), true); + if (r < 0) + return r; + } } return 0; @@ -567,8 +487,9 @@ static int mount_fix_timeouts(Mount *m) { } static int mount_verify(Mount *m) { + _cleanup_free_ char *e = NULL; bool b; - char *e; + assert(m); if (UNIT(m)->load_state != UNIT_LOADED) @@ -577,12 +498,11 @@ static int mount_verify(Mount *m) { if (!m->from_fragment && !m->from_proc_self_mountinfo) return -ENOENT; - if (!(e = unit_name_from_path(m->where, ".mount"))) + e = unit_name_from_path(m->where, ".mount"); + if (!e) return -ENOMEM; b = unit_has_name(UNIT(m), e); - free(e); - if (!b) { log_error_unit(UNIT(m)->id, "%s's Where setting doesn't match unit name. Refusing.", @@ -646,26 +566,6 @@ static int mount_add_extras(Mount *m) { if (r < 0) return r; - r = mount_add_socket_links(m); - if (r < 0) - return r; - - r = mount_add_swap_links(m); - if (r < 0) - return r; - - r = mount_add_path_links(m); - if (r < 0) - return r; - - r = mount_add_requires_mounts_links(m); - if (r < 0) - return r; - - r = mount_add_automount_links(m); - if (r < 0) - return r; - r = mount_add_quota_links(m); if (r < 0) return r; @@ -1650,79 +1550,56 @@ fail: static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) { int r = 0; unsigned i; - char *device, *path, *options, *options2, *fstype, *d, *p, *o; assert(m); rewind(m->proc_self_mountinfo); for (i = 1;; i++) { + _cleanup_free_ char *device = NULL, *path = NULL, *options = NULL, *options2 = NULL, *fstype = NULL, *d = NULL, *p = NULL, *o = NULL; int k; - device = path = options = options2 = fstype = d = p = o = NULL; - - if ((k = fscanf(m->proc_self_mountinfo, - "%*s " /* (1) mount id */ - "%*s " /* (2) parent id */ - "%*s " /* (3) major:minor */ - "%*s " /* (4) root */ - "%ms " /* (5) mount point */ - "%ms" /* (6) mount options */ - "%*[^-]" /* (7) optional fields */ - "- " /* (8) separator */ - "%ms " /* (9) file system type */ - "%ms" /* (10) mount source */ - "%ms" /* (11) mount options 2 */ - "%*[^\n]", /* some rubbish at the end */ - &path, - &options, - &fstype, - &device, - &options2)) != 5) { - - if (k == EOF) - break; - + k = fscanf(m->proc_self_mountinfo, + "%*s " /* (1) mount id */ + "%*s " /* (2) parent id */ + "%*s " /* (3) major:minor */ + "%*s " /* (4) root */ + "%ms " /* (5) mount point */ + "%ms" /* (6) mount options */ + "%*[^-]" /* (7) optional fields */ + "- " /* (8) separator */ + "%ms " /* (9) file system type */ + "%ms" /* (10) mount source */ + "%ms" /* (11) mount options 2 */ + "%*[^\n]", /* some rubbish at the end */ + &path, + &options, + &fstype, + &device, + &options2); + + if (k == EOF) + break; + + if (k != 5) { log_warning("Failed to parse /proc/self/mountinfo:%u.", i); - goto clean_up; + continue; } o = strjoin(options, ",", options2, NULL); - if (!o) { - r = -ENOMEM; - goto finish; - } + if (!o) + return log_oom(); - if (!(d = cunescape(device)) || - !(p = cunescape(path))) { - r = -ENOMEM; - goto finish; - } + d = cunescape(device); + p = cunescape(path); + if (!d || !p) + return log_oom(); - if ((k = mount_add_one(m, d, p, o, fstype, 0, set_flags)) < 0) + k = mount_add_one(m, d, p, o, fstype, 0, set_flags); + if (k < 0) r = k; - -clean_up: - free(device); - free(path); - free(options); - free(options2); - free(fstype); - free(d); - free(p); - free(o); } -finish: - free(device); - free(path); - free(options); - free(options2); - free(fstype); - free(d); - free(p); - free(o); - return r; } diff --git a/src/core/path.c b/src/core/path.c index 8a09deb4ff..99e2fedf29 100644 --- a/src/core/path.c +++ b/src/core/path.c @@ -241,10 +241,6 @@ static bool path_spec_check_good(PathSpec *s, bool initial) { return good; } -static bool path_spec_startswith(PathSpec *s, const char *what) { - return path_startswith(s->path, what); -} - static void path_spec_mkdir(PathSpec *s, mode_t mode) { int r; @@ -301,38 +297,14 @@ static void path_done(Unit *u) { path_free_specs(p); } -int path_add_one_mount_link(Path *p, Mount *m) { +static int path_add_mount_links(Path *p) { PathSpec *s; int r; assert(p); - assert(m); - - if (UNIT(p)->load_state != UNIT_LOADED || - UNIT(m)->load_state != UNIT_LOADED) - return 0; LIST_FOREACH(spec, s, p->specs) { - if (!path_spec_startswith(s, m->where)) - continue; - - r = unit_add_two_dependencies(UNIT(p), UNIT_AFTER, UNIT_REQUIRES, - UNIT(m), true); - if (r < 0) - return r; - } - - return 0; -} - -static int path_add_mount_links(Path *p) { - Unit *other; - int r; - - assert(p); - - LIST_FOREACH(units_by_type, other, UNIT(p)->manager->units_by_type[UNIT_MOUNT]) { - r = path_add_one_mount_link(p, MOUNT(other)); + r = unit_require_mounts_for(UNIT(p), s->path); if (r < 0) return r; } diff --git a/src/core/path.h b/src/core/path.h index 6adab5897d..dec3df7035 100644 --- a/src/core/path.h +++ b/src/core/path.h @@ -90,10 +90,6 @@ struct Path { PathResult result; }; -/* Called from the mount code figure out if a mount is a dependency of - * any of the paths of this path object */ -int path_add_one_mount_link(Path *p, Mount *m); - void path_free_specs(Path *p); extern const UnitVTable path_vtable; diff --git a/src/core/socket.c b/src/core/socket.c index 190b36c3ca..6c0ac1a898 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -258,53 +258,24 @@ static int socket_verify(Socket *s) { return 0; } -static bool socket_needs_mount(Socket *s, const char *prefix) { +static int socket_add_mount_links(Socket *s) { SocketPort *p; - - assert(s); - - LIST_FOREACH(port, p, s->ports) { - - if (p->type == SOCKET_SOCKET) { - if (socket_address_needs_mount(&p->address, prefix)) - return true; - } else if (p->type == SOCKET_FIFO || p->type == SOCKET_SPECIAL) { - if (path_startswith(p->path, prefix)) - return true; - } - } - - return false; -} - -int socket_add_one_mount_link(Socket *s, Mount *m) { int r; assert(s); - assert(m); - if (UNIT(s)->load_state != UNIT_LOADED || - UNIT(m)->load_state != UNIT_LOADED) - return 0; - - if (!socket_needs_mount(s, m->where)) - return 0; - - r = unit_add_two_dependencies(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true); - if (r < 0) - return r; - - return 0; -} + LIST_FOREACH(port, p, s->ports) { + const char *path = NULL; -static int socket_add_mount_links(Socket *s) { - Unit *other; - int r; + if (p->type == SOCKET_SOCKET) + path = socket_address_get_path(&p->address); + else if (p->type == SOCKET_FIFO || p->type == SOCKET_SPECIAL) + path = p->path; - assert(s); + if (!path) + continue; - LIST_FOREACH(units_by_type, other, UNIT(s)->manager->units_by_type[UNIT_MOUNT]) { - r = socket_add_one_mount_link(s, MOUNT(other)); + r = unit_require_mounts_for(UNIT(s), path); if (r < 0) return r; } diff --git a/src/core/socket.h b/src/core/socket.h index 57333226f5..3d7eadc9fe 100644 --- a/src/core/socket.h +++ b/src/core/socket.h @@ -156,10 +156,6 @@ struct Socket { /* Called from the service code when collecting fds */ int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds); -/* Called from the mount code figure out if a mount is a dependency of - * any of the sockets of this socket */ -int socket_add_one_mount_link(Socket *s, Mount *m); - /* Called from the service code when a per-connection service ended */ void socket_connection_unref(Socket *s); diff --git a/src/core/swap.c b/src/core/swap.c index dc6731ab30..a68ab7cdf8 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -137,42 +137,6 @@ static void swap_done(Unit *u) { unit_unwatch_timer(u, &s->timer_watch); } -int swap_add_one_mount_link(Swap *s, Mount *m) { - int r; - - assert(s); - assert(m); - - if (UNIT(s)->load_state != UNIT_LOADED || - UNIT(m)->load_state != UNIT_LOADED) - return 0; - - if (is_device_path(s->what)) - return 0; - - if (!path_startswith(s->what, m->where)) - return 0; - - r = unit_add_two_dependencies(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true); - if (r < 0) - return r; - - return 0; -} - -static int swap_add_mount_links(Swap *s) { - Unit *other; - int r; - - assert(s); - - LIST_FOREACH(units_by_type, other, UNIT(s)->manager->units_by_type[UNIT_MOUNT]) - if ((r = swap_add_one_mount_link(s, MOUNT(other))) < 0) - return r; - - return 0; -} - static int swap_add_device_links(Swap *s) { SwapParameters *p; @@ -300,11 +264,11 @@ static int swap_load(Unit *u) { if ((r = unit_set_description(u, s->what)) < 0) return r; - r = swap_add_device_links(s); + r = unit_require_mounts_for(UNIT(s), s->what); if (r < 0) return r; - r = swap_add_mount_links(s); + r = swap_add_device_links(s); if (r < 0) return r; diff --git a/src/core/swap.h b/src/core/swap.h index 7e48c0ea3b..dd89535895 100644 --- a/src/core/swap.h +++ b/src/core/swap.h @@ -107,8 +107,6 @@ struct Swap { extern const UnitVTable swap_vtable; -int swap_add_one_mount_link(Swap *s, Mount *m); - int swap_dispatch_reload(Manager *m); int swap_fd_event(Manager *m, int events); diff --git a/src/core/unit.c b/src/core/unit.c index ab313b9b91..4b9771076a 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -374,6 +374,34 @@ static void unit_remove_transient(Unit *u) { } } +static void unit_free_requires_mounts_for(Unit *u) { + char **j; + + STRV_FOREACH(j, u->requires_mounts_for) { + char s[strlen(*j) + 1]; + + PATH_FOREACH_PREFIX_MORE(s, *j) { + char *y; + Set *x; + + x = hashmap_get2(u->manager->units_requiring_mounts_for, s, (void**) &y); + if (!x) + continue; + + set_remove(x, u); + + if (set_isempty(x)) { + hashmap_remove(u->manager->units_requiring_mounts_for, y); + free(y); + set_free(x); + } + } + } + + strv_free(u->requires_mounts_for); + u->requires_mounts_for = NULL; +} + void unit_free(Unit *u) { UnitDependency d; Iterator i; @@ -390,6 +418,8 @@ void unit_free(Unit *u) { if (UNIT_VTABLE(u)->done) UNIT_VTABLE(u)->done(u); + unit_free_requires_mounts_for(u); + SET_FOREACH(t, u->names, i) hashmap_remove_value(u->manager->units, t, u); @@ -408,11 +438,6 @@ void unit_free(Unit *u) { for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) bidi_set_free(u, u->dependencies[d]); - if (u->requires_mounts_for) { - LIST_REMOVE(Unit, has_requires_mounts_for, u->manager->has_requires_mounts_for, u); - strv_free(u->requires_mounts_for); - } - if (u->type != _UNIT_TYPE_INVALID) LIST_REMOVE(Unit, units_by_type, u->manager->units_by_type[u->type], u); @@ -2659,40 +2684,39 @@ void unit_ref_unset(UnitRef *ref) { ref->unit = NULL; } -int unit_add_one_mount_link(Unit *u, Mount *m) { +int unit_add_mount_links(Unit *u) { char **i; + int r; assert(u); - assert(m); - - if (u->load_state != UNIT_LOADED || - UNIT(m)->load_state != UNIT_LOADED) - return 0; STRV_FOREACH(i, u->requires_mounts_for) { + char prefix[strlen(*i) + 1]; - if (UNIT(m) == u) - continue; + PATH_FOREACH_PREFIX_MORE(prefix, *i) { + Unit *m; - if (!path_startswith(*i, m->where)) - continue; - - return unit_add_two_dependencies(u, UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true); - } - - return 0; -} + r = manager_get_unit_by_path(u->manager, prefix, ".mount", &m); + if (r < 0) + return r; + if (r == 0) + continue; + if (m == u) + continue; -int unit_add_mount_links(Unit *u) { - Unit *other; - int r; + if (m->load_state != UNIT_LOADED) + continue; - assert(u); + r = unit_add_dependency(u, UNIT_AFTER, m, true); + if (r < 0) + return r; - LIST_FOREACH(units_by_type, other, u->manager->units_by_type[UNIT_MOUNT]) { - r = unit_add_one_mount_link(u, MOUNT(other)); - if (r < 0) - return r; + if (m->fragment_path) { + r = unit_add_dependency(u, UNIT_REQUIRES, m, true); + if (r < 0) + return r; + } + } } return 0; @@ -3012,6 +3036,86 @@ int unit_kill_context( return wait_for_exit; } +int unit_require_mounts_for(Unit *u, const char *path) { + char prefix[strlen(path) + 1], *p; + int r; + + assert(u); + assert(path); + + /* Registers a unit for requiring a certain path and all its + * prefixes. We keep a simple array of these paths in the + * unit, since its usually short. However, we build a prefix + * table for all possible prefixes so that new appearing mount + * units can easily determine which units to make themselves a + * dependency of. */ + + p = strdup(path); + if (!p) + return -ENOMEM; + + path_kill_slashes(p); + + if (!path_is_absolute(p)) { + free(p); + return -EINVAL; + } + + if (!path_is_safe(p)) { + free(p); + return -EPERM; + } + + if (strv_contains(u->requires_mounts_for, p)) { + free(p); + return 0; + } + + r = strv_push(&u->requires_mounts_for, p); + if (r < 0) { + free(p); + return r; + } + + PATH_FOREACH_PREFIX_MORE(prefix, p) { + Set *x; + + x = hashmap_get(u->manager->units_requiring_mounts_for, prefix); + if (!x) { + char *q; + + if (!u->manager->units_requiring_mounts_for) { + u->manager->units_requiring_mounts_for = hashmap_new(string_hash_func, string_compare_func); + if (!u->manager->units_requiring_mounts_for) + return -ENOMEM; + } + + q = strdup(prefix); + if (!q) + return -ENOMEM; + + x = set_new(NULL, NULL); + if (!x) { + free(q); + return -ENOMEM; + } + + r = hashmap_put(u->manager->units_requiring_mounts_for, q, x); + if (r < 0) { + free(q); + set_free(x); + return r; + } + } + + r = set_put(x, u); + if (r < 0) + return r; + } + + return 0; +} + static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = { [UNIT_ACTIVE] = "active", [UNIT_RELOADING] = "reloading", diff --git a/src/core/unit.h b/src/core/unit.h index 0caea183c4..6dd750f8c2 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -173,7 +173,6 @@ struct Unit { /* Counterparts in the cgroup filesystem */ char *cgroup_path; - bool cgroup_realized; CGroupControllerMask cgroup_mask; UnitRef slice; @@ -255,6 +254,8 @@ struct Unit { bool no_gc:1; bool in_audit:1; + + bool cgroup_realized:1; }; struct UnitStatusMessageFormats { @@ -589,7 +590,6 @@ void unit_ref_unset(UnitRef *ref); #define UNIT_DEREF(ref) ((ref).unit) #define UNIT_ISSET(ref) (!!(ref).unit) -int unit_add_one_mount_link(Unit *u, Mount *m); int unit_add_mount_links(Unit *u); int unit_exec_context_defaults(Unit *u, ExecContext *c); @@ -609,6 +609,8 @@ int unit_kill_context(Unit *u, KillContext *c, bool sigkill, pid_t main_pid, pid int unit_make_transient(Unit *u); +int unit_require_mounts_for(Unit *u, const char *path); + const char *unit_active_state_to_string(UnitActiveState i) _const_; UnitActiveState unit_active_state_from_string(const char *s) _pure_; diff --git a/src/shared/socket-util.c b/src/shared/socket-util.c index c583d3dfea..9224208244 100644 --- a/src/shared/socket-util.c +++ b/src/shared/socket-util.c @@ -486,16 +486,16 @@ bool socket_address_is_netlink(const SocketAddress *a, const char *s) { return socket_address_equal(a, &b); } -bool socket_address_needs_mount(const SocketAddress *a, const char *prefix) { +const char* socket_address_get_path(const SocketAddress *a) { assert(a); if (socket_address_family(a) != AF_UNIX) - return false; + return NULL; if (a->sockaddr.un.sun_path[0] == 0) - return false; + return NULL; - return path_startswith(a->sockaddr.un.sun_path, prefix); + return a->sockaddr.un.sun_path; } bool socket_ipv6_is_supported(void) { diff --git a/src/shared/socket-util.h b/src/shared/socket-util.h index 7829a337fc..e0b85adf9f 100644 --- a/src/shared/socket-util.h +++ b/src/shared/socket-util.h @@ -92,7 +92,7 @@ int make_socket_fd(const char* address, int flags); bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) _pure_; -bool socket_address_needs_mount(const SocketAddress *a, const char *prefix); +const char* socket_address_get_path(const SocketAddress *a); const char* socket_address_bind_ipv6_only_to_string(SocketAddressBindIPv6Only b) _const_; SocketAddressBindIPv6Only socket_address_bind_ipv6_only_from_string(const char *s) _pure_; -- cgit v1.2.1 From 299404a19f26aa4f203042d8285ee0b7afa5bf40 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 26 Sep 2013 20:31:37 +0200 Subject: logind: if a user is sitting in front of the computer and can shutdown the machine anyway he should also be able to reboot it --- src/login/org.freedesktop.login1.policy.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/login/org.freedesktop.login1.policy.in b/src/login/org.freedesktop.login1.policy.in index 0c551d4f9b..b96d32d526 100644 --- a/src/login/org.freedesktop.login1.policy.in +++ b/src/login/org.freedesktop.login1.policy.in @@ -190,7 +190,7 @@ auth_admin_keep auth_admin_keep - auth_admin_keep + yes org.freedesktop.login1.reboot -- cgit v1.2.1 From 90dc8c2ea2cebf2dd195abe4768205a831fd32cb Mon Sep 17 00:00:00 2001 From: Mike Gilbert Date: Thu, 26 Sep 2013 20:39:41 +0200 Subject: main: set umask before creating any files This avoids a problem when we inherit a non-zero umask from the initramfs. This would cause /run/systemd to be created with the wrong mode. --- src/core/main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index 72bd542af0..0629d142ff 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1265,6 +1265,10 @@ int main(int argc, char *argv[]) { log_show_color(isatty(STDERR_FILENO) > 0); + /* Disable the umask logic */ + if (getpid() == 1) + umask(0); + if (getpid() == 1 && detect_container(NULL) <= 0) { /* Running outside of a container as PID 1 */ @@ -1438,14 +1442,10 @@ int main(int argc, char *argv[]) { if (serialization) assert_se(fdset_remove(fds, fileno(serialization)) >= 0); - if (arg_running_as == SYSTEMD_SYSTEM) { + if (arg_running_as == SYSTEMD_SYSTEM) /* Become a session leader if we aren't one yet. */ setsid(); - /* Disable the umask logic */ - umask(0); - } - /* Move out of the way, so that we won't block unmounts */ assert_se(chdir("/") == 0); -- cgit v1.2.1 From c68ba912c347a79885bb0e863034bdb3a8ae057e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 26 Sep 2013 21:32:47 +0200 Subject: logind: never consider a closing session relevant for PK checks https://bugzilla.redhat.com/show_bug.cgi?id=1010215 --- src/login/logind-dbus.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index e76381b322..bb85c7d4af 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -957,6 +957,7 @@ static int have_multiple_sessions( * count, and non-login sessions do not count either. */ HASHMAP_FOREACH(session, m->sessions, i) if (session->class == SESSION_USER && + !session->closing && session->user->uid != uid) return true; -- cgit v1.2.1 From 7ac807320a7416463d7ff3ef6ede574863a601c5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 26 Sep 2013 22:49:44 +0200 Subject: core: drop some out-of-date references to cgroup settings --- man/systemd-cgtop.xml | 36 +++++++++++++++--------------------- man/systemd-system.conf.xml | 27 +-------------------------- man/systemd.unit.xml | 5 ++++- src/core/dbus-manager.c | 27 --------------------------- src/core/system.conf | 3 +-- src/core/user.conf | 1 - 6 files changed, 21 insertions(+), 78 deletions(-) diff --git a/man/systemd-cgtop.xml b/man/systemd-cgtop.xml index 0e9e5e611a..51549c4ac2 100644 --- a/man/systemd-cgtop.xml +++ b/man/systemd-cgtop.xml @@ -73,30 +73,23 @@ only accounted for control groups in the cpuacct hierarchy, memory usage only for those in memory and disk - I/O usage for those in - blkio. systemd1 - by default places all services in their own control - group in the cpuacct hierarchy, but - not in memory nor - blkio. If resource monitoring for - these resources is required, it is recommended to add - blkio and memory - to the DefaultControllers= setting - in /etc/systemd/system.conf (see - systemd-system.conf5 - for details). Alternatively, it is possible to enable - resource accounting individually for services, by - making use of the ControlGroup= - option in the unit files (See - systemd.exec5 + I/O usage for those in blkio. If + resource monitoring for these resources is required, + it is recommended to add the + CPUAccounting=1, + MemoryAccounting=1 and + BlockIOAccounting=1 settings in the + unit files in question (See + systemd.cgroup5 for details). To emphasize this: unless - blkio and memory - are enabled for the services in question with either - of the options suggested above no resource accounting - will be available for system services and the data shown - by systemd-cgtop will be + CPUAccounting=1, + MemoryAccounting=1 and + BlockIOAccounting=1 are enabled for + the services in question no resource accounting will + be available for system services and the data shown by + systemd-cgtop will be incomplete. @@ -281,6 +274,7 @@ systemd1, systemctl1, systemd-cgls1, + systemd.cgroup5, top1 diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml index c52e59096a..e8cf8a9cb2 100644 --- a/man/systemd-system.conf.xml +++ b/man/systemd-system.conf.xml @@ -104,32 +104,7 @@ - DefaultControllers=cpu - - Configures in which - control group hierarchies to create - per-service cgroups automatically, in - addition to the - name=systemd named - hierarchy. Defaults to - cpu. Takes a - space-separated list of controller - names. Pass the empty string to ensure - that systemd does not touch any - hierarchies but its own. - - Note that the default value of - 'cpu' will make realtime scheduling - unavailable to system services. See - My - Service Can't Get Realtime! - for more - information. - - - - JoinControllers=cpu,cpuacct,cpuset net_cls,netprio + JoinControllers=cpu,cpuacct net_cls,netprio Configures controllers that shall be mounted in a single diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index d61426a845..5c8b8e8868 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -1241,7 +1241,10 @@ %R Parent directory of the control group path where units are placed. - For system instances this usually resolves to /, except in containers, where this resolves to the container's root directory. This specifier is particularly useful in the ControlGroup= setting (see systemd.exec5). + For system instances this usually + resolves to /, except in + containers, where this resolves to the + container's root directory. %t diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 75e2e45b66..676a07ffa5 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -103,32 +103,6 @@ " \n" \ " \n" \ " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " " \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " " \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ " \n" \ " \n" \ " \n" \ @@ -316,7 +290,6 @@ " \n" \ " \n" \ " \n" \ - " \n" \ " \n" \ " \n" \ " \n" \ diff --git a/src/core/system.conf b/src/core/system.conf index f2817bc507..7b03c8782b 100644 --- a/src/core/system.conf +++ b/src/core/system.conf @@ -17,10 +17,9 @@ #ShowStatus=yes #CrashChVT=1 #CPUAffinity=1 2 -#DefaultControllers=cpu #DefaultStandardOutput=journal #DefaultStandardError=inherit -#JoinControllers=cpu,cpuacct,cpuset net_cls,net_prio +#JoinControllers=cpu,cpuacct net_cls,net_prio #RuntimeWatchdogSec=0 #ShutdownWatchdogSec=10min #CapabilityBoundingSet= diff --git a/src/core/user.conf b/src/core/user.conf index 4252451eb7..4a0129a984 100644 --- a/src/core/user.conf +++ b/src/core/user.conf @@ -12,6 +12,5 @@ #LogTarget=console #LogColor=yes #LogLocation=no -#DefaultControllers=cpu #DefaultStandardOutput=inherit #DefaultStandardError=inherit -- cgit v1.2.1 From 3fde5f30bda2a70d97f3dc8fa918e42e1c07cc2c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 27 Sep 2013 00:05:07 +0200 Subject: man: drop references to "cgroup" wher appropriate Since cgroups are mostly now an implementation detail of systemd lets deemphasize it a bit in the man pages. This renames systemd.cgroup(5) to systemd.resource-control(5) and uses the term "resource control" rather than "cgroup" where appropriate. This leaves the word "cgroup" in at a couple of places though, like for example systemd-cgtop and systemd-cgls where cgroup stuff is at the core of what is happening. --- Makefile-man.am | 2 +- man/loginctl.xml | 4 +- man/machinectl.xml | 4 +- man/pam_systemd.xml | 2 +- man/systemctl.xml | 14 +- man/systemd-cgls.xml | 6 +- man/systemd-cgtop.xml | 4 +- man/systemd.cgroup.xml | 350 --------------------------------------- man/systemd.exec.xml | 2 +- man/systemd.mount.xml | 6 +- man/systemd.resource-control.xml | 348 ++++++++++++++++++++++++++++++++++++++ man/systemd.scope.xml | 2 +- man/systemd.service.xml | 6 +- man/systemd.slice.xml | 22 +-- man/systemd.socket.xml | 12 +- man/systemd.swap.xml | 6 +- 16 files changed, 394 insertions(+), 396 deletions(-) delete mode 100644 man/systemd.cgroup.xml create mode 100644 man/systemd.resource-control.xml diff --git a/Makefile-man.am b/Makefile-man.am index 1f635956e2..c8a4342396 100644 --- a/Makefile-man.am +++ b/Makefile-man.am @@ -78,7 +78,6 @@ MANPAGES += \ man/systemd-update-utmp.service.8 \ man/systemd.1 \ man/systemd.automount.5 \ - man/systemd.cgroup.5 \ man/systemd.device.5 \ man/systemd.exec.5 \ man/systemd.journal-fields.7 \ @@ -86,6 +85,7 @@ MANPAGES += \ man/systemd.mount.5 \ man/systemd.path.5 \ man/systemd.preset.5 \ + man/systemd.resource-control.5 \ man/systemd.scope.5 \ man/systemd.service.5 \ man/systemd.slice.5 \ diff --git a/man/loginctl.xml b/man/loginctl.xml index ef0dfc06b6..1b54ff7dc3 100644 --- a/man/loginctl.xml +++ b/man/loginctl.xml @@ -117,8 +117,8 @@ - Do not ellipsize cgroup - members. + Do not ellipsize + process tree entries. diff --git a/man/machinectl.xml b/man/machinectl.xml index 5efa3a542a..2ed9f2e8a1 100644 --- a/man/machinectl.xml +++ b/man/machinectl.xml @@ -117,8 +117,8 @@ - Do not ellipsize cgroup - members. + Do not ellipsize + process tree entries. diff --git a/man/pam_systemd.xml b/man/pam_systemd.xml index 951ae207a4..0e25a4ac9f 100644 --- a/man/pam_systemd.xml +++ b/man/pam_systemd.xml @@ -55,7 +55,7 @@ Description pam_systemd registers user - sessions in the systemd login manager + sessions with the systemd login manager systemd-logind.service8, and hence the systemd control group hierarchy. diff --git a/man/systemctl.xml b/man/systemctl.xml index 32bcf03f2f..e789d4b629 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -174,7 +174,7 @@ along with systemd; If not, see . - Do not ellipsize unit names, cgroup members, and + Do not ellipsize unit names, process tree entries, and truncate unit descriptions in the output of list-units and list-jobs. @@ -711,14 +711,14 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service Set the specified unit properties at runtime where this is supported. This allows changing configuration - parameter properties such as resource management controls at + parameter properties such as resource control settings at runtime. Not all properties may be changed at runtime, but - many resource management settings (primarily those in - systemd.cgroup5) + many resource control settings (primarily those in + systemd.resource-control5) may. The changes are applied instantly, and stored on disk for future boots, unless is - passed, in which case the settings only apply until the next - reboot. The syntax of the property assignment follows + passed, in which case the settings only apply until the + next reboot. The syntax of the property assignment follows closely the syntax of assignments in unit files. Example: systemctl set-property foobar.service CPUShares=777 @@ -1290,7 +1290,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service journalctl1, loginctl1, systemd.unit5, - systemd.cgroup5, + systemd.resource-management5, systemd.special7, wall1, systemd.preset5 diff --git a/man/systemd-cgls.xml b/man/systemd-cgls.xml index fcaf89413e..432706bcbc 100644 --- a/man/systemd-cgls.xml +++ b/man/systemd-cgls.xml @@ -116,8 +116,8 @@ - Do not ellipsize cgroup - members. + Do not ellipsize + process tree members. @@ -132,7 +132,7 @@ - Limit cgroups shown to + Limit control groups shown to the part corresponding to the container MACHINE. diff --git a/man/systemd-cgtop.xml b/man/systemd-cgtop.xml index 51549c4ac2..7faedfbfdb 100644 --- a/man/systemd-cgtop.xml +++ b/man/systemd-cgtop.xml @@ -80,7 +80,7 @@ MemoryAccounting=1 and BlockIOAccounting=1 settings in the unit files in question (See - systemd.cgroup5 + systemd.resource-control5 for details). To emphasize this: unless @@ -274,7 +274,7 @@ systemd1, systemctl1, systemd-cgls1, - systemd.cgroup5, + systemd.resource-control5, top1 diff --git a/man/systemd.cgroup.xml b/man/systemd.cgroup.xml deleted file mode 100644 index ac5896233c..0000000000 --- a/man/systemd.cgroup.xml +++ /dev/null @@ -1,350 +0,0 @@ - - - - - - - - - systemd.cgroup - systemd - - - - Developer - Lennart - Poettering - lennart@poettering.net - - - - - - systemd.cgroup - 5 - - - - systemd.cgroup - Control Group configuration unit settings - - - - - slice.slice, - scope.scope, - service.service, - socket.socket, - mount.mount, - swap.swap - - - - - Description - - Unit configuration files for services, slices, scopes, - sockets, mount points, and swap devices share a subset of - configuration options which configure the control group settings - for spawned processes. - - Control Groups is a concept for organizing processes in a - hierarch tree of named groups for the purpose of resource - management. - - This man page lists the configuration options shared by - those six unit types. See - systemd.unit5 - for the common options of all unit configuration files, and - systemd.slice5, - systemd.scope5, - systemd.service5, - systemd.socket5, - systemd.mount5, - and - systemd.swap5 - for more information on the specific unit configuration files. The - execution-specific configuration options are configured in the - [Slice], [Scope], [Service], [Socket], [Mount], or [Swap] - sections, depending on the unit type. - - - - Options - - Units of the types listed above can have settings - for cgroup configuration: - - - - - CPUAccounting= - - - Turn on CPU usage accounting for this unit. Takes a - boolean argument. Note that turning on CPU accounting for - one unit might also implicitly turn it on for all units - contained in the same slice and for all its parent slices and - the units contained therein. - - - - - CPUShares=weight - - - Assign the specified overall CPU time share weight to - the processes executed. Takes an integer value. This - controls the cpu.shares control group - attribute, which defaults to 1024. For details about this - control group attribute, see sched-design-CFS.txt. - - Implies CPUAccounting=true. - - - - - MemoryAccounting= - - - Turn on process and kernel memory accounting for this - unit. Takes a boolean argument. Note that turning on memory - accounting for one unit might also implicitly turn it on for - all units contained in the same slice and for all its parent - slices and the units contained therein. - - - - - MemoryLimit=bytes - - - Specify the limit on maximum memory usage of the - executed processes. The limit specifies how much process and - kernel memory can be used by tasks in this unit. Takes a - memory size in bytes. If the value is suffixed with K, M, G - or T, the specified memory size is parsed as Kilobytes, - Megabytes, Gigabytes, or Terabytes (with the base 1024), - respectively. This controls the - memory.limit_in_bytes control group - attribute. For details about this control group attribute, - see memory.txt. - - Implies MemoryAccounting=true. - - - - - BlockIOAccounting= - - - Turn on Block IO accounting for this unit. Takes a - boolean argument. Note that turning on block IO accounting - for one unit might also implicitly turn it on for all units - contained in the same slice and all for its parent slices and - the units contained therein. - - - - - BlockIOWeight=weight - - Set the default - overall block IO weight for the - executed processes. Takes a single - weight value (between 10 and 1000) to - set the default block IO weight. This - controls the - blkio.weight - control group attribute, which - defaults to 1000. For details about - this control group attribute, see - blkio-controller.txt. - - Implies - BlockIOAccounting=true. - - - - - BlockIODeviceWeight=device weight - - - Set the per-device overall block IO weight for the - executed processes. Takes a space-separated pair of a file - path and a weight value to specify the device specific - weight value, between 10 and 1000. (Example: "/dev/sda - 500"). The file path may be specified as path to a block - device node or as any other file in which case the backing - block device of the file system of the file is - determined. This controls the - blkio.weight_device control group - attribute, which defaults to 1000. Use this option multiple - times to set weights for multiple devices. For details about - this control group attribute, see blkio-controller.txt. - - Implies - BlockIOAccounting=true. - - - - - BlockIOReadBandwidth=device bytes - BlockIOWriteBandwidth=device bytes - - - Set the per-device overall block IO bandwidth limit - for the executed processes. Takes a space-separated pair of - a file path and a bandwidth value (in bytes per second) to - specify the device specific bandwidth. The file path may be - a path to a block device node, or as any other file in which - case the backing block device of the file system of the file - is used. If the bandwidth is suffixed with K, M, G, or T, - the specified bandwidth is parsed as Kilobytes, Megabytes, - Gigabytes, or Terabytes, respectively (Example: - "/dev/disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0 5M"). This - controls the blkio.read_bps_device and - blkio.write_bps_device control group - attributes. Use this option multiple times to set bandwidth - limits for multiple devices. For details about these control - group attributes, see - blkio-controller.txt. - - - Implies - BlockIOAccounting=true. - - - - - DeviceAllow= - - - Control access to specific device nodes by the - executed processes. Takes two space-separated strings: a - device node path (such as /dev/null) - followed by a combination of r, - w, m to control - reading, writing, - or creation of the specific device node by the unit - (mknod), respectively. This controls - the devices.allow and - devices.deny control group - attributes. For details about these control group attributes, - see devices.txt. - - - - - DevicePolicy=auto|closed|strict - - - - Control the policy for allowing device access: - - - - - - means to only allow types of access that are - explicitly specified. - - - - - - - in addition, allows access to standard pseudo - devices including - /dev/null, - /dev/zero, - /dev/full, - /dev/random, and - /dev/urandom. - - - - - - - - - in addition, allows access to all devices if no - explicit DeviceAllow= is present. - This is the default. - - - - - - - - - Slice= - - - The name of the slice unit to place the unit - in. Defaults to system.slice for all - non-instantiated units of all unit types (except for slice - units themselves see below). Instance units are by default - placed in a subslice of system.slice - that is named after the template name. - - This option may be used to arrange systemd units in a - hierarchy of slices each of which might have resource - settings applied. - - For units of type slice, the only accepted value for - this setting is the parent slice. Since the name of a slice - unit implies the parent slice, it is hence redundant to ever - set this parameter directly for slice units. - - - - - - - - See Also - - systemd1, - systemd.unit5, - systemd.service5, - systemd.slice5, - systemd.scope5, - systemd.socket5, - systemd.mount5, - systemd.swap5, - systemd.directives7, - systemd.special7, - The documentation for control groups and specific controllers in the Linux kernel: - cgroups.txt, - cpuacct.txt, - memory.txt, - blkio-controller.txt. - - - diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index ba4e808ddd..f50161f30c 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -1108,7 +1108,7 @@ systemd.swap5, systemd.mount5, systemd.kill5, - systemd.cgroup5, + systemd.resource-control5, systemd.directives7, exec3 diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml index e5b5c3c7c3..48af1caace 100644 --- a/man/systemd.mount.xml +++ b/man/systemd.mount.xml @@ -76,8 +76,8 @@ systemd.kill5, which define the way the processes are terminated, and in - systemd.cgroup5, - which configure control group settings for the + systemd.resource-control5, + which configure resource control settings for the processes of the service. Note that the User= and Group= options are not particularly useful for mount units specifying a Type= option or @@ -302,7 +302,7 @@ systemd.unit5, systemd.exec5, systemd.kill5, - systemd.cgroup5, + systemd.resource-control5, systemd.service5, systemd.device5, proc5, diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml new file mode 100644 index 0000000000..de017a72fd --- /dev/null +++ b/man/systemd.resource-control.xml @@ -0,0 +1,348 @@ + + + + + + + + + systemd.resource-control + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.resource-control + 5 + + + + systemd.resource-control + Resource control unit settings + + + + + slice.slice, + scope.scope, + service.service, + socket.socket, + mount.mount, + swap.swap + + + + + Description + + Unit configuration files for services, slices, scopes, + sockets, mount points, and swap devices share a subset of + configuration options for resource control of spawned + processes. Internally, this relies on the the Control Groups + kernel concept for organizing processes in a hierarchial tree of + named groups for the purpose of resource management. + + This man page lists the configuration options shared by + those six unit types. See + systemd.unit5 + for the common options of all unit configuration files, and + systemd.slice5, + systemd.scope5, + systemd.service5, + systemd.socket5, + systemd.mount5, + and + systemd.swap5 + for more information on the specific unit configuration files. The + resource control configuration options are configured in the + [Slice], [Scope], [Service], [Socket], [Mount], or [Swap] + sections, depending on the unit type. + + + + Options + + Units of the types listed above can have settings + for resource control configuration: + + + + + CPUAccounting= + + + Turn on CPU usage accounting for this unit. Takes a + boolean argument. Note that turning on CPU accounting for + one unit might also implicitly turn it on for all units + contained in the same slice and for all its parent slices and + the units contained therein. + + + + + CPUShares=weight + + + Assign the specified overall CPU time share weight to + the processes executed. Takes an integer value. This + controls the cpu.shares control group + attribute, which defaults to 1024. For details about this + control group attribute, see sched-design-CFS.txt. + + Implies CPUAccounting=true. + + + + + MemoryAccounting= + + + Turn on process and kernel memory accounting for this + unit. Takes a boolean argument. Note that turning on memory + accounting for one unit might also implicitly turn it on for + all units contained in the same slice and for all its parent + slices and the units contained therein. + + + + + MemoryLimit=bytes + + + Specify the limit on maximum memory usage of the + executed processes. The limit specifies how much process and + kernel memory can be used by tasks in this unit. Takes a + memory size in bytes. If the value is suffixed with K, M, G + or T, the specified memory size is parsed as Kilobytes, + Megabytes, Gigabytes, or Terabytes (with the base 1024), + respectively. This controls the + memory.limit_in_bytes control group + attribute. For details about this control group attribute, + see memory.txt. + + Implies MemoryAccounting=true. + + + + + BlockIOAccounting= + + + Turn on Block IO accounting for this unit. Takes a + boolean argument. Note that turning on block IO accounting + for one unit might also implicitly turn it on for all units + contained in the same slice and all for its parent slices and + the units contained therein. + + + + + BlockIOWeight=weight + + Set the default + overall block IO weight for the + executed processes. Takes a single + weight value (between 10 and 1000) to + set the default block IO weight. This + controls the + blkio.weight + control group attribute, which + defaults to 1000. For details about + this control group attribute, see + blkio-controller.txt. + + Implies + BlockIOAccounting=true. + + + + + BlockIODeviceWeight=device weight + + + Set the per-device overall block IO weight for the + executed processes. Takes a space-separated pair of a file + path and a weight value to specify the device specific + weight value, between 10 and 1000. (Example: "/dev/sda + 500"). The file path may be specified as path to a block + device node or as any other file in which case the backing + block device of the file system of the file is + determined. This controls the + blkio.weight_device control group + attribute, which defaults to 1000. Use this option multiple + times to set weights for multiple devices. For details about + this control group attribute, see blkio-controller.txt. + + Implies + BlockIOAccounting=true. + + + + + BlockIOReadBandwidth=device bytes + BlockIOWriteBandwidth=device bytes + + + Set the per-device overall block IO bandwidth limit + for the executed processes. Takes a space-separated pair of + a file path and a bandwidth value (in bytes per second) to + specify the device specific bandwidth. The file path may be + a path to a block device node, or as any other file in which + case the backing block device of the file system of the file + is used. If the bandwidth is suffixed with K, M, G, or T, + the specified bandwidth is parsed as Kilobytes, Megabytes, + Gigabytes, or Terabytes, respectively (Example: + "/dev/disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0 5M"). This + controls the blkio.read_bps_device and + blkio.write_bps_device control group + attributes. Use this option multiple times to set bandwidth + limits for multiple devices. For details about these control + group attributes, see + blkio-controller.txt. + + + Implies + BlockIOAccounting=true. + + + + + DeviceAllow= + + + Control access to specific device nodes by the + executed processes. Takes two space-separated strings: a + device node path (such as /dev/null) + followed by a combination of r, + w, m to control + reading, writing, + or creation of the specific device node by the unit + (mknod), respectively. This controls + the devices.allow and + devices.deny control group + attributes. For details about these control group attributes, + see devices.txt. + + + + + DevicePolicy=auto|closed|strict + + + + Control the policy for allowing device access: + + + + + + means to only allow types of access that are + explicitly specified. + + + + + + + in addition, allows access to standard pseudo + devices including + /dev/null, + /dev/zero, + /dev/full, + /dev/random, and + /dev/urandom. + + + + + + + + + in addition, allows access to all devices if no + explicit DeviceAllow= is present. + This is the default. + + + + + + + + + Slice= + + + The name of the slice unit to place the unit + in. Defaults to system.slice for all + non-instantiated units of all unit types (except for slice + units themselves see below). Instance units are by default + placed in a subslice of system.slice + that is named after the template name. + + This option may be used to arrange systemd units in a + hierarchy of slices each of which might have resource + settings applied. + + For units of type slice, the only accepted value for + this setting is the parent slice. Since the name of a slice + unit implies the parent slice, it is hence redundant to ever + set this parameter directly for slice units. + + + + + + + + See Also + + systemd1, + systemd.unit5, + systemd.service5, + systemd.slice5, + systemd.scope5, + systemd.socket5, + systemd.mount5, + systemd.swap5, + systemd.directives7, + systemd.special7, + The documentation for control groups and specific controllers in the Linux kernel: + cgroups.txt, + cpuacct.txt, + memory.txt, + blkio-controller.txt. + + + diff --git a/man/systemd.scope.xml b/man/systemd.scope.xml index e8fa1aed59..9813e0a696 100644 --- a/man/systemd.scope.xml +++ b/man/systemd.scope.xml @@ -86,7 +86,7 @@ along with systemd; If not, see . systemd1, systemd-run1, systemd.unit5, - systemd.cgroup5, + systemd.resource-control5, systemd.service5, systemd.directives7. diff --git a/man/systemd.service.xml b/man/systemd.service.xml index c06e14efc2..5e1ddf7188 100644 --- a/man/systemd.service.xml +++ b/man/systemd.service.xml @@ -76,8 +76,8 @@ systemd.kill5, which define the way the processes of the service are terminated, and in - systemd.cgroup5, - which configure control group settings for the + systemd.resource-control5, + which configure resource control settings for the processes of the service. Unless DefaultDependencies= @@ -1007,7 +1007,7 @@ systemctl8, systemd.unit5, systemd.exec5, - systemd.cgroup5, + systemd.resource-control5, systemd.kill5, systemd.directives7 diff --git a/man/systemd.slice.xml b/man/systemd.slice.xml index b7b0622d3c..4d27ddf890 100644 --- a/man/systemd.slice.xml +++ b/man/systemd.slice.xml @@ -58,14 +58,14 @@ along with systemd; If not, see . .slice encodes information about a slice which is a concept for hierarchially managing resources of a group of processes. This management is performed by creating a node in the - control group tree. Units that manage processes (primarilly scope - and service units) may be assigned to a specific slice. For each - slice, certain resource limits may the be set that apply to all - processes of all units contained in that slice. Slices are - organized hierarchially in a tree. The name of the slice encodes - the location in the tree. The name consists of a dash-separated - series of names, which describes the path to the slice from the - root slice. The root slice is named, + Linux Control Group (cgroup) tree. Units that manage processes + (primarilly scope and service units) may be assigned to a specific + slice. For each slice, certain resource limits may the be set that + apply to all processes of all units contained in that + slice. Slices are organized hierarchially in a tree. The name of + the slice encodes the location in the tree. The name consists of a + dash-separated series of names, which describes the path to the + slice from the root slice. The root slice is named, -.slice. Example: foo-bar.slice is a slice that is located within foo.slice, which in turn is located in @@ -89,9 +89,9 @@ along with systemd; If not, see . files. The common configuration items are configured in the generic [Unit] and [Install] sections. The slice specific configuration options are configured in - the [Slice] section. Currently, only generic cgroup settings + the [Slice] section. Currently, only generic resource control settings as described in - systemd.cgroup7 are allowed. + systemd.resource-control7 are allowed. Unless DefaultDependencies=false @@ -110,7 +110,7 @@ along with systemd; If not, see . systemd1, systemd.unit5, - systemd.cgroup5, + systemd.resource-control5, systemd.service5, systemd.scope5, systemd.special7, diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml index 419a38caa7..8c88d9f8aa 100644 --- a/man/systemd.socket.xml +++ b/man/systemd.socket.xml @@ -78,11 +78,11 @@ commands are executed in, and in systemd.kill5, - which define the way the processes are - terminated, and in - systemd.cgroup5, - which configure control group settings for the - processes of the service. + which define the way the processes are terminated, and + in + systemd.resource-control5, + which configure resource control settings for the + processes of the socket. For each socket file a matching service file (see @@ -712,7 +712,7 @@ systemd.unit5, systemd.exec5, systemd.kill5, - systemd.cgroup5, + systemd.resource-control5, systemd.service5, systemd.directives7 diff --git a/man/systemd.swap.xml b/man/systemd.swap.xml index 18ef5b0f53..813ae6c942 100644 --- a/man/systemd.swap.xml +++ b/man/systemd.swap.xml @@ -76,8 +76,8 @@ systemd.kill5, which define the way the processes are terminated, and in - systemd.cgroup5, - which configure control group settings for the + systemd.resource-control5, + which configure resource control settings for the processes of the service. Swap units must be named after the devices @@ -206,7 +206,7 @@ systemd.unit5, systemd.exec5, systemd.kill5, - systemd.cgroup5, + systemd.resource-control5, systemd.device5, systemd.mount5, swapon8, -- cgit v1.2.1 From 68372da693edb69a0881698ba9d0893bfddc9435 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 27 Sep 2013 00:11:54 +0200 Subject: systemctl: make sure set-property mangles unit names --- src/systemctl/systemctl.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 8b9183dcb3..eede616e50 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -3829,7 +3829,8 @@ static int append_assignment(DBusMessageIter *iter, const char *assignment) { static int set_property(DBusConnection *bus, char **args) { - _cleanup_free_ DBusMessage *m = NULL, *reply = NULL; + _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL; + _cleanup_free_ char *n = NULL; DBusMessageIter iter, sub; dbus_bool_t runtime; DBusError error; @@ -3850,7 +3851,11 @@ static int set_property(DBusConnection *bus, char **args) { runtime = arg_runtime; - if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &args[1]) || + n = unit_name_mangle(args[1]); + if (!n) + return log_oom(); + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &n) || !dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &runtime) || !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(sv)", &sub)) return log_oom(); -- cgit v1.2.1 From a38d1d28d1b506b4dd36f952cad7013b0f627798 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 27 Sep 2013 00:35:36 +0200 Subject: dbus: fix introspection for TimerSlackNSec --- src/core/dbus-execute.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/dbus-execute.h b/src/core/dbus-execute.h index 5a6a559c99..79bf30838a 100644 --- a/src/core/dbus-execute.h +++ b/src/core/dbus-execute.h @@ -63,7 +63,7 @@ " \n" \ " \n" \ " \n" \ - " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ -- cgit v1.2.1 From d43de69002fdfbee351f655065e4fc2914b9fcd3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 27 Sep 2013 02:02:21 +0200 Subject: swap: properly expose timeout property on the bus --- src/core/dbus-swap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/dbus-swap.c b/src/core/dbus-swap.c index 86fcf16eaf..06edfdcde4 100644 --- a/src/core/dbus-swap.c +++ b/src/core/dbus-swap.c @@ -95,6 +95,7 @@ static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_swap_append_swap_result, swap_result, static const BusProperty bus_swap_properties[] = { { "What", bus_property_append_string, "s", offsetof(Swap, what), true }, { "Priority", bus_swap_append_priority, "i", 0 }, + { "TimeoutUSec",bus_property_append_usec, "t", offsetof(Swap, timeout_usec)}, BUS_EXEC_COMMAND_PROPERTY("ExecActivate", offsetof(Swap, exec_command[SWAP_EXEC_ACTIVATE]), false), BUS_EXEC_COMMAND_PROPERTY("ExecDeactivate", offsetof(Swap, exec_command[SWAP_EXEC_DEACTIVATE]), false), { "ControlPID", bus_property_append_pid, "u", offsetof(Swap, control_pid) }, -- cgit v1.2.1 From 278d4bcfe981d058380cf388e5ac09d761438820 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 27 Sep 2013 02:59:50 +0200 Subject: Update TODO --- TODO | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/TODO b/TODO index 474532164b..25b7587277 100644 --- a/TODO +++ b/TODO @@ -48,11 +48,9 @@ CGroup Rework Completion: * handle jointly mounted controllers correctly -* make BlockIODeviceWeight=, BlockIODeviceBandwidth= runtime settable - * introduce high-level settings for RT budget, swappiness -* wiki: document new bus APIs of PID 1 (transient units, Reloading signal) +* wiki: guidelines how to make use of new cgroup apis Features: @@ -63,15 +61,8 @@ Features: * When using "systemd status" on a slice unit also show all messages matching _SYSTEMD_SLICE= not just _SYSTEMD_UNIT= -* always set memory.user_hierarchy for all cgroups we create - * After coming back from hibernation reset hibernation swap partition -* mounts: do not test each mount unit against each other mount unit to - determine prefixes. Instead generated list of all prefixes and - interate through that to bring down complexity from O(n^2) to O(n) - when loading units - * If we try to find a unit via a dangling symlink generate a clean error. Currently we just ignore it and read the unit from the search path anyway. @@ -231,8 +222,6 @@ Features: * logind: add Suspend() bus calls which take timestamps to fix double suspend issues when somebody hits suspend and closes laptop quickly. -* we need dynamic units - * cgtop: make cgtop useful in a container * test/: @@ -348,7 +337,6 @@ Features: - logind: wakelock/opportunistic suspend support - Add pretty name for seats in logind - logind: allow showing logout dialog from system? - - logind: spawn user@..service on login - logind: non-local X11 server handling - logind: add equivalent to sd_pid_get_owner_uid() to the D-Bus API - pam: when leaving a session explicitly exclude the ReleaseSession() caller process from the killing spree @@ -357,8 +345,6 @@ Features: * exec: when deinitializating a tty device fix the perms and group, too, not only when initializing. Set access mode/gid to 0620/tty. -* DeviceAllow/DeviceDeny: disallow everything by default, but whitelist /dev/zero, /dev/null and friends - * service: watchdog logic: for testing purposes allow ping, but do not require pong * journal: @@ -533,8 +519,6 @@ Features: * Query Paul Moore about relabelling socket fds while they are open -* system.conf should have controls for cgroups - * allow writing multiple conditions in unit files on one line * explore multiple service instances per listening socket idea @@ -625,10 +609,6 @@ Features: * support crash reporting operation modes (https://live.gnome.org/GnomeOS/Design/Whiteboards/ProblemReporting) -* clean up session cgroups that remain after logout (think sshd), but eventually run empty - -* when an instanced service exits, remove its parent cgroup too if possible. - * default to actual 32bit PIDs, via /proc/sys/kernel/pid_max * be able to specify a forced restart of service A where service B depends on, in case B -- cgit v1.2.1 From 8a7935a23bfec14beb73e004beb01273254cf789 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 27 Sep 2013 07:58:57 +0200 Subject: Do not use unitialized variable and remove duplicated line --- src/core/load-fragment.c | 4 ++-- src/journal/journald-server.c | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 70ea13aa80..44920d6449 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -1788,7 +1788,6 @@ int config_parse_unit_requires_mounts_for( char *state; size_t l; char *w; - int r; assert(filename); assert(lvalue); @@ -1796,6 +1795,7 @@ int config_parse_unit_requires_mounts_for( assert(data); FOREACH_WORD_QUOTED(w, l, rvalue, state) { + int r; _cleanup_free_ char *n; n = strndup(w, l); @@ -1816,7 +1816,7 @@ int config_parse_unit_requires_mounts_for( } } - return r; + return 0; } int config_parse_documentation(const char *unit, diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index e888480284..4f47eb1c11 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -1270,7 +1270,6 @@ int process_event(Server *s, struct epoll_event *ev) { if ((ev->events|EPOLLIN|EPOLLHUP) != (EPOLLIN|EPOLLHUP)) { log_error("Got invalid event from epoll for %s: %"PRIx32, "stdout stream", ev->events); - log_error("Got invalid event from epoll."); return -EIO; } -- cgit v1.2.1 From f2ec0646aba7c6703a6c79603957e805b74c3bef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 27 Sep 2013 08:24:00 +0200 Subject: build-sys: restore detection of sphinx --- configure.ac | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configure.ac b/configure.ac index af0dbbeeee..45526f4a54 100644 --- a/configure.ac +++ b/configure.ac @@ -202,6 +202,7 @@ AS_IF([test "x$have_python" = "xyes" -a "x$enable_python_devel" != "xno"], [ [have_python_devel=no])]) AS_IF([test "x$have_python_devel" = xno -a "x$enable_python_devel" = xyes], [AC_MSG_ERROR([*** python-devel support requested but libraries not found])]) + AC_PATH_PROGS(SPHINX_BUILD, sphinx-build-${PYTHON_VERSION} sphinx-build) ]) AM_CONDITIONAL([HAVE_PYTHON_DEVEL], [test "$have_python_devel" = "yes"]) @@ -1068,6 +1069,7 @@ AC_MSG_RESULT([ SysV rc?.d directories: ${SYSTEM_SYSVRCND_PATH} Build Python: ${PYTHON} Installation Python: ${PYTHON_BINARY} + sphinx binary: ${SPHINX_BUILD} firmware path: ${FIRMWARE_PATH} PAM modules dir: ${with_pamlibdir} PAM configuration dir: ${with_pamconfdir} -- cgit v1.2.1 From 8b179a830a789746cce0be6671e2de235e3b0ea9 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Wed, 25 Sep 2013 22:58:00 +0200 Subject: kernel-install: avoid using 'cp --preserve' Force 0644 and root:root instead, to avoid problems with fat filesystems. --- src/kernel-install/90-loaderentry.install | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/kernel-install/90-loaderentry.install b/src/kernel-install/90-loaderentry.install index 6b91d1cccb..a6a8abc2bd 100644 --- a/src/kernel-install/90-loaderentry.install +++ b/src/kernel-install/90-loaderentry.install @@ -59,7 +59,9 @@ if ! [[ ${BOOT_OPTIONS[*]} ]]; then exit 1 fi -cp --preserve "$KERNEL_IMAGE" "$BOOT_DIR_ABS/linux" || { +cp "$KERNEL_IMAGE" "$BOOT_DIR_ABS/linux" && + chown root:root "$BOOT_DIR_ABS/linux" && + chmod 0644 "$BOOT_DIR_ABS/linux" || { echo "Could not copy '$KERNEL_IMAGE to '$BOOT_DIR_ABS/linux'." >&2 exit 1 } -- cgit v1.2.1 From edcfd89ad0996686488c02ee0062d913fa0ba483 Mon Sep 17 00:00:00 2001 From: Michael Scherer Date: Fri, 27 Sep 2013 11:43:28 +0200 Subject: Add a bit more explicit message, to help confused users Seeing http://www.happyassassin.net/2013/09/27/further-sysadmin-adventures-wheres-my-freeipa-badge/ it seems that the default message is a bit confusing for people who never encountered it before, so adding a link to the manpage could help them. --- tmpfiles.d/systemd.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmpfiles.d/systemd.conf b/tmpfiles.d/systemd.conf index c397c71b75..b6304401fe 100644 --- a/tmpfiles.d/systemd.conf +++ b/tmpfiles.d/systemd.conf @@ -22,7 +22,7 @@ d /run/systemd/users 0755 root root - d /run/systemd/machines 0755 root root - d /run/systemd/shutdown 0755 root root - -F /run/nologin 0644 - - - "System is booting up." +F /run/nologin 0644 - - - "System is booting up. See pam_nologin(8)" m /var/log/journal 2755 root systemd-journal - - m /var/log/journal/%m 2755 root systemd-journal - - -- cgit v1.2.1 From 8083d486d0ac8e159b2d1294c8f6be7b11f9cab6 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Sat, 28 Sep 2013 14:51:39 -0400 Subject: kmod-static-nodes: condition execution on modules.devname --- units/kmod-static-nodes.service.in | 1 + 1 file changed, 1 insertion(+) diff --git a/units/kmod-static-nodes.service.in b/units/kmod-static-nodes.service.in index d8a84204a7..ff4017bada 100644 --- a/units/kmod-static-nodes.service.in +++ b/units/kmod-static-nodes.service.in @@ -10,6 +10,7 @@ Description=Create list of required static device nodes for the current kernel DefaultDependencies=no Before=sysinit.target systemd-tmpfiles-setup-dev.service ConditionCapability=CAP_MKNOD +ConditionPathExists=/lib/modules/%v/modules.devname [Service] Type=oneshot -- cgit v1.2.1 From 893fa014de0f73337ff4a4c9c531d6789b72f5bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 29 Sep 2013 14:40:58 +0200 Subject: Fix buffer overrun when enumerating files https://bugs.freedesktop.org/show_bug.cgi?id=69887 Based-on-a-patch-by: Hans Petter Jansson --- src/shared/util.c | 79 +++++++++++++++++----------------------------------- src/test/test-util.c | 10 +++++++ 2 files changed, 36 insertions(+), 53 deletions(-) diff --git a/src/shared/util.c b/src/shared/util.c index 200955376e..fb42d663a6 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -4412,38 +4412,31 @@ int dirent_ensure_type(DIR *d, struct dirent *de) { } int in_search_path(const char *path, char **search) { - char **i, *parent; + char **i; + _cleanup_free_ char *parent = NULL; int r; r = path_get_parent(path, &parent); if (r < 0) return r; - r = 0; - - STRV_FOREACH(i, search) { - if (path_equal(parent, *i)) { - r = 1; - break; - } - } - - free(parent); + STRV_FOREACH(i, search) + if (path_equal(parent, *i)) + return 1; - return r; + return 0; } int get_files_in_directory(const char *path, char ***list) { - DIR *d; - int r = 0; - unsigned n = 0; - char **l = NULL; + _cleanup_closedir_ DIR *d = NULL; + size_t bufsize = 0, n = 0; + _cleanup_strv_free_ char **l = NULL; assert(path); /* Returns all files in a directory in *list, and the number * of files as return value. If list is NULL returns only the - * number */ + * number. */ d = opendir(path); if (!d) @@ -4455,11 +4448,9 @@ int get_files_in_directory(const char *path, char ***list) { int k; k = readdir_r(d, &buf.de, &de); - if (k != 0) { - r = -k; - goto finish; - } - + assert(k >= 0); + if (k > 0) + return -k; if (!de) break; @@ -4469,43 +4460,25 @@ int get_files_in_directory(const char *path, char ***list) { continue; if (list) { - if ((unsigned) r >= n) { - char **t; - - n = MAX(16, 2*r); - t = realloc(l, sizeof(char*) * n); - if (!t) { - r = -ENOMEM; - goto finish; - } - - l = t; - } - - assert((unsigned) r < n); + /* one extra slot is needed for the terminating NULL */ + if (!GREEDY_REALLOC(l, bufsize, n + 2)) + return -ENOMEM; - l[r] = strdup(de->d_name); - if (!l[r]) { - r = -ENOMEM; - goto finish; - } + l[n] = strdup(de->d_name); + if (!l[n]) + return -ENOMEM; - l[++r] = NULL; + l[++n] = NULL; } else - r++; + n++; } -finish: - if (d) - closedir(d); - - if (r >= 0) { - if (list) - *list = l; - } else - strv_free(l); + if (list) { + *list = l; + l = NULL; /* avoid freeing */ + } - return r; + return n; } char *strjoin(const char *x, ...) { diff --git a/src/test/test-util.c b/src/test/test-util.c index ad13d53de3..c5762ede4b 100644 --- a/src/test/test-util.c +++ b/src/test/test-util.c @@ -27,6 +27,7 @@ #include #include "util.h" +#include "strv.h" static void test_streq_ptr(void) { assert_se(streq_ptr(NULL, NULL)); @@ -582,6 +583,14 @@ static void test_fstab_node_to_udev_node(void) { free(n); } +static void test_get_files_in_directory(void) { + _cleanup_strv_free_ char **l = NULL, **t = NULL; + + assert_se(get_files_in_directory("/tmp", &l) >= 0); + assert_se(get_files_in_directory(".", &l) >= 0); + assert_se(get_files_in_directory(".", NULL) >= 0); +} + int main(int argc, char *argv[]) { test_streq_ptr(); test_first_word(); @@ -618,6 +627,7 @@ int main(int argc, char *argv[]) { test_parse_user_at_host(); test_split_pair(); test_fstab_node_to_udev_node(); + test_get_files_in_directory(); return 0; } -- cgit v1.2.1 From 4469ff4adebbed4778e7fe767f0165776c1ba62a Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Sun, 29 Sep 2013 15:37:30 +0400 Subject: set IgnoreOnIsolate=true for systemd-cryptsetup@.service When crypttab contains noauto, cryptsetup service does not have any explicit dependencies. If service is started later manually (directly or via mount dependency) it will be stopped on isolate. mount units already have IgnoreOnIsolate set by default. Set it by default for cryptsetup units as well. --- src/cryptsetup/cryptsetup-generator.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c index 8792e6b1f5..e1798a3e82 100644 --- a/src/cryptsetup/cryptsetup-generator.c +++ b/src/cryptsetup/cryptsetup-generator.c @@ -118,6 +118,7 @@ static int create_disk( "Conflicts=umount.target\n" "DefaultDependencies=no\n" "BindsTo=dev-mapper-%i.device\n" + "IgnoreOnIsolate=true\n" "After=systemd-readahead-collect.service systemd-readahead-replay.service\n", f); -- cgit v1.2.1 From ea021cc3ea7082786e764734bb344eebbd6f2caa Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 30 Sep 2013 18:54:05 +0200 Subject: man: link cgroups api docs from relevant man pages --- man/systemd.resource-control.xml | 5 +++++ man/systemd.scope.xml | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml index de017a72fd..868890590d 100644 --- a/man/systemd.resource-control.xml +++ b/man/systemd.resource-control.xml @@ -83,6 +83,11 @@ along with systemd; If not, see . resource control configuration options are configured in the [Slice], [Scope], [Service], [Socket], [Mount], or [Swap] sections, depending on the unit type. + + See the New + Control Group Interfaces for an introduction how to make + use of resource control APIs from programs. diff --git a/man/systemd.scope.xml b/man/systemd.scope.xml index 9813e0a696..392abbf151 100644 --- a/man/systemd.scope.xml +++ b/man/systemd.scope.xml @@ -69,6 +69,11 @@ along with systemd; If not, see . be used to easily launch a command in a new scope unit from the command line. + See the New + Control Group Interfaces for an introduction how to make + use of scope units from programs. + Unless DefaultDependencies=false is used, scope units will implicitly have dependencies of type Conflicts= and -- cgit v1.2.1 From 3efabbe47f3c10a9585a9fde46351a2bf9665f54 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 30 Sep 2013 18:54:12 +0200 Subject: update TODO --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index 25b7587277..df4813cc46 100644 --- a/TODO +++ b/TODO @@ -54,6 +54,8 @@ CGroup Rework Completion: Features: +* logind should forget about fb devices in favour of going drm only + * move config_parse_path_strv() out of conf-parser.c * libdsystemd-bus should expose utf8 validation calls -- cgit v1.2.1 From ba54bcb822fe1b6ab5c653d63dfdae706a28a128 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 30 Sep 2013 18:56:34 +0200 Subject: man: mention the systemd homepage from systemd(1) --- man/systemd.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/man/systemd.xml b/man/systemd.xml index 97ef768608..fe6e331f25 100644 --- a/man/systemd.xml +++ b/man/systemd.xml @@ -1280,6 +1280,7 @@ See Also + The systemd Homepage, systemd-system.conf5, locale.conf5, systemctl1, -- cgit v1.2.1 From ceadabb102b05b237bfab11e1f742975ee4daeb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Mon, 30 Sep 2013 10:08:09 +0200 Subject: build-sys: link libsystemd-login with libsystemd-label.la MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit libsystemd-login.la uses cg_create() that currently seems to be a part of libsystemd-label.la. However, it doesn't link against that library and it seems that none of the (unconditional) libraries it uses do. In the end, people end up getting «undefined reference to `cg_create'» when trying to build e.g. dbus. --- Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.am b/Makefile.am index 92de1630b4..af4e215538 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3919,6 +3919,7 @@ libsystemd_login_la_LDFLAGS = \ libsystemd_login_la_LIBADD = \ libsystemd-shared.la \ libsystemd-daemon-internal.la \ + libsystemd-label.la \ $(RT_LIBS) libsystemd_login_internal_la_SOURCES = \ -- cgit v1.2.1 From 69ae3ee07ee4dc7592f6d2d5f181b478a772a644 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 30 Sep 2013 23:58:44 +0200 Subject: logs-show.c: show all messages for a slice --- TODO | 3 --- src/shared/logs-show.c | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index df4813cc46..c1f6e5ad62 100644 --- a/TODO +++ b/TODO @@ -60,9 +60,6 @@ Features: * libdsystemd-bus should expose utf8 validation calls -* When using "systemd status" on a slice unit also show all messages - matching _SYSTEMD_SLICE= not just _SYSTEMD_UNIT= - * After coming back from hibernation reset hibernation swap partition * If we try to find a unit via a dangling symlink generate a clean diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index 2dd5025bc3..7bb19b4006 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -1048,6 +1048,16 @@ int add_matches_for_unit(sd_journal *j, const char *unit) { (r = sd_journal_add_match(j, m4, 0)) ); + if (r == 0 && endswith(unit, ".slice")) { + char *m5 = strappend("_SYSTEMD_SLICE=", unit); + + /* Show all messages belonging to a slice */ + (void)( + (r = sd_journal_add_disjunction(j)) || + (r = sd_journal_add_match(j, m5, 0)) + ); + } + return r; } @@ -1087,6 +1097,18 @@ int add_matches_for_user_unit(sd_journal *j, const char *unit, uid_t uid) { (r = sd_journal_add_match(j, muid, 0)) || (r = sd_journal_add_match(j, "_UID=0", 0)) ); + + if (r == 0 && endswith(unit, ".slice")) { + char *m5 = strappend("_SYSTEMD_SLICE=", unit); + + /* Show all messages belonging to a slice */ + (void)( + (r = sd_journal_add_disjunction(j)) || + (r = sd_journal_add_match(j, m5, 0)) || + (r = sd_journal_add_match(j, muid, 0)) + ); + } + return r; } -- cgit v1.2.1 From 6c081276dc11722656906361ac78e415757865e3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 1 Oct 2013 00:06:48 +0200 Subject: main: don't free fds array twice --- src/core/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/main.c b/src/core/main.c index 0629d142ff..fe291f8410 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1567,6 +1567,7 @@ int main(int argc, char *argv[]) { /* This will close all file descriptors that were opened, but * not claimed by any unit. */ fdset_free(fds); + fds = NULL; if (serialization) { fclose(serialization); -- cgit v1.2.1 From bcd8e6d1bd3f434af894faeb400fee0e99445a7f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 1 Oct 2013 00:08:30 +0200 Subject: local: fix memory leak when putting together locale settings Also, we need to use proper strv_env_xyz() calls when putting together the environment array, since otherwise settings won't be properly overriden. And let's get rid of strv_appendf(), is overkill and there was only one user. --- src/core/locale-setup.c | 31 +++++++++++++++++++++++++++---- src/core/manager.c | 4 +++- src/shared/strv.c | 15 --------------- src/shared/strv.h | 1 - 4 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/core/locale-setup.c b/src/core/locale-setup.c index 31374ac644..276deb9dc1 100644 --- a/src/core/locale-setup.c +++ b/src/core/locale-setup.c @@ -29,6 +29,7 @@ #include "virt.h" #include "fileio.h" #include "strv.h" +#include "env-util.h" enum { /* We don't list LC_ALL here on purpose. People should be @@ -69,7 +70,7 @@ static const char * const variable_names[_VARIABLE_MAX] = { }; int locale_setup(char ***environment) { - char **env; + char **add; char *variables[_VARIABLE_MAX] = {}; int r = 0, i; @@ -119,22 +120,44 @@ int locale_setup(char ***environment) { log_warning("Failed to read /etc/locale.conf: %s", strerror(-r)); } + add = NULL; for (i = 0; i < _VARIABLE_MAX; i++) { + char *s; + if (!variables[i]) continue; - env = strv_appendf(*environment, "%s=%s", variable_names[i], variables[i]); - if (!env) { + s = strjoin(variable_names[i], "=", variables[i], NULL); + if (!s) { + r = -ENOMEM; + goto finish; + } + + if (strv_push(&add, s) < 0) { + free(s); + r = -ENOMEM; + goto finish; + } + } + + if (!strv_isempty(add)) { + char **e; + + e = strv_env_merge(2, *environment, add); + if (!e) { r = -ENOMEM; goto finish; } - *environment = env; + strv_free(*environment); + *environment = e; } r = 0; finish: + strv_free(add); + for (i = 0; i < _VARIABLE_MAX; i++) free(variables[i]); diff --git a/src/core/manager.c b/src/core/manager.c index bc57e4a1fd..58dacdc8b5 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -2665,14 +2665,16 @@ void manager_undo_generators(Manager *m) { } int manager_environment_add(Manager *m, char **environment) { - char **e = NULL; assert(m); + e = strv_env_merge(2, m->environment, environment); if (!e) return -ENOMEM; + strv_free(m->environment); m->environment = e; + return 0; } diff --git a/src/shared/strv.c b/src/shared/strv.c index 2df478f30b..adeee282b7 100644 --- a/src/shared/strv.c +++ b/src/shared/strv.c @@ -424,21 +424,6 @@ fail: return NULL; } -char **strv_appendf(char **l, const char *format, ...) { - va_list ap; - _cleanup_free_ char *s = NULL; - int r; - - va_start(ap, format); - r = vasprintf(&s, format, ap); - va_end(ap); - - if (r < 0) - return NULL; - - return strv_append(l, s); -} - int strv_push(char ***l, char *value) { char **c; unsigned n; diff --git a/src/shared/strv.h b/src/shared/strv.h index 4e80ea6d89..d1f2a0ef32 100644 --- a/src/shared/strv.h +++ b/src/shared/strv.h @@ -42,7 +42,6 @@ unsigned strv_length(char * const *l) _pure_; char **strv_merge(char **a, char **b); char **strv_merge_concat(char **a, char **b, const char *suffix); char **strv_append(char **l, const char *s); -char **strv_appendf(char **l, const char *format, ...) _printf_attr_(2, 3); int strv_extend(char ***l, const char *value); int strv_push(char ***l, char *value); -- cgit v1.2.1 From 45fa9e29f8c9759c8f2f4238fed956f695c73dc3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 1 Oct 2013 00:13:18 +0200 Subject: hashmap: size hashmap bucket array dynamically Instead of fixing the hashmap bucket array to 127 entries dynamically size it, starting with a smaller one of 31. As soon as a fill level of 75% is reached, quadruple the size, and so on. This should siginficantly optimize the lookup time in large tables (from O(n) back to O(1)), and save memory on smaller tables (which most are). --- src/shared/hashmap.c | 152 ++++++++++++++++++++++++++++++++++++------------ src/shared/hashmap.h | 1 + src/test/test-hashmap.c | 28 ++++++++- 3 files changed, 143 insertions(+), 38 deletions(-) diff --git a/src/shared/hashmap.c b/src/shared/hashmap.c index 4ea1a0f4cb..633079277d 100644 --- a/src/shared/hashmap.c +++ b/src/shared/hashmap.c @@ -28,7 +28,7 @@ #include "hashmap.h" #include "macro.h" -#define NBUCKETS 127 +#define INITIAL_N_BUCKETS 31 struct hashmap_entry { const void *key; @@ -42,13 +42,13 @@ struct Hashmap { compare_func_t compare_func; struct hashmap_entry *iterate_list_head, *iterate_list_tail; - unsigned n_entries; + + struct hashmap_entry ** buckets; + unsigned n_buckets, n_entries; bool from_pool; }; -#define BY_HASH(h) ((struct hashmap_entry**) ((uint8_t*) (h) + ALIGN(sizeof(Hashmap)))) - struct pool { struct pool *next; unsigned n_tiles; @@ -64,6 +64,11 @@ static void *first_entry_tile = NULL; static void* allocate_tile(struct pool **first_pool, void **first_tile, size_t tile_size) { unsigned i; + /* When a tile is released we add it to the list and simply + * place the next pointer at its offset 0. */ + + assert(tile_size >= sizeof(void*)); + if (*first_tile) { void *r; @@ -173,7 +178,7 @@ Hashmap *hashmap_new(hash_func_t hash_func, compare_func_t compare_func) { b = is_main_thread(); - size = ALIGN(sizeof(Hashmap)) + NBUCKETS * sizeof(struct hashmap_entry*); + size = ALIGN(sizeof(Hashmap)) + INITIAL_N_BUCKETS * sizeof(struct hashmap_entry*); if (b) { h = allocate_tile(&first_hashmap_pool, &first_hashmap_tile, size); @@ -191,23 +196,30 @@ Hashmap *hashmap_new(hash_func_t hash_func, compare_func_t compare_func) { h->hash_func = hash_func ? hash_func : trivial_hash_func; h->compare_func = compare_func ? compare_func : trivial_compare_func; + h->n_buckets = INITIAL_N_BUCKETS; h->n_entries = 0; h->iterate_list_head = h->iterate_list_tail = NULL; + h->buckets = (struct hashmap_entry**) ((uint8_t*) h + ALIGN(sizeof(Hashmap))); + h->from_pool = b; return h; } int hashmap_ensure_allocated(Hashmap **h, hash_func_t hash_func, compare_func_t compare_func) { + Hashmap *q; + assert(h); if (*h) return 0; - if (!(*h = hashmap_new(hash_func, compare_func))) + q = hashmap_new(hash_func, compare_func); + if (!q) return -ENOMEM; + *h = q; return 0; } @@ -216,11 +228,11 @@ static void link_entry(Hashmap *h, struct hashmap_entry *e, unsigned hash) { assert(e); /* Insert into hash table */ - e->bucket_next = BY_HASH(h)[hash]; + e->bucket_next = h->buckets[hash]; e->bucket_previous = NULL; - if (BY_HASH(h)[hash]) - BY_HASH(h)[hash]->bucket_previous = e; - BY_HASH(h)[hash] = e; + if (h->buckets[hash]) + h->buckets[hash]->bucket_previous = e; + h->buckets[hash] = e; /* Insert into iteration list */ e->iterate_previous = h->iterate_list_tail; @@ -260,7 +272,7 @@ static void unlink_entry(Hashmap *h, struct hashmap_entry *e, unsigned hash) { if (e->bucket_previous) e->bucket_previous->bucket_next = e->bucket_next; else - BY_HASH(h)[hash] = e->bucket_next; + h->buckets[hash] = e->bucket_next; assert(h->n_entries >= 1); h->n_entries--; @@ -272,7 +284,7 @@ static void remove_entry(Hashmap *h, struct hashmap_entry *e) { assert(h); assert(e); - hash = h->hash_func(e->key) % NBUCKETS; + hash = h->hash_func(e->key) % h->n_buckets; unlink_entry(h, e, hash); @@ -291,6 +303,9 @@ void hashmap_free(Hashmap*h) { hashmap_clear(h); + if (h->buckets != (struct hashmap_entry**) ((uint8_t*) h + ALIGN(sizeof(Hashmap)))) + free(h->buckets); + if (h->from_pool) deallocate_tile(&first_hashmap_tile, h); else @@ -357,22 +372,72 @@ void hashmap_clear_free_free(Hashmap *h) { static struct hashmap_entry *hash_scan(Hashmap *h, unsigned hash, const void *key) { struct hashmap_entry *e; assert(h); - assert(hash < NBUCKETS); + assert(hash < h->n_buckets); - for (e = BY_HASH(h)[hash]; e; e = e->bucket_next) + for (e = h->buckets[hash]; e; e = e->bucket_next) if (h->compare_func(e->key, key) == 0) return e; return NULL; } +static bool resize_buckets(Hashmap *h) { + unsigned m; + struct hashmap_entry **n, *i; + + assert(h); + + if (_likely_(h->n_entries*4 < h->n_buckets*3)) + return false; + + /* Increase by four */ + m = (h->n_entries+1)*4-1; + + /* If we hit OOM we simply risk packed hashmaps... */ + n = new0(struct hashmap_entry*, m); + if (!n) + return false; + + for (i = h->iterate_list_head; i; i = i->iterate_next) { + unsigned hash, x; + + hash = h->hash_func(i->key); + + /* First, drop from old bucket table */ + if (i->bucket_next) + i->bucket_next->bucket_previous = i->bucket_previous; + + if (i->bucket_previous) + i->bucket_previous->bucket_next = i->bucket_next; + else + h->buckets[hash % h->n_buckets] = i->bucket_next; + + /* Then, add to new backet table */ + x = hash % m; + + i->bucket_next = n[x]; + i->bucket_previous = NULL; + if (n[x]) + n[x]->bucket_previous = i; + n[x] = i; + } + + if (h->buckets != (struct hashmap_entry**) ((uint8_t*) h + ALIGN(sizeof(Hashmap)))) + free(h->buckets); + + h->buckets = n; + h->n_buckets = m; + + return true; +} + int hashmap_put(Hashmap *h, const void *key, void *value) { struct hashmap_entry *e; unsigned hash; assert(h); - hash = h->hash_func(key) % NBUCKETS; + hash = h->hash_func(key) % h->n_buckets; e = hash_scan(h, hash, key); if (e) { if (e->value == value) @@ -380,6 +445,9 @@ int hashmap_put(Hashmap *h, const void *key, void *value) { return -EEXIST; } + if (resize_buckets(h)) + hash = h->hash_func(key) % h->n_buckets; + if (h->from_pool) e = allocate_tile(&first_entry_pool, &first_entry_tile, sizeof(struct hashmap_entry)); else @@ -402,7 +470,7 @@ int hashmap_replace(Hashmap *h, const void *key, void *value) { assert(h); - hash = h->hash_func(key) % NBUCKETS; + hash = h->hash_func(key) % h->n_buckets; e = hash_scan(h, hash, key); if (e) { e->key = key; @@ -419,7 +487,7 @@ int hashmap_update(Hashmap *h, const void *key, void *value) { assert(h); - hash = h->hash_func(key) % NBUCKETS; + hash = h->hash_func(key) % h->n_buckets; e = hash_scan(h, hash, key); if (!e) return -ENOENT; @@ -435,7 +503,7 @@ void* hashmap_get(Hashmap *h, const void *key) { if (!h) return NULL; - hash = h->hash_func(key) % NBUCKETS; + hash = h->hash_func(key) % h->n_buckets; e = hash_scan(h, hash, key); if (!e) return NULL; @@ -450,7 +518,7 @@ void* hashmap_get2(Hashmap *h, const void *key, void **key2) { if (!h) return NULL; - hash = h->hash_func(key) % NBUCKETS; + hash = h->hash_func(key) % h->n_buckets; e = hash_scan(h, hash, key); if (!e) return NULL; @@ -467,7 +535,7 @@ bool hashmap_contains(Hashmap *h, const void *key) { if (!h) return false; - hash = h->hash_func(key) % NBUCKETS; + hash = h->hash_func(key) % h->n_buckets; if (!hash_scan(h, hash, key)) return false; @@ -483,7 +551,7 @@ void* hashmap_remove(Hashmap *h, const void *key) { if (!h) return NULL; - hash = h->hash_func(key) % NBUCKETS; + hash = h->hash_func(key) % h->n_buckets; if (!(e = hash_scan(h, hash, key))) return NULL; @@ -501,11 +569,11 @@ int hashmap_remove_and_put(Hashmap *h, const void *old_key, const void *new_key, if (!h) return -ENOENT; - old_hash = h->hash_func(old_key) % NBUCKETS; + old_hash = h->hash_func(old_key) % h->n_buckets; if (!(e = hash_scan(h, old_hash, old_key))) return -ENOENT; - new_hash = h->hash_func(new_key) % NBUCKETS; + new_hash = h->hash_func(new_key) % h->n_buckets; if (hash_scan(h, new_hash, new_key)) return -EEXIST; @@ -526,11 +594,11 @@ int hashmap_remove_and_replace(Hashmap *h, const void *old_key, const void *new_ if (!h) return -ENOENT; - old_hash = h->hash_func(old_key) % NBUCKETS; + old_hash = h->hash_func(old_key) % h->n_buckets; if (!(e = hash_scan(h, old_hash, old_key))) return -ENOENT; - new_hash = h->hash_func(new_key) % NBUCKETS; + new_hash = h->hash_func(new_key) % h->n_buckets; if ((k = hash_scan(h, new_hash, new_key))) if (e != k) remove_entry(h, k); @@ -552,9 +620,10 @@ void* hashmap_remove_value(Hashmap *h, const void *key, void *value) { if (!h) return NULL; - hash = h->hash_func(key) % NBUCKETS; + hash = h->hash_func(key) % h->n_buckets; - if (!(e = hash_scan(h, hash, key))) + e = hash_scan(h, hash, key); + if (!e) return NULL; if (e->value != value) @@ -642,9 +711,10 @@ void *hashmap_iterate_skip(Hashmap *h, const void *key, Iterator *i) { if (!h) return NULL; - hash = h->hash_func(key) % NBUCKETS; + hash = h->hash_func(key) % h->n_buckets; - if (!(e = hash_scan(h, hash, key))) + e = hash_scan(h, hash, key); + if (!e) return NULL; *i = (Iterator) e; @@ -723,6 +793,14 @@ unsigned hashmap_size(Hashmap *h) { return h->n_entries; } +unsigned hashmap_buckets(Hashmap *h) { + + if (!h) + return 0; + + return h->n_buckets; +} + bool hashmap_isempty(Hashmap *h) { if (!h) @@ -766,12 +844,12 @@ void hashmap_move(Hashmap *h, Hashmap *other) { n = e->iterate_next; - h_hash = h->hash_func(e->key) % NBUCKETS; + h_hash = h->hash_func(e->key) % h->n_buckets; if (hash_scan(h, h_hash, e->key)) continue; - other_hash = other->hash_func(e->key) % NBUCKETS; + other_hash = other->hash_func(e->key) % other->n_buckets; unlink_entry(other, e, other_hash); link_entry(h, e, h_hash); @@ -787,12 +865,13 @@ int hashmap_move_one(Hashmap *h, Hashmap *other, const void *key) { assert(h); - h_hash = h->hash_func(key) % NBUCKETS; + h_hash = h->hash_func(key) % h->n_buckets; if (hash_scan(h, h_hash, key)) return -EEXIST; - other_hash = other->hash_func(key) % NBUCKETS; - if (!(e = hash_scan(other, other_hash, key))) + other_hash = other->hash_func(key) % other->n_buckets; + e = hash_scan(other, other_hash, key); + if (!e) return -ENOENT; unlink_entry(other, e, other_hash); @@ -806,7 +885,8 @@ Hashmap *hashmap_copy(Hashmap *h) { assert(h); - if (!(copy = hashmap_new(h->hash_func, h->compare_func))) + copy = hashmap_new(h->hash_func, h->compare_func); + if (!copy) return NULL; if (hashmap_merge(copy, h) < 0) { @@ -845,7 +925,7 @@ void *hashmap_next(Hashmap *h, const void *key) { if (!h) return NULL; - hash = h->hash_func(key) % NBUCKETS; + hash = h->hash_func(key) % h->n_buckets; e = hash_scan(h, hash, key); if (!e) return NULL; diff --git a/src/shared/hashmap.h b/src/shared/hashmap.h index 15b7e27585..3d4f6721bc 100644 --- a/src/shared/hashmap.h +++ b/src/shared/hashmap.h @@ -76,6 +76,7 @@ int hashmap_move_one(Hashmap *h, Hashmap *other, const void *key); unsigned hashmap_size(Hashmap *h) _pure_; bool hashmap_isempty(Hashmap *h) _pure_; +unsigned hashmap_buckets(Hashmap *h) _pure_; void *hashmap_iterate(Hashmap *h, Iterator *i, const void **key); void *hashmap_iterate_backwards(Hashmap *h, Iterator *i, const void **key); diff --git a/src/test/test-hashmap.c b/src/test/test-hashmap.c index 2c27d08670..56a9b58c24 100644 --- a/src/test/test-hashmap.c +++ b/src/test/test-hashmap.c @@ -467,6 +467,30 @@ static void test_hashmap_get(void) { hashmap_free_free(m); } +static void test_hashmap_many(void) { + Hashmap *h; + unsigned i; + +#define N_ENTRIES 100000 + + assert_se(h = hashmap_new(NULL, NULL)); + + for (i = 1; i < N_ENTRIES*3; i+=3) { + assert_se(hashmap_put(h, UINT_TO_PTR(i), UINT_TO_PTR(i)) >= 0); + assert_se(PTR_TO_UINT(hashmap_get(h, UINT_TO_PTR(i))) == i); + } + + for (i = 1; i < N_ENTRIES*3; i++) + assert_se(hashmap_contains(h, UINT_TO_PTR(i)) == (i % 3 == 1)); + + log_info("%u <= %u * 0.75 = %g", hashmap_size(h), hashmap_buckets(h), hashmap_buckets(h) * 0.75); + + assert_se(hashmap_size(h) <= hashmap_buckets(h) * 0.75); + assert_se(hashmap_size(h) == N_ENTRIES); + + hashmap_free(h); +} + static void test_uint64_compare_func(void) { const uint64_t a = 0x100, b = 0x101; @@ -486,8 +510,7 @@ static void test_string_compare_func(void) { assert_se(string_compare_func("fred", "fred") == 0); } -int main(int argc, const char *argv[]) -{ +int main(int argc, const char *argv[]) { test_hashmap_copy(); test_hashmap_get_strv(); test_hashmap_move_one(); @@ -504,6 +527,7 @@ int main(int argc, const char *argv[]) test_hashmap_isempty(); test_hashmap_get(); test_hashmap_size(); + test_hashmap_many(); test_uint64_compare_func(); test_trivial_compare_func(); test_string_compare_func(); -- cgit v1.2.1 From 0b926f194aa117519bfc89a12ee6f01ffeeccc21 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 1 Oct 2013 00:15:15 +0200 Subject: Update TODO --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index c1f6e5ad62..d42de36b91 100644 --- a/TODO +++ b/TODO @@ -54,6 +54,8 @@ CGroup Rework Completion: Features: +* we probably should replace the left-over uses of strv_append() and replace them by strv_push() or strv_extend() + * logind should forget about fb devices in favour of going drm only * move config_parse_path_strv() out of conf-parser.c -- cgit v1.2.1 From ae05436265da80e2b6c88d2d7050f3912e7bfa96 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 1 Oct 2013 00:19:25 +0200 Subject: Revert "build-sys: link libsystemd-login with libsystemd-label.la" Systemd-logind does not pull in cg_create(), if we unconditionally link this, all users of systemd-logind qill need the label stuff and therefore link against selinux. It is probably a build-system issue, or something that need to be sorted out in a differnt way than linking not needed libs. This reverts commit ceadabb102b05b237bfab11e1f742975ee4daeb1. --- Makefile.am | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index af4e215538..92de1630b4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3919,7 +3919,6 @@ libsystemd_login_la_LDFLAGS = \ libsystemd_login_la_LIBADD = \ libsystemd-shared.la \ libsystemd-daemon-internal.la \ - libsystemd-label.la \ $(RT_LIBS) libsystemd_login_internal_la_SOURCES = \ -- cgit v1.2.1 From a1c9563cced72abe337e423b2a5ad19e0ed81325 Mon Sep 17 00:00:00 2001 From: Patrick McCarty Date: Mon, 30 Sep 2013 17:43:38 -0700 Subject: smack-setup: fix path to Smack/CIPSO mappings The correct path to the dir with CIPSO mappings is /etc/smack/cipso.d/; /etc/smack/cipso is a file that can include these mappings as well, though it is no longer supported in upstream libsmack. --- src/core/smack-setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/smack-setup.c b/src/core/smack-setup.c index d67a84a583..1434dea7c1 100644 --- a/src/core/smack-setup.c +++ b/src/core/smack-setup.c @@ -40,7 +40,7 @@ #include "label.h" #define SMACK_CONFIG "/etc/smack/accesses.d/" -#define CIPSO_CONFIG "/etc/smack/cipso/" +#define CIPSO_CONFIG "/etc/smack/cipso.d/" #ifdef HAVE_SMACK -- cgit v1.2.1 From ba5ecfcdbb4a4aa05f5040f847c207fd0df5de4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristian=20Rodr=C3=ADguez?= Date: Sun, 29 Sep 2013 23:17:42 -0300 Subject: systemctl: remove legacy upstart compatibility --- src/systemctl/systemctl.c | 93 ----------------------------------------------- 1 file changed, 93 deletions(-) diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index eede616e50..bb7ada9f32 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -5678,94 +5678,6 @@ _pure_ static int action_to_runlevel(void) { return table[arg_action]; } -static int talk_upstart(void) { - _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL; - _cleanup_dbus_error_free_ DBusError error; - int previous, rl, r; - char - env1_buf[] = "RUNLEVEL=X", - env2_buf[] = "PREVLEVEL=X"; - char *env1 = env1_buf, *env2 = env2_buf; - const char *emit = "runlevel"; - dbus_bool_t b_false = FALSE; - DBusMessageIter iter, sub; - DBusConnection *bus; - - dbus_error_init(&error); - - if (!(rl = action_to_runlevel())) - return 0; - - if (utmp_get_runlevel(&previous, NULL) < 0) - previous = 'N'; - - if (!(bus = dbus_connection_open_private("unix:abstract=/com/ubuntu/upstart", &error))) { - if (dbus_error_has_name(&error, DBUS_ERROR_NO_SERVER)) { - r = 0; - goto finish; - } - - log_error("Failed to connect to Upstart bus: %s", bus_error_message(&error)); - r = -EIO; - goto finish; - } - - if ((r = bus_check_peercred(bus)) < 0) { - log_error("Failed to verify owner of bus."); - goto finish; - } - - if (!(m = dbus_message_new_method_call( - "com.ubuntu.Upstart", - "/com/ubuntu/Upstart", - "com.ubuntu.Upstart0_6", - "EmitEvent"))) { - - log_error("Could not allocate message."); - r = -ENOMEM; - goto finish; - } - - dbus_message_iter_init_append(m, &iter); - - env1_buf[sizeof(env1_buf)-2] = rl; - env2_buf[sizeof(env2_buf)-2] = previous; - - if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &emit) || - !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub) || - !dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &env1) || - !dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &env2) || - !dbus_message_iter_close_container(&iter, &sub) || - !dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &b_false)) { - log_error("Could not append arguments to message."); - r = -ENOMEM; - goto finish; - } - - if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { - - if (bus_error_is_no_service(&error)) { - r = -EADDRNOTAVAIL; - goto finish; - } - - log_error("Failed to issue method call: %s", bus_error_message(&error)); - r = -EIO; - goto finish; - } - - r = 1; - -finish: - if (bus) { - dbus_connection_flush(bus); - dbus_connection_close(bus); - dbus_connection_unref(bus); - } - - return r; -} - static int talk_initctl(void) { struct init_request request = {}; int r; @@ -6037,11 +5949,6 @@ static int start_with_fallback(DBusConnection *bus) { goto done; } - /* Hmm, talking to systemd via D-Bus didn't work. Then - * let's try to talk to Upstart via D-Bus. */ - if (talk_upstart() > 0) - goto done; - /* Nothing else worked, so let's try * /dev/initctl */ if (talk_initctl() > 0) -- cgit v1.2.1 From abaaabf40a9891014ed4c402d7beb5a67ac256b1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 1 Oct 2013 03:22:41 +0200 Subject: build-sys: don't fallback to upstart defaults --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 45526f4a54..4c7fa23dfa 100644 --- a/configure.ac +++ b/configure.ac @@ -808,7 +808,7 @@ AC_ARG_WITH(telinit, AS_HELP_STRING([--with-telinit=PATH], [Path to telinit]), [TELINIT="$withval"], - [TELINIT="/lib/upstart/telinit"]) + [TELINIT="/lib/sysvinit/telinit"]) AC_DEFINE_UNQUOTED(TELINIT, ["$TELINIT"], [Path to telinit]) -- cgit v1.2.1 From e6dca814412f17db05910acedf76d36d3b7f1355 Mon Sep 17 00:00:00 2001 From: Evan Callicoat Date: Mon, 23 Sep 2013 21:01:04 -0500 Subject: units: Add SHELL environment variable With the advent of systemd --user sessions, it's become very interesting to spawn X as a user unit, as well as accompanying processes that may have previously been in a .xinitrc/.xsession, or even just to replace a collection of XDG/GDM/KDM/etc session files with independent systemd --user units. The simplest case here would be to login on a tty, with the traditional /usr/sbin/login "login manager". However, systemd --user (spawned by user@.service) is at the top level of the slice for the user, and does not inherit any environment variables from the login process. Given the number of common applications which rely on SHELL being set in the environment, it seems like the cleanest way to provide this variable is to set it to %s in the user@.service. Ideally in the long-term, applications which rely on SHELL being set should be fixed to just grab it from getpwnam() or similar, but until that becomes more common, I propose this simple change to make user sessions a little bit nicer out of the box. --- units/user@.service.in | 1 + 1 file changed, 1 insertion(+) diff --git a/units/user@.service.in b/units/user@.service.in index 3f8b59d07f..3718a57087 100644 --- a/units/user@.service.in +++ b/units/user@.service.in @@ -13,6 +13,7 @@ After=systemd-user-sessions.service User=%I PAMName=systemd-user Type=notify +Environment=SHELL=%s ExecStart=-@rootlibexecdir@/systemd --user Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%I/dbus/user_bus_socket Slice=user-%i.slice -- cgit v1.2.1 From c22ceead439fbd7825acb14b5db904851d0389ef Mon Sep 17 00:00:00 2001 From: Chen Jie Date: Thu, 12 Sep 2013 09:21:41 +0800 Subject: util.c: ignore pollfd.revent for loop_read/loop_write Let read()/write() report any error/EOF. --- src/shared/util.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/shared/util.c b/src/shared/util.c index fb42d663a6..5dc605eb8d 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -2186,8 +2186,10 @@ ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) { return n > 0 ? n : -errno; } - if (pollfd.revents != POLLIN) - return n > 0 ? n : -EIO; + /* We knowingly ignore the revents value here, + * and expect that any error/EOF is reported + * via read()/write() + */ continue; } @@ -2234,8 +2236,10 @@ ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) { return n > 0 ? n : -errno; } - if (pollfd.revents != POLLOUT) - return n > 0 ? n : -EIO; + /* We knowingly ignore the revents value here, + * and expect that any error/EOF is reported + * via read()/write() + */ continue; } -- cgit v1.2.1 From 7400b9d2e99938d17b281d7df43680eade18666e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 1 Oct 2013 05:06:56 +0200 Subject: core: whenever a new PID is passed to us, make sure we watch it --- src/core/service.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/core/service.c b/src/core/service.c index 24b7bef287..67920248d3 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -191,7 +191,13 @@ static int service_set_main_pid(Service *s, pid_t pid) { if (pid == getpid()) return -EINVAL; - service_unwatch_main_pid(s); + if (s->main_pid == pid && s->main_pid_known) + return 0; + + if (s->main_pid != pid) { + service_unwatch_main_pid(s); + exec_status_start(&s->main_exec_status, pid); + } s->main_pid = pid; s->main_pid_known = true; @@ -205,8 +211,6 @@ static int service_set_main_pid(Service *s, pid_t pid) { } else s->main_pid_alien = false; - exec_status_start(&s->main_exec_status, pid); - return 0; } @@ -2696,8 +2700,10 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value, if (parse_pid(value, &pid) < 0) log_debug_unit(u->id, "Failed to parse main-pid value %s", value); - else - service_set_main_pid(s, (pid_t) pid); + else { + service_set_main_pid(s, pid); + unit_watch_pid(UNIT(s), pid); + } } else if (streq(key, "main-pid-known")) { int b; @@ -3389,6 +3395,7 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags) { log_debug_unit(u->id, "%s: got %s", u->id, e); service_set_main_pid(s, pid); + unit_watch_pid(UNIT(s), pid); } } @@ -3685,8 +3692,10 @@ static void service_bus_query_pid_done( (s->state == SERVICE_START || s->state == SERVICE_START_POST || s->state == SERVICE_RUNNING || - s->state == SERVICE_RELOAD)) + s->state == SERVICE_RELOAD)){ service_set_main_pid(s, pid); + unit_watch_pid(UNIT(s), pid); + } } int service_set_socket_fd(Service *s, int fd, Socket *sock) { -- cgit v1.2.1 From 4cc1fe69131bb5c79553b017f3c5bc42f7c0a599 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 1 Oct 2013 13:35:37 +0200 Subject: update TODO --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index d42de36b91..d21ecfe622 100644 --- a/TODO +++ b/TODO @@ -54,6 +54,8 @@ CGroup Rework Completion: Features: +* set $SHELL where we set $HOME and $USER when User= is set of a service, drop its manual setting from user@.service + * we probably should replace the left-over uses of strv_append() and replace them by strv_push() or strv_extend() * logind should forget about fb devices in favour of going drm only -- cgit v1.2.1 From ea52e2aee8dd7b3f51e9a00e76a54ef12dc0e898 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Thu, 26 Sep 2013 00:38:34 +0200 Subject: kernel-install: add compat with 'installkernel' If 'kernel-install' is called as 'installkernel' it will be compatible with the syntax used by the kernel's build system. This means it can be called by doing 'make install' in a kernel build directory, if the correct symlink has been installed (which we don't do by default yet). [Edit harald@redhat.com: removed basename and use shift] --- src/kernel-install/kernel-install | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/kernel-install/kernel-install b/src/kernel-install/kernel-install index fb2ee57b5b..9d3e75db08 100644 --- a/src/kernel-install/kernel-install +++ b/src/kernel-install/kernel-install @@ -54,9 +54,15 @@ dropindirs_sort() export LC_COLLATE=C -COMMAND="$1" -KERNEL_VERSION="$2" -KERNEL_IMAGE="$3" +if [[ "${0##*/}" == 'installkernel' ]]; then + COMMAND='add' +else + COMMAND="$1" + shift +fi + +KERNEL_VERSION="$1" +KERNEL_IMAGE="$2" if [[ -f /etc/machine-id ]]; then read MACHINE_ID < /etc/machine-id -- cgit v1.2.1 From 081dfa852fc5cd183a20747f2d8e4ef62d29d181 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 1 Oct 2013 17:48:15 +0200 Subject: logind: fix session-device dbus notify Had this fix lying around here for some time. Thanks to missing type-checking for va-args we passed in the actual major/minor values instead of pointers to it. Fix it by saving the values on the stack first and passing in the pointers. --- src/login/logind-session-device.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/login/logind-session-device.c b/src/login/logind-session-device.c index b45f9ebe0c..27afafa1aa 100644 --- a/src/login/logind-session-device.c +++ b/src/login/logind-session-device.c @@ -46,9 +46,13 @@ static void session_device_notify(SessionDevice *sd, enum SessionDeviceNotificat _cleanup_dbus_message_unref_ DBusMessage *m = NULL; _cleanup_free_ char *path = NULL; const char *t = NULL; + uint32_t major, minor; assert(sd); + major = major(sd->dev); + minor = minor(sd->dev); + if (!sd->session->controller) return; @@ -68,8 +72,8 @@ static void session_device_notify(SessionDevice *sd, enum SessionDeviceNotificat switch (type) { case SESSION_DEVICE_RESUME: if (!dbus_message_append_args(m, - DBUS_TYPE_UINT32, major(sd->dev), - DBUS_TYPE_UINT32, minor(sd->dev), + DBUS_TYPE_UINT32, &major, + DBUS_TYPE_UINT32, &minor, DBUS_TYPE_UNIX_FD, &sd->fd, DBUS_TYPE_INVALID)) return; @@ -88,8 +92,8 @@ static void session_device_notify(SessionDevice *sd, enum SessionDeviceNotificat } if (t && !dbus_message_append_args(m, - DBUS_TYPE_UINT32, major(sd->dev), - DBUS_TYPE_UINT32, minor(sd->dev), + DBUS_TYPE_UINT32, &major, + DBUS_TYPE_UINT32, &minor, DBUS_TYPE_STRING, &t, DBUS_TYPE_INVALID)) return; -- cgit v1.2.1 From c2e5d024a380bae6ead301fb4f40787b372ec3e0 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 1 Oct 2013 17:53:43 +0200 Subject: logind: check whether first drmSetMaster succeeded The initial drmSetMaster may fail if there is an active master already. We must not assume that all existing clients comply to logind rules. We check for this during session-activation already but didn't during device setup. Fix this by checking the return code. As drmSetMaster has had horrible return codes in the past (0 for failure? EINVAL for denied access, ..) we need to be quite pedantic. To guarantee an open file-descriptor we need to close the device and reopen it without master if setting master failed first. --- src/login/logind-session-device.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/login/logind-session-device.c b/src/login/logind-session-device.c index 27afafa1aa..546c53710e 100644 --- a/src/login/logind-session-device.c +++ b/src/login/logind-session-device.c @@ -144,7 +144,7 @@ static int sd_drmdropmaster(int fd) { } static int session_device_open(SessionDevice *sd, bool active) { - int fd; + int fd, r; assert(sd->type != DEVICE_TYPE_UNKNOWN); @@ -155,9 +155,17 @@ static int session_device_open(SessionDevice *sd, bool active) { switch (sd->type) { case DEVICE_TYPE_DRM: - if (active) - sd_drmsetmaster(fd); - else { + if (active) { + /* Weird legacy DRM semantics might return an error + * even though we're master. No way to detect that so + * fail at all times and let caller retry in inactive + * state. */ + r = sd_drmsetmaster(fd); + if (r < 0) { + close(fd); + return r; + } + } else { /* DRM-Master is granted to the first user who opens a * device automatically (ughh, racy!). Hence, we just * drop DRM-Master in case we were the first. */ @@ -384,9 +392,17 @@ int session_device_new(Session *s, dev_t dev, SessionDevice **out) { * revoke access and thus invalidate the fd. But this is still needed * to pass a valid fd back. */ sd->active = session_is_active(s); - sd->fd = session_device_open(sd, sd->active); - if (sd->fd < 0) - goto error; + r = session_device_open(sd, sd->active); + if (r < 0) { + /* EINVAL _may_ mean a master is active; retry inactive */ + if (sd->active && r == -EINVAL) { + sd->active = false; + r = session_device_open(sd, false); + } + if (r < 0) + goto error; + } + sd->fd = r; LIST_PREPEND(SessionDevice, sd_by_device, sd->device->session_devices, sd); -- cgit v1.2.1 From dfd552707d43087a1e0079cdae9f5290e14b78e9 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 1 Oct 2013 17:58:58 +0200 Subject: logind: send PropertyChanged during deactivation We only send the PropertyChanged signal for the to-be-activated session but not for the to-be-deactivated one. Fix that so both listeners get notified about the new state. --- src/login/logind-seat.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c index 4a4d40adca..feebcf4558 100644 --- a/src/login/logind-seat.c +++ b/src/login/logind-seat.c @@ -246,8 +246,10 @@ int seat_set_active(Seat *s, Session *session) { old_active = s->active; s->active = session; - if (old_active) + if (old_active) { session_device_pause_all(old_active); + session_send_changed(old_active, "Active\0"); + } seat_apply_acls(s, old_active); -- cgit v1.2.1 From 11c2f7a81381127c253cc6fd05da6dad0d842336 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 1 Oct 2013 17:59:44 +0200 Subject: logind: run with CAP_SYS_ADMIN DRM Master access requires CAP_SYS_ADMIN, yay! Add it to the capability bounding set for systemd-logind. As CAP_SYS_ADMIN actually allows a huge set of actions, this mostly renders the restriction-set useless. Anyway, patches are already pending to reduce the restriction on the kernel side. But these won't really make it into any stable-release so for now we're stuck with CAP_SYS_ADMIN. --- units/systemd-logind.service.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/units/systemd-logind.service.in b/units/systemd-logind.service.in index 6b687171ca..31b5cd011f 100644 --- a/units/systemd-logind.service.in +++ b/units/systemd-logind.service.in @@ -18,7 +18,7 @@ ExecStart=@rootlibexecdir@/systemd-logind Restart=always RestartSec=0 BusName=org.freedesktop.login1 -CapabilityBoundingSet=CAP_AUDIT_CONTROL CAP_CHOWN CAP_KILL CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE CAP_FOWNER CAP_SYS_TTY_CONFIG +CapabilityBoundingSet=CAP_SYS_ADMIN CAP_AUDIT_CONTROL CAP_CHOWN CAP_KILL CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE CAP_FOWNER CAP_SYS_TTY_CONFIG # Increase the default a bit in order to allow many simultaneous # logins since we keep one fd open per session. -- cgit v1.2.1 From 3a83f5223acbeb1235310798c4d3660121c8880f Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 1 Oct 2013 18:08:54 +0200 Subject: logind: remove fbdev session-device support fbdev does not support access-handover so it is quite useless to route it through logind. If compositors want to use it they ought to open it themselves. It's highly recommended to be ignored entirely, though. fbdev is about to be deprecated in the kernel. --- src/login/logind-session-device.c | 18 ++---------------- src/login/logind-session-device.h | 1 - 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/src/login/logind-session-device.c b/src/login/logind-session-device.c index 546c53710e..6605935f3c 100644 --- a/src/login/logind-session-device.c +++ b/src/login/logind-session-device.c @@ -176,7 +176,6 @@ static int session_device_open(SessionDevice *sd, bool active) { if (!active) sd_eviocrevoke(fd); break; - case DEVICE_TYPE_FBDEV: case DEVICE_TYPE_UNKNOWN: default: /* fallback for devices wihout synchronizations */ @@ -213,14 +212,6 @@ static int session_device_start(SessionDevice *sd) { close_nointr_nofail(sd->fd); sd->fd = r; break; - case DEVICE_TYPE_FBDEV: - /* fbdev devices have no way to synchronize access. Moreover, - * they mostly operate through mmaps() without any pageflips - * and modesetting, so there is no way for us to prevent access - * but tear down mmaps. - * That would be quite expensive to do on a per-fd context. So - * ignore legcy fbdev and let its users feel the pain they asked - * for when deciding for fbdev. */ case DEVICE_TYPE_UNKNOWN: default: /* fallback for devices wihout synchronizations */ @@ -252,7 +243,6 @@ static void session_device_stop(SessionDevice *sd) { * protection this way. */ sd_eviocrevoke(sd->fd); break; - case DEVICE_TYPE_FBDEV: case DEVICE_TYPE_UNKNOWN: default: /* fallback for devices without synchronization */ @@ -270,10 +260,7 @@ static DeviceType detect_device_type(struct udev_device *dev) { subsystem = udev_device_get_subsystem(dev); type = DEVICE_TYPE_UNKNOWN; - if (streq_ptr(subsystem, "graphics")) { - if (!streq(sysname, "fbcon") && startswith(sysname, "fb")) - type = DEVICE_TYPE_FBDEV; - } else if (streq_ptr(subsystem, "drm")) { + if (streq_ptr(subsystem, "drm")) { if (startswith(sysname, "card")) type = DEVICE_TYPE_DRM; } else if (streq_ptr(subsystem, "input")) { @@ -314,8 +301,7 @@ static int session_device_verify(SessionDevice *sd) { goto err_dev; } sp = udev_device_get_syspath(dev); - } else if (sd->type != DEVICE_TYPE_FBDEV && - sd->type != DEVICE_TYPE_DRM) { + } else if (sd->type != DEVICE_TYPE_DRM) { /* Prevent opening unsupported devices. Especially devices of * subsystem "input" must be opened via the evdev node as * we require EVIOCREVOKE. */ diff --git a/src/login/logind-session-device.h b/src/login/logind-session-device.h index eac7ca7a63..61a843d09d 100644 --- a/src/login/logind-session-device.h +++ b/src/login/logind-session-device.h @@ -33,7 +33,6 @@ typedef struct SessionDevice SessionDevice; enum DeviceType { DEVICE_TYPE_UNKNOWN, - DEVICE_TYPE_FBDEV, DEVICE_TYPE_DRM, DEVICE_TYPE_EVDEV, }; -- cgit v1.2.1 From ef7939dfbb454f5ed7a00c2c4c686e0c5aa48f00 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 1 Oct 2013 19:21:35 +0200 Subject: Update TODO Remove "logind fbdev removal" as it is no longer supported. --- TODO | 2 -- 1 file changed, 2 deletions(-) diff --git a/TODO b/TODO index d21ecfe622..07269f47d2 100644 --- a/TODO +++ b/TODO @@ -58,8 +58,6 @@ Features: * we probably should replace the left-over uses of strv_append() and replace them by strv_push() or strv_extend() -* logind should forget about fb devices in favour of going drm only - * move config_parse_path_strv() out of conf-parser.c * libdsystemd-bus should expose utf8 validation calls -- cgit v1.2.1 From a3b6fafed441d96380a3f089118f7486d6aa3126 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 1 Oct 2013 23:11:23 +0200 Subject: hashmap: randomize hash functions a bit --- configure.ac | 2 +- src/shared/hashmap.c | 104 +++++++++++++++++++++++++++++++-------------------- src/shared/util.c | 19 ++++++++++ src/shared/util.h | 1 + 4 files changed, 85 insertions(+), 41 deletions(-) diff --git a/configure.ac b/configure.ac index 4c7fa23dfa..7e1d6f4e1c 100644 --- a/configure.ac +++ b/configure.ac @@ -821,7 +821,7 @@ have_myhostname=no AC_ARG_ENABLE(myhostname, AS_HELP_STRING([--disable-myhostname], [disable nss-myhostname support])) if test "x$enable_myhostname" != "xno"; then AC_HEADER_STDC - AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h sys/time.h unistd.h nss.h sys/ioctl.h]) + AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h sys/time.h unistd.h nss.h sys/ioctl.h sys/auxv.h]) AC_C_CONST AC_TYPE_SIZE_T diff --git a/src/shared/hashmap.c b/src/shared/hashmap.c index 633079277d..f06fce6ef3 100644 --- a/src/shared/hashmap.c +++ b/src/shared/hashmap.c @@ -24,6 +24,10 @@ #include #include +#ifdef HAVE_SYS_AUXV_H +#include +#endif + #include "util.h" #include "hashmap.h" #include "macro.h" @@ -46,6 +50,7 @@ struct Hashmap { struct hashmap_entry ** buckets; unsigned n_buckets, n_entries; + unsigned random_xor; bool from_pool; }; @@ -171,10 +176,15 @@ int uint64_compare_func(const void *_a, const void *_b) { return a < b ? -1 : (a > b ? 1 : 0); } +static unsigned bucket_hash(Hashmap *h, const void *p) { + return (h->hash_func(p) ^ h->random_xor) % h->n_buckets; +} + Hashmap *hashmap_new(hash_func_t hash_func, compare_func_t compare_func) { bool b; Hashmap *h; size_t size; + void *auxv; b = is_main_thread(); @@ -204,6 +214,19 @@ Hashmap *hashmap_new(hash_func_t hash_func, compare_func_t compare_func) { h->from_pool = b; + /* Let's randomize our hash functions a bit so that they are + * harder to guess for clients. For this, start out by cheaply + * using some bits the kernel passed into the process using + * the auxiliary vector. If the hashmap grows later on we will + * rehash everything using a new random XOR mask from + * /dev/random. */ +#ifdef HAVE_SYS_AUXV_H + auxv = (void*) getauxval(AT_RANDOM); + h->random_xor = auxv ? *(unsigned*) auxv : random_u(); +#else + h->random_xor = random_u(); +#endif + return h; } @@ -284,8 +307,7 @@ static void remove_entry(Hashmap *h, struct hashmap_entry *e) { assert(h); assert(e); - hash = h->hash_func(e->key) % h->n_buckets; - + hash = bucket_hash(h, e->key); unlink_entry(h, e, hash); if (h->from_pool) @@ -368,7 +390,6 @@ void hashmap_clear_free_free(Hashmap *h) { } } - static struct hashmap_entry *hash_scan(Hashmap *h, unsigned hash, const void *key) { struct hashmap_entry *e; assert(h); @@ -382,8 +403,8 @@ static struct hashmap_entry *hash_scan(Hashmap *h, unsigned hash, const void *ke } static bool resize_buckets(Hashmap *h) { - unsigned m; struct hashmap_entry **n, *i; + unsigned m, nxor; assert(h); @@ -398,6 +419,11 @@ static bool resize_buckets(Hashmap *h) { if (!n) return false; + /* Let's use a different randomized xor value for the + * extension, so that people cannot guess what we are using + * here forever */ + nxor = random_u(); + for (i = h->iterate_list_head; i; i = i->iterate_next) { unsigned hash, x; @@ -410,10 +436,10 @@ static bool resize_buckets(Hashmap *h) { if (i->bucket_previous) i->bucket_previous->bucket_next = i->bucket_next; else - h->buckets[hash % h->n_buckets] = i->bucket_next; + h->buckets[(hash ^ h->random_xor) % h->n_buckets] = i->bucket_next; /* Then, add to new backet table */ - x = hash % m; + x = (hash ^ nxor) % m; i->bucket_next = n[x]; i->bucket_previous = NULL; @@ -427,6 +453,7 @@ static bool resize_buckets(Hashmap *h) { h->buckets = n; h->n_buckets = m; + h->random_xor = nxor; return true; } @@ -437,7 +464,7 @@ int hashmap_put(Hashmap *h, const void *key, void *value) { assert(h); - hash = h->hash_func(key) % h->n_buckets; + hash = bucket_hash(h, key); e = hash_scan(h, hash, key); if (e) { if (e->value == value) @@ -446,7 +473,7 @@ int hashmap_put(Hashmap *h, const void *key, void *value) { } if (resize_buckets(h)) - hash = h->hash_func(key) % h->n_buckets; + hash = bucket_hash(h, key); if (h->from_pool) e = allocate_tile(&first_entry_pool, &first_entry_tile, sizeof(struct hashmap_entry)); @@ -470,7 +497,7 @@ int hashmap_replace(Hashmap *h, const void *key, void *value) { assert(h); - hash = h->hash_func(key) % h->n_buckets; + hash = bucket_hash(h, key); e = hash_scan(h, hash, key); if (e) { e->key = key; @@ -487,7 +514,7 @@ int hashmap_update(Hashmap *h, const void *key, void *value) { assert(h); - hash = h->hash_func(key) % h->n_buckets; + hash = bucket_hash(h, key); e = hash_scan(h, hash, key); if (!e) return -ENOENT; @@ -503,7 +530,7 @@ void* hashmap_get(Hashmap *h, const void *key) { if (!h) return NULL; - hash = h->hash_func(key) % h->n_buckets; + hash = bucket_hash(h, key); e = hash_scan(h, hash, key); if (!e) return NULL; @@ -518,7 +545,7 @@ void* hashmap_get2(Hashmap *h, const void *key, void **key2) { if (!h) return NULL; - hash = h->hash_func(key) % h->n_buckets; + hash = bucket_hash(h, key); e = hash_scan(h, hash, key); if (!e) return NULL; @@ -535,12 +562,8 @@ bool hashmap_contains(Hashmap *h, const void *key) { if (!h) return false; - hash = h->hash_func(key) % h->n_buckets; - - if (!hash_scan(h, hash, key)) - return false; - - return true; + hash = bucket_hash(h, key); + return !!hash_scan(h, hash, key); } void* hashmap_remove(Hashmap *h, const void *key) { @@ -551,9 +574,9 @@ void* hashmap_remove(Hashmap *h, const void *key) { if (!h) return NULL; - hash = h->hash_func(key) % h->n_buckets; - - if (!(e = hash_scan(h, hash, key))) + hash = bucket_hash(h, key); + e = hash_scan(h, hash, key); + if (!e) return NULL; data = e->value; @@ -569,11 +592,12 @@ int hashmap_remove_and_put(Hashmap *h, const void *old_key, const void *new_key, if (!h) return -ENOENT; - old_hash = h->hash_func(old_key) % h->n_buckets; - if (!(e = hash_scan(h, old_hash, old_key))) + old_hash = bucket_hash(h, old_key); + e = hash_scan(h, old_hash, old_key); + if (!e) return -ENOENT; - new_hash = h->hash_func(new_key) % h->n_buckets; + new_hash = bucket_hash(h, new_key); if (hash_scan(h, new_hash, new_key)) return -EEXIST; @@ -594,12 +618,14 @@ int hashmap_remove_and_replace(Hashmap *h, const void *old_key, const void *new_ if (!h) return -ENOENT; - old_hash = h->hash_func(old_key) % h->n_buckets; - if (!(e = hash_scan(h, old_hash, old_key))) + old_hash = bucket_hash(h, old_key); + e = hash_scan(h, old_hash, old_key); + if (!e) return -ENOENT; - new_hash = h->hash_func(new_key) % h->n_buckets; - if ((k = hash_scan(h, new_hash, new_key))) + new_hash = bucket_hash(h, new_key); + k = hash_scan(h, new_hash, new_key); + if (k) if (e != k) remove_entry(h, k); @@ -620,7 +646,7 @@ void* hashmap_remove_value(Hashmap *h, const void *key, void *value) { if (!h) return NULL; - hash = h->hash_func(key) % h->n_buckets; + hash = bucket_hash(h, key); e = hash_scan(h, hash, key); if (!e) @@ -711,7 +737,7 @@ void *hashmap_iterate_skip(Hashmap *h, const void *key, Iterator *i) { if (!h) return NULL; - hash = h->hash_func(key) % h->n_buckets; + hash = bucket_hash(h, key); e = hash_scan(h, hash, key); if (!e) @@ -820,9 +846,9 @@ int hashmap_merge(Hashmap *h, Hashmap *other) { for (e = other->iterate_list_head; e; e = e->iterate_next) { int r; - if ((r = hashmap_put(h, e->key, e->value)) < 0) - if (r != -EEXIST) - return r; + r = hashmap_put(h, e->key, e->value); + if (r < 0 && r != -EEXIST) + return r; } return 0; @@ -844,13 +870,11 @@ void hashmap_move(Hashmap *h, Hashmap *other) { n = e->iterate_next; - h_hash = h->hash_func(e->key) % h->n_buckets; - + h_hash = bucket_hash(h, e->key); if (hash_scan(h, h_hash, e->key)) continue; - other_hash = other->hash_func(e->key) % other->n_buckets; - + other_hash = bucket_hash(other, e->key); unlink_entry(other, e, other_hash); link_entry(h, e, h_hash); } @@ -865,11 +889,11 @@ int hashmap_move_one(Hashmap *h, Hashmap *other, const void *key) { assert(h); - h_hash = h->hash_func(key) % h->n_buckets; + h_hash = bucket_hash(h, key); if (hash_scan(h, h_hash, key)) return -EEXIST; - other_hash = other->hash_func(key) % other->n_buckets; + other_hash = bucket_hash(other, key); e = hash_scan(other, other_hash, key); if (!e) return -ENOENT; @@ -925,7 +949,7 @@ void *hashmap_next(Hashmap *h, const void *key) { if (!h) return NULL; - hash = h->hash_func(key) % h->n_buckets; + hash = bucket_hash(h, key); e = hash_scan(h, hash, key); if (!e) return NULL; diff --git a/src/shared/util.c b/src/shared/util.c index 5dc605eb8d..9be6acfc8f 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -2424,6 +2424,25 @@ fallback: return random() * RAND_MAX + random(); } +unsigned random_u(void) { + _cleanup_close_ int fd; + unsigned u; + ssize_t r; + + fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) + goto fallback; + + r = loop_read(fd, &u, sizeof(u), true); + if (r != sizeof(u)) + goto fallback; + + return u; + +fallback: + return random() * RAND_MAX + random(); +} + void rename_process(const char name[8]) { assert(name); diff --git a/src/shared/util.h b/src/shared/util.h index 63f4e3dff2..1b845b3803 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -253,6 +253,7 @@ int make_null_stdio(void); int make_console_stdio(void); unsigned long long random_ull(void); +unsigned random_u(void); /* For basic lookup tables with strictly enumerated entries */ #define __DEFINE_STRING_TABLE_LOOKUP(name,type,scope) \ -- cgit v1.2.1 From cd4010b37349413db1e553e213e62e654ca28113 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 2 Oct 2013 03:02:25 +0200 Subject: build-ss: prepare new release --- Makefile.am | 12 ++++----- NEWS | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 2 +- 3 files changed, 94 insertions(+), 7 deletions(-) diff --git a/Makefile.am b/Makefile.am index 92de1630b4..7785865d67 100644 --- a/Makefile.am +++ b/Makefile.am @@ -34,16 +34,16 @@ SUBDIRS = . po # Keep the test-suite.log .PRECIOUS: $(TEST_SUITE_LOG) Makefile -LIBUDEV_CURRENT=4 -LIBUDEV_REVISION=8 -LIBUDEV_AGE=3 +LIBUDEV_CURRENT=5 +LIBUDEV_REVISION=0 +LIBUDEV_AGE=4 LIBGUDEV_CURRENT=1 LIBGUDEV_REVISION=3 LIBGUDEV_AGE=1 LIBSYSTEMD_LOGIN_CURRENT=9 -LIBSYSTEMD_LOGIN_REVISION=0 +LIBSYSTEMD_LOGIN_REVISION=1 LIBSYSTEMD_LOGIN_AGE=9 LIBSYSTEMD_DAEMON_CURRENT=0 @@ -51,11 +51,11 @@ LIBSYSTEMD_DAEMON_REVISION=10 LIBSYSTEMD_DAEMON_AGE=0 LIBSYSTEMD_ID128_CURRENT=0 -LIBSYSTEMD_ID128_REVISION=25 +LIBSYSTEMD_ID128_REVISION=26 LIBSYSTEMD_ID128_AGE=0 LIBSYSTEMD_JOURNAL_CURRENT=11 -LIBSYSTEMD_JOURNAL_REVISION=2 +LIBSYSTEMD_JOURNAL_REVISION=3 LIBSYSTEMD_JOURNAL_AGE=11 # Dirs of external packages diff --git a/NEWS b/NEWS index d2e6510690..557774dc1f 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,92 @@ systemd System and Service Manager +CHANGES WITH 208: + + * logind has gained support for facilitating privileged input + and drm device access for unprivileged clients. This work is + useful to allow Wayland display servers (and similar + programs, such as kmscon) to run under the user's ID and + access input and drm devices which are normally + protected. When this is used (and the kernel is new enough) + logind will "mute" IO on the file descriptors passed to + Wayland as long as it is in the background and "unmute" it + if it returns into the foreground. This allows secure + session switching without allowing background sessions to + eavesdrop on input and display data. This also introduces + session switching support if VT support is turned off in the + kernel, and on seats that are not seat0. + + * A new kernel command line option luks.options= is understood + now which allows specifiying LUKS options for usage for LUKS + encrypted partitions specified with luks.uuid=. + + * tmpfiles.d(5) snippets may now use specifier expansion in + path names. More specifically %m, %b, %H, %v, are now + replaced by the local machine id, boot id, hostname, and + kernel version number. + + * A new tmpfiles.d(5) command "m" has been introduced which + may be used to change the owner/group/access mode of a file + or directory if it exists, but do nothing if it doesn't. + + * This release removes high-level support for the + MemorySoftLimit= cgroup setting. The underlying kernel + cgroup attribute memory.soft_limit= is currently badly + designed and likely to be removed from the kernel API in its + current form, hence we shouldn't expose it for now. + + * The memory.use_hierarchy cgroup attribute is now enabled for + all cgroups systemd creates in the memory cgroup + hierarchy. This option is likely to be come the built-in + default in the kernel anyway, and the non-hierarchial mode + never made much sense in the intrinsically hierarchial + cgroup system. + + * A new field _SYSTEMD_SLICE= is logged along with all journal + messages containing the slice a message was generated + from. This is useful to allow easy per-customer filtering of + logs among other things. + + * systemd-journald will no longer adjust the group of journal + files it creates to the "systemd-journal" group. Instead we + rely on the journal directory to be owned by the + "systemd-journal" group, and its setgid bit set, so that the + kernel file system layer will automatically enforce that + journal files inherit this group assignment. The reason for + this change is that we cannot allow NSS look-ups from + journald which would be necessary to resolve + "systemd-journal" to a numeric GID, because this might + create deadlocks if NSS involves synchronous queries to + other daemons (such as nscd, or sssd) which in turn are + logging clients of journald and might block on it, which + would then dead lock. A tmpfiles.d(5) snippet included in + systemd will make sure the setgid bit and group are + properly set on the journal directory if it exists on every + boot. However, we recommend adjusting it manually after + upgrades too (or from RPM scriptlets), so that the change is + not delayed until next reboot. + + * Backlight and random seed files in /var/lib/ have moved into + the /var/lib/systemd/ directory, in order to centralize all + systemd generated files in one directory. + + * Boot time performance measurements (as displayed by + "systemd-analyze" for example) will now read ACPI 5.0 FPDT + performance information if that's available to determine how + much time BIOS and boot loader initialization required. With + a sufficiently new BIOS you hence no longer need to boot + with Gummiboot to get access to such information. + + Contributions from: Andrey Borzenkov, Chen Jie, Colin Walters, + Cristian Rodríguez, Dave Reisner, David Herrmann, David + Mackey, David Strauss, Eelco Dolstra, Evan Callicoat, Gao + feng, Harald Hoyer, Jimmie Tauriainen, Kay Sievers, Lennart + Poettering, Lukas Nykryn, Mantas Mikulėnas, Martin Pitt, + Michael Scherer, Michał Górny, Mike Gilbert, Patrick McCarty, + Sebastian Ott, Tom Gundersen, Zbigniew Jędrzejewski-Szmek + + -- Berlin, 2013-10-02 + CHANGES WITH 207: * The Restart= option for services now understands a new diff --git a/configure.ac b/configure.ac index 7e1d6f4e1c..4f26092e91 100644 --- a/configure.ac +++ b/configure.ac @@ -20,7 +20,7 @@ AC_PREREQ([2.64]) AC_INIT([systemd], - [207], + [208], [http://bugs.freedesktop.org/enter_bug.cgi?product=systemd], [systemd], [http://www.freedesktop.org/wiki/Software/systemd]) -- cgit v1.2.1 From fbd8ebddbe43f55f76d6d6dc681b342ca2dd4376 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 2 Oct 2013 04:52:48 +0200 Subject: build-sys: mkdir.[ch] should be in libsystemd-shared Otherwise, why is mkdir-label.[ch] split out? --- Makefile.am | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile.am b/Makefile.am index 7785865d67..4570e18de2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -721,7 +721,9 @@ libsystemd_shared_la_SOURCES = \ src/shared/acpi-fpdt.c \ src/shared/boot-timestamps.h \ src/shared/boot-timestamps.c \ - src/shared/refcnt.h + src/shared/refcnt.h \ + src/shared/mkdir.c \ + src/shared/mkdir.h #------------------------------------------------------------------------------- noinst_LTLIBRARIES += \ @@ -771,9 +773,7 @@ libsystemd_label_la_SOURCES = \ src/shared/label.h \ src/shared/selinux-util.c \ src/shared/selinux-util.h \ - src/shared/mkdir.c \ src/shared/mkdir-label.c \ - src/shared/mkdir.h \ src/shared/ask-password-api.c \ src/shared/ask-password-api.h \ src/shared/fileio-label.c \ -- cgit v1.2.1 From 1434ae6fd49f8377b0ddbd4c675736e0d3226ea6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 2 Oct 2013 04:54:07 +0200 Subject: cgroup: there's no point in labelling cgroupfs dirs, so let's not do that This allows us to get rid of the dep on libsystemd-label for cgroup management. https://bugs.freedesktop.org/show_bug.cgi?id=69966 --- Makefile.am | 1 - src/shared/cgroup-label.c | 80 ----------------------------------------------- src/shared/cgroup-util.c | 41 ++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 81 deletions(-) delete mode 100644 src/shared/cgroup-label.c diff --git a/Makefile.am b/Makefile.am index 4570e18de2..8d9c58758f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -767,7 +767,6 @@ noinst_LTLIBRARIES += \ libsystemd-label.la libsystemd_label_la_SOURCES = \ - src/shared/cgroup-label.c \ src/shared/socket-label.c \ src/shared/label.c \ src/shared/label.h \ diff --git a/src/shared/cgroup-label.c b/src/shared/cgroup-label.c deleted file mode 100644 index bae0a627d2..0000000000 --- a/src/shared/cgroup-label.c +++ /dev/null @@ -1,80 +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 Lesser General Public License as published by - the Free Software Foundation; either version 2.1 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see . -***/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "cgroup-util.h" -#include "log.h" -#include "set.h" -#include "macro.h" -#include "util.h" -#include "mkdir.h" - -/* This is split out since it needs label calls, either directly or - * indirectly. */ - -int cg_create(const char *controller, const char *path) { - _cleanup_free_ char *fs = NULL; - int r; - - r = cg_get_path_and_check(controller, path, NULL, &fs); - if (r < 0) - return r; - - r = mkdir_parents_prefix_label("/sys/fs/cgroup", fs, 0755); - if (r < 0) - return r; - - if (mkdir(fs, 0755) < 0) { - - if (errno == EEXIST) - return 0; - - return -errno; - } - - return 1; -} - -int cg_create_and_attach(const char *controller, const char *path, pid_t pid) { - int r, q; - - assert(pid >= 0); - - r = cg_create(controller, path); - if (r < 0) - return r; - - q = cg_attach(controller, path, pid); - if (q < 0) - return q; - - /* This does not remove the cgroup on failure */ - return r; -} diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index f57f2b2c42..8a4eddab7a 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -39,6 +39,7 @@ #include "unit-name.h" #include "fileio.h" #include "special.h" +#include "mkdir.h" int cg_enumerate_processes(const char *controller, const char *path, FILE **_f) { _cleanup_free_ char *fs = NULL; @@ -618,6 +619,46 @@ int cg_delete(const char *controller, const char *path) { return r == -ENOENT ? 0 : r; } +int cg_create(const char *controller, const char *path) { + _cleanup_free_ char *fs = NULL; + int r; + + r = cg_get_path_and_check(controller, path, NULL, &fs); + if (r < 0) + return r; + + r = mkdir_parents(fs, 0755); + if (r < 0) + return r; + + if (mkdir(fs, 0755) < 0) { + + if (errno == EEXIST) + return 0; + + return -errno; + } + + return 1; +} + +int cg_create_and_attach(const char *controller, const char *path, pid_t pid) { + int r, q; + + assert(pid >= 0); + + r = cg_create(controller, path); + if (r < 0) + return r; + + q = cg_attach(controller, path, pid); + if (q < 0) + return q; + + /* This does not remove the cgroup on failure */ + return r; +} + int cg_attach(const char *controller, const char *path, pid_t pid) { _cleanup_free_ char *fs = NULL; char c[DECIMAL_STR_MAX(pid_t) + 2]; -- cgit v1.2.1