[systemd-devel] [PATCH 0/3] Add support for setting limit of memory + swap usage

2013-09-17 Thread Chen Hanxiao
From: Chen Hanxiao chenhanx...@cn.fujitsu.com

Add support for setting limit of memory + swap usage.
So programes like libvirt could set it via systemd.
Users could also set this via systemctl command.

Chen Hanxiao (3):
  Enable systemd to set/show limit of memory+Swap usage
  Add support for systemctl to set limit of memory+Swap usage
  Add support for showing limit of memory+Swap usage via
cgroup_context_dump

 src/core/cgroup.c | 13 +
 src/core/cgroup.h |  1 +
 src/core/dbus-cgroup.c| 18 ++
 src/core/load-fragment-gperf.gperf.m4 |  1 +
 src/systemctl/systemctl.c |  3 ++-
 5 files changed, 35 insertions(+), 1 deletion(-)

-- 
1.8.2.1

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH 3/3] Add support for showing limit of memory+Swap usage via cgroup_context_dump

2013-09-17 Thread Chen Hanxiao
From: Chen Hanxiao chenhanx...@cn.fujitsu.com

Add support for showing limit of memory+Swap usage
via cgroup_context_dump.

Signed-off-by: Chen Hanxiao chenhanx...@cn.fujitsu.com
---
 src/core/cgroup.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index d8bc318..c6a1690 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -95,6 +95,7 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const 
char *prefix) {
 %sCPUShares=%lu\n
 %sBlockIOWeight%lu\n
 %sMemoryLimit=% PRIu64 \n
+%sMemorySWLimit=% PRIu64 \n
 %sMemorySoftLimit=% PRIu64 \n
 %sDevicePolicy=%s\n,
 prefix, yes_no(c-cpu_accounting),
@@ -103,6 +104,7 @@ 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-memsw_limit,
 prefix, c-memory_soft_limit,
 prefix, cgroup_device_policy_to_string(c-device_policy));
 
-- 
1.8.2.1

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH 1/3] Enable systemd to set/show limit of memory+Swap usage

2013-09-17 Thread Chen Hanxiao
From: Chen Hanxiao chenhanx...@cn.fujitsu.com

Enable systemd to set/show limit of memory+Swap usage.

Signed-off-by: Chen Hanxiao chenhanx...@cn.fujitsu.com
---
 src/core/cgroup.c | 11 +++
 src/core/cgroup.h |  1 +
 src/core/dbus-cgroup.c| 18 ++
 src/core/load-fragment-gperf.gperf.m4 |  1 +
 4 files changed, 31 insertions(+)

diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index 1f41efc..d8bc318 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -34,6 +34,7 @@ void cgroup_context_init(CGroupContext *c) {
 
 c-cpu_shares = 1024;
 c-memory_limit = c-memory_soft_limit = (uint64_t) -1;
+c-memsw_limit = (uint64_t) -1;
 c-blockio_weight = 1000;
 }
 
@@ -266,6 +267,15 @@ 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-memsw_limit != (uint64_t) -1) {
+sprintf(buf, % PRIu64 \n, c-memsw_limit);
+r = cg_set_attribute(memory, path, 
memory.memsw.limit_in_bytes, buf);
+} else
+r = cg_set_attribute(memory, path, 
memory.memsw.limit_in_bytes, -1);
+
+if (r  0)
+log_error(Failed to set memory.memsw.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);
@@ -337,6 +347,7 @@ CGroupControllerMask cgroup_context_get_mask(CGroupContext 
*c) {
 
 if (c-memory_accounting ||
 c-memory_limit != (uint64_t) -1 ||
+c-memsw_limit != (uint64_t) -1 ||
 c-memory_soft_limit != (uint64_t) -1)
 mask |= CGROUP_MEMORY;
 
diff --git a/src/core/cgroup.h b/src/core/cgroup.h
index 786bd71..3519061 100644
--- a/src/core/cgroup.h
+++ b/src/core/cgroup.h
@@ -77,6 +77,7 @@ struct CGroupContext {
 LIST_HEAD(CGroupBlockIODeviceBandwidth, blockio_device_bandwidths);
 
 uint64_t memory_limit;
+uint64_t memsw_limit;
 uint64_t memory_soft_limit;
 
 CGroupDevicePolicy device_policy;
diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c
index 1f2a396..8235da0 100644
--- a/src/core/dbus-cgroup.c
+++ b/src/core/dbus-cgroup.c
@@ -133,6 +133,7 @@ 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)   },
+{ MemorySWLimit,   bus_property_append_uint64,  t, 
offsetof(CGroupContext, memsw_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   },
@@ -438,6 +439,23 @@ int bus_cgroup_set_property(
 
 return 1;
 
+} else if (streq(name, MemorySWLimit)) {
+
+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);
+
+c-memsw_limit = limit;
+
+unit_write_drop_in_private_format(u, mode, name, 
%s=% PRIu64, name, limit);
+}
+
+return 1;
+
 } else if (streq(name, DevicePolicy)) {
 const char *policy;
 CGroupDevicePolicy p;
diff --git a/src/core/load-fragment-gperf.gperf.m4 
b/src/core/load-fragment-gperf.gperf.m4
index 33c6880..0471cae 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -89,6 +89,7 @@ $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)

[systemd-devel] [PATCH 2/3] Add support for systemctl to set limit of memory+Swap usage

2013-09-17 Thread Chen Hanxiao
From: Chen Hanxiao chenhanx...@cn.fujitsu.com

Add support for systemctl to set limit of memory+Swap usage.

Signed-off-by: Chen Hanxiao chenhanx...@cn.fujitsu.com
---
 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 57e5bb9..116e0b5 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -3657,7 +3657,8 @@ 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) || streq(field, 
MemorySWLimit) ||
+   streq(field, MemorySoftLimit)) {
 off_t bytes;
 uint64_t u;
 
-- 
1.8.2.1

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH] Just list all the variables

2013-09-17 Thread Colin Guthrie
'Twas brillig, and Zbigniew Jędrzejewski-Szmek at 16/09/13 14:26 did
gyre and gimble:
 On Thu, Sep 12, 2013 at 03:37:14PM +0200, Zbigniew Jędrzejewski-Szmek wrote:
 On Thu, Sep 12, 2013 at 03:32:12PM +0200, Zbigniew Jędrzejewski-Szmek wrote:
 On Fri, Jul 26, 2013 at 11:24:44AM +0100, Colin Guthrie wrote:
 +paraAll processes are executed in a clean environment in
 +which only the TERM, PATH, USER, and HOME variables are
 +inherited (from PID1) by default. In order to set 
 additional
 +variables, see the Environment= and EnvironmentFile= 
 options
 +below. To specify variables globally, you can configure
 +DefaultEnvironment= in
 +
 citerefentryrefentrytitlesystemd-system.conf/refentrytitlemanvolnum5/manvolnum/citerefentry./para
 Hi,
 I pushed something like this now, but with completely different text,
 since variables exported have changed significantly, and in addition
 the behaviour for PID 1 and user instances is significantly different.
 Hm, looking at the other part of this thread, Kay and Lennart have provided
 a full list of variables. It is too long for one or two paragraphs, so
 maybe a separate section describing all variables and circumstances in
 which they are set should be added.
 I compiled a list of the variables. It is kind of hard to provide
 some meaningful text without being either very verbose or trivial,
 and I feel the text still awkward. Comments, suggestions?

Maybe a little awkward but I still think it's better than what is there
currently!

Some minor comments below.

 ---
  man/systemd.exec.xml | 133 
 ++-
  1 file changed, 111 insertions(+), 22 deletions(-)
 
 diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
 index 5721dc1..2a950cf 100644
 --- a/man/systemd.exec.xml
 +++ b/man/systemd.exec.xml
 @@ -57,7 +57,7 @@
  titleDescription/title
  
  paraUnit 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./para
  
 @@ -76,27 +76,6 @@
  configuration options are configured in the [Service],
  [Socket], [Mount], or [Swap] sections, depending on the unit
  type./para
 -
 -paraProcesses started by the system systemd instance
 -are executed in a clean environment in which only the
 -varname$PATH/varname and varname$LANG/varname
 -variables are set by default. In order to add
 -additional variables, see the
 -varnameEnvironment=/varname and
 -varnameEnvironmentFile=/varname options below. To
 -specify variables globally, see
 -varnameDefaultEnvironment=/varname in
 -
 citerefentryrefentrytitlesystemd-system.conf/refentrytitlemanvolnum5/manvolnum/citerefentry
 -or the kernel option
 -varnamesystemd.setenv=/varname in
 -
 citerefentryrefentrytitlesystemd/refentrytitlemanvolnum1/manvolnum/citerefentry.
  Processes
 -started by the user systemd instances inherit all
 -environment variables from the user systemd instance,
 -and have varname$HOME/varname,
 -varname$USER/varname,
 -varname$XDG_RUNTIME_DIR/varname defined, among
 -others. In addition, varname$MANAGERPID/varname
 -contains the PID of the user systemd instance./para
  /refsect1
  
  refsect1
 @@ -1006,6 +985,116 @@
  /refsect1
  
  refsect1
 +titleEnvironment variables in spawned processes/title
 +
 +paraProcesses 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.
 +/para
 +
 +variablelist class='environment-variables'
 +varlistentry
 +termvarname$PATH/varname/term
 +
 +listitemparaColon-separated list
 +of directiories to use when launching
 +executables. Set for all units.
 +/para/listitem

It's possibly worth mentioning that variables are not set from the
underlying environment. e.g. if a user set export
PATH=/opt/mystuff/bin:$PATH 

Re: [systemd-devel] [PATCH 1/5] cgroup: add the setting memory.use_hierarchy support for systemd

2013-09-17 Thread Lennart Poettering
On Mon, 16.09.13 09:57, Gao feng (gaof...@cn.fujitsu.com) wrote:

 
 On 09/13/2013 08:26 PM, Lennart Poettering wrote:
  On Fri, 13.09.13 17:49, Gao feng (gaof...@cn.fujitsu.com) wrote:
  
  Some programs need to set the memory.use_hierarchy(such as libvirt),
  Add this feature.
  
  Hmm, should this really be an option? Shouldn't we much rather turn this
  on unconditionally if the memory controller is used for a unit?
  
  This appears like an option that would go a way in Tejun's new sane
  cgroup tree logic anyway, no?
  
 
 So, systemd has no job to deal with memory hierarchy? the kernel will
 support memory hierarchy unconditionally? right?

Hmm? What I was suggesting is that memory.use_hierarchy should be the
default for systemd, and not configurable by the user, under the
assumption that with Tejun's sane_behaviour thing this would become the
default anyway?

Tejun?

Lennart

-- 
Lennart Poettering - Red Hat, Inc.
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] An option to activate other unit (or units) when an unit enter deactivated state

2013-09-17 Thread Lennart Poettering
On Fri, 13.09.13 02:34, 황재영 (j-zero.hw...@samsung.com) wrote:

Hello guys.
 
I'm searching an option that activate unit (or units) when an unit enter
deactivated state.
 
I know OnFailure option, but that is activated when entering failed
state only.
 
Is threr any option that can be activated when all case?

No this is not available. We don't want to turn systemd units into a
Turing complete language, so I am really conservative on adding
something liket this.

Note however, that with Type=oneshot services you can get something
similar, simply by queuing multiple oneshot services with ordering
dependencies in to the systemd job queue.

Lennart

-- 
Lennart Poettering - Red Hat, Inc.
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH 1/3] Enable systemd to set/show limit of memory+Swap usage

2013-09-17 Thread Lennart Poettering
On Tue, 17.09.13 14:21, Chen Hanxiao (chenhanx...@cn.fujitsu.com) wrote:

 +{ MemorySWLimit,   bus_property_append_uint64,  
 t, offsetof(CGroupContext, memsw_limit)   },
  { MemorySoftLimit, bus_property_append_uint64,  
 t, offsetof(CGroupContext, memory_soft_limit)  },

The patch looks fine in principle, but I really don't like the
abbreviated name like this. Can we name this MemorySwapLimit= or so?
Or MemoryAndSwapLimit=? Or MemoryPlusSwapLimit=? Or
MemoryIncludingSwapLimit=? MemorySwapSumLimit=?

I don't particularly like either of the latter really, anybody else got
suggestions?

The one that is the most descriptive fromt he above is probably
MemoryIncludingSwapLimit=, even if it sucks hard to type...

Lennart

-- 
Lennart Poettering - Red Hat, Inc.
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH v2 04/10] logind: make Session.Activate() lazy

2013-09-17 Thread David Herrmann
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 fe5fa27..fa8b515 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) {
-- 
1.8.4

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH v2 03/10] logind: add session controllers

2013-09-17 Thread David Herrmann
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 5decf81..113a2b7 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 2cc4d85..b8b32cd 100644
--- a/src/login/logind-session-dbus.c
+++ b/src/login/logind-session-dbus.c
@@ -40,6 +40,10 @@
arg name=\who\ type=\s\/\n   \
arg name=\signal\ type=\s\/\n\
   /method\n \
+  method name=\RequestControl\/\n \
+   arg name=\force\ type=\b\/\n \
+  /method\n \
+  method name=\DropControl\/\n\
   signal name=\Lock\/\n   \
   signal name=\Unlock\/\n \
   property name=\Id\ type=\s\ access=\read\/\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, RequestControl)) {
+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 = 

[systemd-devel] [PATCH v2 06/10] logind: rename vtconsole to seat0

2013-09-17 Thread David Herrmann
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 113a2b7..4a23c93 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 dcaf0ac..88fd724 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));
@@ -429,16 +429,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
@@ -450,7 +450,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) {
@@ -508,7 +508,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 bd5390f..47fe89a 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 5a1e621..77eeb9c 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -387,7 +387,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 c99c284..702382a 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 

[systemd-devel] [PATCH v2 05/10] logind: introduce session-devices

2013-09-17 Thread David Herrmann
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 mimic 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-node 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 device-nodes exclusively to
identify devices on the bus. On RequestDevice() we retrieve the
udev_device from the device-node 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 device-node. 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 

[systemd-devel] [PATCH v2 10/10] logind: implement generic multi-session

2013-09-17 Thread David Herrmann
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 f88738a..4a4d40a 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 d3438b8..be6db6e 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 659f161..af9d5a1 100644
--- a/src/login/logind-session-device.c
+++ b/src/login/logind-session-device.c
@@ -452,10 +452,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) {
@@ -487,3 +498,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 98e61e6..61732bc 100644
--- a/src/login/logind-session-device.h
+++ b/src/login/logind-session-device.h
@@ -55,3 +55,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 906115a..722e3d3 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) {
  

Re: [systemd-devel] [PATCH 1/3] Enable systemd to set/show limit of memory+Swap usage

2013-09-17 Thread Lennart Poettering
On Tue, 17.09.13 14:21, Chen Hanxiao (chenhanx...@cn.fujitsu.com) wrote:

 From: Chen Hanxiao chenhanx...@cn.fujitsu.com
 
 @@ -89,6 +89,7 @@ $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.MemorySWLimit,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)

OK, so here's another idea: I have the strong suspicion that people are
much more likely using the new limit that includes the swap than the
current MemoryLimit= that doesn't.

Hence, to make this simpler, I'd propose to simply swap things around:

MemoryLimit= would start writing to memory.memsw.limit_in_bytes. And a
new MemoryRAMLimit= would controler the original memory.limit_in_bytes?

This shifts things around a bit but I think it would be much nicer to
use?

Lennart

-- 
Lennart Poettering - Red Hat, Inc.
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH v2 08/10] logind: fix session_activate(vtnr = 0)

2013-09-17 Thread David Herrmann
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 77eeb9c..1df2a06 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -378,7 +378,7 @@ int session_activate(Session *s) {
 assert(s);
 assert(s-user);
 
-if (s-vtnr  0)
+if (s-vtnr = 0)
 return -ENOTSUP;
 
 if (!s-seat)
-- 
1.8.4

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] Question: who should set up the cpuset cgroup

2013-09-17 Thread Lennart Poettering
On Mon, 16.09.13 11:17, Gao feng (gaof...@cn.fujitsu.com) wrote:

 Hi
 
 I'm working on adding set cpuset cgroup support for systemd.
 this work almost finished. but I faced a problem.
 
 As we know, if we create a machine,the cgroup for this machine
 will be created as well. and the cgroup of this machine is a
 sub-directory of machine.slice(or other slices..). And if the
 cpuset of machine.slice is unset. the setting of cpuset for this
 machine will failed. since the cpuset.mems and cpuset.cpus of
 machine.slice is null.
 
 The question is who should set up the cpuset cgroup of machine.slice?
 
 1, set up when systemd creates cpuset cgroup for machine.slice?
 2, the programs which create the machines?
 3, other ideas? kernel?

I have the suspicion that we need to propagate this down from the root
of the hierarchy as soon as a leaf sets a cpu set.

Let's say the root has enabled all cpus (which is the default after
all), and you enable only a subset for a leaf 2 levels down, but do not
specify anything for the slice that is in the middle, then the cpuset of
the root should be propagated down.
  
Consider this hierarchy:

-.slice 
   /   \
  / \
machine.slicesystemd.slice
 |
 |
machine-customer1.slice
 |
 |
 a.scope

If a.scope gets a cpuset assigned, and neither machine.slice nor
machine-customer1.slice have any, then the cpuset of -.slice should be
inherited into machine.slice and then further into
machine-customer1.slice, if you follow what I mean?

Lennart

-- 
Lennart Poettering - Red Hat, Inc.
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH] Just list all the variables

2013-09-17 Thread Zbigniew Jędrzejewski-Szmek
On Tue, Sep 17, 2013 at 09:56:53AM +0100, Colin Guthrie wrote:
 It's possibly worth mentioning that variables are not set from the
 underlying environment. e.g. if a user set export
 PATH=/opt/mystuff/bin:$PATH in /etc/profile.d/my-stuff.sh, systemd will
 not see that PATH change.
 
 While it applies to all variables listed here and I know you mention it
 at the end, this ($PATH) is the one that most regular users would
 probably expect to be inherited (IMO) so it possibly warrants a mention
 above the tl;dr fold!

Applied, with a note that says that $PATH is fixed. In essence, it is,
because pid eins uses a fixed one, and that is passwd onto systemd
--user, which in turns passes it onto child services.

Zbyszek
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH v2 01/10] logind: listen actively for session devices

2013-09-17 Thread Lennart Poettering
On Tue, 17.09.13 17:39, David Herrmann (dh.herrm...@gmail.com) wrote:

Applied! Thanks!

 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 51b1535..a9a9633 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 3b15356..315f0e6 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 470d08b..2c60b8a 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);

Re: [systemd-devel] [PATCH v2 03/10] logind: add session controllers

2013-09-17 Thread Lennart Poettering
On Tue, 17.09.13 17:39, David Herrmann (dh.herrm...@gmail.com) wrote:

Please rename the bus calls to TakeControl()/ReleaseControl() (as
discussed at the hackfest). Otherwise patch #2 and #3 look good to merge!

 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 5decf81..113a2b7 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 2cc4d85..b8b32cd 100644
 --- a/src/login/logind-session-dbus.c
 +++ b/src/login/logind-session-dbus.c
 @@ -40,6 +40,10 @@
 arg name=\who\ type=\s\/\n   \
 arg name=\signal\ type=\s\/\n\
/method\n \
 +  method name=\RequestControl\/\n \
 +   arg name=\force\ type=\b\/\n \
 +  /method\n \
 +  method name=\DropControl\/\n\
signal name=\Lock\/\n   \
signal name=\Unlock\/\n \
property name=\Id\ type=\s\ access=\read\/\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, RequestControl)) {
 +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 

[systemd-devel] [PATCH v2 09/10] logind: extract has_vts() from can_multi_session()

2013-09-17 Thread David Herrmann
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 4a23c93..fd8ee1b 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 4c2c424..f88738a 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++) {
@@ -282,7 +282,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);
@@ -306,7 +306,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);
@@ -417,18 +417,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);
 
@@ -438,19 +440,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 47fe89a..d3438b8 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 1df2a06..906115a 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -206,7 +206,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)
@@ -316,7 +316,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)) {
   

[systemd-devel] [PATCH v2 07/10] logind: fix seat_can_tty() to check for VTs

2013-09-17 Thread David Herrmann
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 88fd724..4c2c424 100644
--- a/src/login/logind-seat.c
+++ b/src/login/logind-seat.c
@@ -450,7 +450,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) {
-- 
1.8.4

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH v2 03/10] logind: add session controllers

2013-09-17 Thread Lennart Poettering
On Tue, 17.09.13 18:29, Lennart Poettering (lenn...@poettering.net) wrote:

 Please rename the bus calls to TakeControl()/ReleaseControl() (as
 discussed at the hackfest). Otherwise patch #2 and #3 look good to merge!

Oh well, did the change myself now and commited! Thanks!

Also commited #2, and #4.

Lennart

-- 
Lennart Poettering - Red Hat, Inc.
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH 1/3] Enable systemd to set/show limit of memory+Swap usage

2013-09-17 Thread Lennart Poettering
On Tue, 17.09.13 17:36, Lennart Poettering (lenn...@poettering.net) wrote:

 On Tue, 17.09.13 14:21, Chen Hanxiao (chenhanx...@cn.fujitsu.com) wrote:
 
  From: Chen Hanxiao chenhanx...@cn.fujitsu.com
  
  @@ -89,6 +89,7 @@ $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.MemorySWLimit,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)
 
 OK, so here's another idea: I have the strong suspicion that people are
 much more likely using the new limit that includes the swap than the
 current MemoryLimit= that doesn't.
 
 Hence, to make this simpler, I'd propose to simply swap things around:
 
 MemoryLimit= would start writing to memory.memsw.limit_in_bytes. And a
 new MemoryRAMLimit= would controler the original memory.limit_in_bytes?
 
 This shifts things around a bit but I think it would be much nicer to
 use?

OK, so I talked to Tejun here at LinuxCon and he said that we probably
should not expose memory.memsw.limit_in_bytes for now since it's likely
to change or go away soon. In fact, the only memory attribute we should
expose for now is MemoryLimit= accorrding to him, and it should do what
it already does.

Also, he said that memory.use_hierarchy should be unconditionally set by
systemd for all cgroups systemd creates.

Lennart

-- 
Lennart Poettering - Red Hat, Inc.
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] udev: path_id - fix by-path link generation for scm devices

2013-09-17 Thread Sebastian Ott

Set some_transport = true to prevent scm devices from being ignored.

Suggested-by: Harald Hoyer har...@redhat.com
Signed-off-by: Sebastian Ott seb...@linux.vnet.ibm.com
---
 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 da02731..0659967 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);
-- 
1.8.1

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] Question: who should set up the cpuset cgroup

2013-09-17 Thread Lennart Poettering
On Tue, 17.09.13 17:45, Lennart Poettering (lenn...@poettering.net) wrote:

  1, set up when systemd creates cpuset cgroup for machine.slice?
  2, the programs which create the machines?
  3, other ideas? kernel?
 
 I have the suspicion that we need to propagate this down from the root
 of the hierarchy as soon as a leaf sets a cpu set.
 
 Let's say the root has enabled all cpus (which is the default after
 all), and you enable only a subset for a leaf 2 levels down, but do not
 specify anything for the slice that is in the middle, then the cpuset of
 the root should be propagated down.
   
 Consider this hierarchy:
 
 -.slice 
/   \
   / \
 machine.slicesystemd.slice
  |
  |
 machine-customer1.slice
  |
  |
  a.scope
 
 If a.scope gets a cpuset assigned, and neither machine.slice nor
 machine-customer1.slice have any, then the cpuset of -.slice should be
 inherited into machine.slice and then further into
 machine-customer1.slice, if you follow what I mean?

So I talked to Tejun about this too, and he said that cpuset is too
broken in the kernel for us to wrap it right now in systemd. As soon as
the kernel is fixed it will provide a proper propagation logic in the
kernel natively anyway, so we shouldn't bother with this in userspace.

Lennart

-- 
Lennart Poettering - Red Hat, Inc.
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH v2 05/10] logind: introduce session-devices

2013-09-17 Thread Lennart Poettering
On Tue, 17.09.13 17:39, David Herrmann (dh.herrm...@gmail.com) wrote:

 arg name=\force\ type=\b\/\n \
/method\n \
method name=\DropControl\/\n\
 +  method name=\RequestDevice\\n   \
 +   arg name=\node\ type=\s\ direction=\in\/\n \
 +   arg name=\fd\ type=\h\ direction=\out\/\n  \
 +   arg name=\paused\ type=\b\ direction=\out\/\n  \
 +  /method\n \
 +  method name=\ReleaseDevice\\n   \
 +   arg name=\node\ type=\s\/\n  \
 +  /method\n
  \

Please rename this pair to TakeDevice() and ReleaseDevice().

 index 000..659f161
 --- /dev/null
 +++ b/src/login/logind-session-device.c
 @@ -0,0 +1,489 @@
 +/*-*- 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 http://www.gnu.org/licenses/.
 +***/
 +
 +#include assert.h
 +#include fcntl.h
 +#include libudev.h
 +#include linux/input.h
 +#include linux/ioctl.h
 +#include string.h
 +#include sys/ioctl.h
 +#include sys/stat.h
 +#include sys/types.h
 +#include unistd.h
 +
 +#include dbus-common.h
 +#include logind-session-device.h
 +#include util.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_STRING, sd-node,
 +  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_STRING, sd-node,
 +   DBUS_TYPE_STRING, t,
 +   DBUS_TYPE_INVALID))
 +return;
 +
 +dbus_connection_send(sd-session-manager-bus, m, NULL);
 +}
 +
 +static int sd_eviocrevoke(int fd)
 +{

{ please on the same line as the function name.

 +static bool warned;
 +int r;
 +
 +#ifndef EVIOCREVOKE
 +#  define EVIOCREVOKE _IOW('E', 0x91, int)
 +#endif

Please move this to missing.h.

 +
 +assert(fd = 0);
 +
 +r = ioctl(fd, EVIOCREVOKE, 1);
 +if (r  0) {
 +r = -errno;
 +if (r == -ENOSYS  !warned) {
 +warned = true;
 +log_warning(kernel does not support 
 evdev-revocation);
 +}
 +}
 +
 +return 0;
 +}
 +
 +static int sd_drmsetmaster(int fd)
 +{

{...

 +int r;
 +
 +#ifndef DRM_IOCTL_SET_MASTER
 +#  define DRM_IOCTL_SET_MASTER _IO('d', 0x1e)
 +#endif

→ missing.h!

 +
 +assert(fd = 0);
 +
 +r = ioctl(fd, DRM_IOCTL_SET_MASTER, 0);
 +if 

Re: [systemd-devel] [PATCH] systemd-nspawn@: drop ControlGroup=

2013-09-17 Thread Lennart Poettering
On Mon, 16.09.13 07:38, Brandon Philips (bran...@ifup.co) wrote:

 ControlGroup= is deprecated now drop this from
 systemd-nspawn@.service. Without this 206 has a broken systemd-nspawn@
 unit.

Commited a patch like this while you were sitting next to me!

Thanks!

Lennart

-- 
Lennart Poettering - Red Hat, Inc.
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH] udev: path_id - fix by-path link generation for scm devices

2013-09-17 Thread Kay Sievers
On Tue, Sep 17, 2013 at 12:16 PM, Sebastian Ott
seb...@linux.vnet.ibm.com wrote:

 Set some_transport = true to prevent scm devices from being ignored.

Applied.

Thanks,
Kay
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH v2 01/10] logind: listen actively for session devices

2013-09-17 Thread David Herrmann
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 51b1535..a9a9633 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 3b15356..315f0e6 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 470d08b..2c60b8a 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 

Re: [systemd-devel] [PATCH v2 09/10] logind: extract has_vts() from can_multi_session()

2013-09-17 Thread Lennart Poettering
On Tue, 17.09.13 17:40, David Herrmann (dh.herrm...@gmail.com) wrote:

Applied #6 to #9, please update/rebase #5 and #10.

Thanks a lot!

 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 4a23c93..fd8ee1b 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 4c2c424..f88738a 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++) {
 @@ -282,7 +282,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);
 @@ -306,7 +306,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);
 @@ -417,18 +417,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);
  
 @@ -438,19 +440,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 47fe89a..d3438b8 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 1df2a06..906115a 100644
 --- a/src/login/logind-session.c
 +++ b/src/login/logind-session.c
 @@ -206,7 +206,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))
  

Re: [systemd-devel] [ANNOUNCE] systemd 207

2013-09-17 Thread Lennart Poettering
On Fri, 13.09.13 15:15, Colin Guthrie (gm...@colin.guthr.ie) wrote:

 
 'Twas brillig, and Lennart Poettering at 13/09/13 03:16 did gyre and gimble:
  * 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).
 
 I think you mean the *former* is preferred now? (I cannot see how
 allow-discards is easier to type than discard ;)

I clarified this in the NEWS file now. Of course discard is the 
preferred name as you guessed.

  * 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.
 
 It's also worth noting here that sysctl.d files are processed
 differently now.
 
 Up to and including v197 (or fabe5c0e5fce730aa66e10a9c4f9fdd443d7aeda),
 sysctl.d files had to be named higher than the 50-default.conf file to
 override something. e.g. if you wanted to override kernel.sysrq = 16
 then you needed to put it in a file named 51-i-know-better.conf in the
 appropriate location.
 
 From v198+ the order changed, and you had to name the file *lower* than
 50-default.conf, e.g. 49-i-know-better.conf.
 
 Now from v207 onwards the ordering has reverted back to the v197 logic
 (which I agree feels more natural).
 
 If you have distro tools and/or have deployed updates which adapted to
 this change in behaviour, you should undo those changes with this release.
 
 It may make sense to update the NEWS file in git to include a note about
 this (albeit very minor) API breakage (although the v198 NEWS didn't
 mention it's change in behaviour so perhaps it's fine to leave it out!).
 
 All the best

I added a short comment now to the NEWS file that mentions that this
basically reverts things to pre-198. Does that work for you?

Thanks,

Lennart

-- 
Lennart Poettering - Red Hat, Inc.
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] Should systemd-logind provide a DM-independent specification for per seat autologin settings and others?

2013-09-17 Thread Lennart Poettering
On Fri, 13.09.13 09:14, Laércio Benedito Sivali de Sousa (lbsous...@gmail.com) 
wrote:

 Hi guys!
 
 With systemd-logind, we finally have a canonical way to implement
 multiseat in Linux. As current display managers implement completely
 logind's protocol for automatic multiseat support, per seat configuration
 in these DMs is almost unneeded.

I am not convinced this is really material for logind, since we wouldn't
do anything with it... And it's really not a configuration store for
other services. dconf might be that, but certainly not systemd/logind.

 However, even with complete automatic multiseat support, some per seat
 settings are still valuable in DMs, namely:
 
 * Autologin settings for each seat: enable/disable, set user/password, set
 autologin delay.
 * Customize display server (X, Mir, Wayland/Weston) command line for each
 seat.

(Side note: systemd/logind is not supported by Ubuntu (only an outdated
fork of logind was incorporated into it), and Mir is not supported by on
anything but Ubuntu. Hence Mir is irrelevant to us.)

Lennart

-- 
Lennart Poettering - Red Hat, Inc.
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] systemd shutdown vs ostree

2013-09-17 Thread Lennart Poettering
On Sun, 15.09.13 17:26, Koen Kooi (k...@dominion.thruhere.net) wrote:

  On Sat, Sep 14, 2013 at 10:52 AM, Koen Kooi k...@dominion.thruhere.net 
  wrote:
  Please keep in mind that pstore is x86 only. EFI isn't x86 only, but 
  exceedingly rare outside of that arch.
  
  What? Pstore itself isn't. It's a generic interface to persistent
  platform storage. There are backends using EFI variables, NVRAM
  (PowerPC) or the APEI ERST (x86). As a last resort there's also a
  platform-independent RAM backend which may at least survive a simple
  reboot.
 
 OK, so x86 and ppc only. That will leaves out arm, mips and others.

I am pretty sure that it would be relatively easy to add support for an
addition ARM backend to pstore if such functionality is available on ARM
systems. The thing is simply that we should support pstore where it is
available, and get people to use that as the one and only API for these
kinds of things.

That all said, currently we cannot use pstore anyway, since there is no
way to tag the pstore data with the machine identity the data is
from. Which means that if you have a suse/Fedora dual-boot system there
is no way how we could make sure that the Suse instance doesn't end up
with Fedora's pstore logs in the journal and vice versa. 

To make pstore workable for us we'd need some scheme how we could echo
the machine ID into some virtual kernel file and then be sure that the
kernel adds that into the pstore data if something happens.

Lennart

-- 
Lennart Poettering - Red Hat, Inc.
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] bug #64614 and journal seeking woes

2013-09-17 Thread Zbigniew Jędrzejewski-Szmek
Hi,
I was looking at https://bugs.freedesktop.org/show_bug.cgi?id=64614

tl;dr: doing
   sd_journal_seek_tail()
   sd_journal_next()
   sd_journal_next()
   sd_journal_next()
   sd_journal_next()
returns 1 (success) each time, and random entries.

Likewise, doing
   sd_journal_seek_head()
   sd_journal_previous()...
returns 1 (success) and random entries.

Those specific cases could be changed to behave differently, but I
think that there's a more general problem.

According to sd_journal_seek_tail(3), this function positions the journal
on the last entry. sd_j_seek_head positions the journal on the oldest
entry. It is important that journal is *on* the first/last entry, which
suggests that it is in a valid location. Nevertheless,
   sd_journal_get_cursor()
returns -EADDRNOTAVAIL, as if the journal was *before* or *after* the last
entry.

Also, doing sd_j_seek_tail() + sd_j_previous() moves to the *last* entry,
which seems inconsistent with the description in the man pages (if we
were *at* the last entry, and we move back, we should be at the next to
last entry).

Also, doing sd_j_seek_tail(), waiting a bit while the journal file grows,
and doing sd_j_previous() lands as at the *current* last entry, which
is a bit strange.

I'd like to change:
1. sd_j_seek_tail() to seek to a concrete entry, the last at a specific time,
2. sd_j_seek_head() likewise,
3. allow sd_j_get_cursor() after such a seek
4. make sd_j_seek_tail() + sd_j_next() return 0 (if the file hasn't grown),
   or the first new entry if it has grown meanwhile
5. likewise make sd_j_seek_head() + sd_j_previous() return 0

Thoughts, comments, shrugs?

Zbyszek
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] logind: implement generic multi-session

2013-09-17 Thread David Herrmann
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 f88738a..4a4d40a 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 d3438b8..be6db6e 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 80fd364..e92bb54 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 511fce0..eac7ca7 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 fcc1901..eea0bfb 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) {
  

Re: [systemd-devel] [ANNOUNCE] systemd 207

2013-09-17 Thread Jan Engelhardt

On Tuesday 2013-09-17 21:03, Lennart Poettering wrote:
On Fri, 13.09.13 15:15, Colin Guthrie (gm...@colin.guthr.ie) wrote:
 
 'Twas brillig, and Lennart Poettering at 13/09/13 03:16 did gyre and gimble:
  * 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).
 
 I think you mean the *former* is preferred now? (I cannot see how
 allow-discards is easier to type than discard ;)

I clarified this in the NEWS file now. Of course discard is the 
preferred name as you guessed.

Humm. That's unfortunate (in a way) that discards is the same
allow-discards.

In pam_mount where discard too had been feature-requested (and then
implemented according to the way it sounds): allow-discards
_allows_ discarding, but only discard would make it such that
the filesystem issues discards to the block layer, leaving the
former case for manual discards.
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [ANNOUNCE] systemd 207

2013-09-17 Thread Lennart Poettering
On Wed, 18.09.13 00:13, Jan Engelhardt (jeng...@inai.de) wrote:

 
 
 On Tuesday 2013-09-17 21:03, Lennart Poettering wrote:
 On Fri, 13.09.13 15:15, Colin Guthrie (gm...@colin.guthr.ie) wrote:
  
  'Twas brillig, and Lennart Poettering at 13/09/13 03:16 did gyre and 
  gimble:
   * 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).
  
  I think you mean the *former* is preferred now? (I cannot see how
  allow-discards is easier to type than discard ;)
 
 I clarified this in the NEWS file now. Of course discard is the 
 preferred name as you guessed.
 
 Humm. That's unfortunate (in a way) that discards is the same
 allow-discards.
 
 In pam_mount where discard too had been feature-requested (and then
 implemented according to the way it sounds): allow-discards
 _allows_ discarding, but only discard would make it such that
 the filesystem issues discards to the block layer, leaving the
 former case for manual discards.

Hmm, and what the is the underlying between the two in pam_mount? I
mean, what does it translate to in mount options?

Lennart

-- 
Lennart Poettering - Red Hat, Inc.
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH] logind: implement generic multi-session

2013-09-17 Thread Lennart Poettering
On Tue, 17.09.13 23:40, David Herrmann (dh.herrm...@gmail.com) wrote:

Applied both! Thanks a lot!

 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 f88738a..4a4d40a 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 d3438b8..be6db6e 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 80fd364..e92bb54 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 511fce0..eac7ca7 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 

Re: [systemd-devel] [ANNOUNCE] systemd 207

2013-09-17 Thread Lennart Poettering
On Wed, 18.09.13 00:15, Lennart Poettering (lenn...@poettering.net) wrote:

  On Tuesday 2013-09-17 21:03, Lennart Poettering wrote:
  On Fri, 13.09.13 15:15, Colin Guthrie (gm...@colin.guthr.ie) wrote:
   
   'Twas brillig, and Lennart Poettering at 13/09/13 03:16 did gyre and 
   gimble:
* 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).
   
   I think you mean the *former* is preferred now? (I cannot see how
   allow-discards is easier to type than discard ;)
  
  I clarified this in the NEWS file now. Of course discard is the 
  preferred name as you guessed.
  
  Humm. That's unfortunate (in a way) that discards is the same
  allow-discards.
  
  In pam_mount where discard too had been feature-requested (and then
  implemented according to the way it sounds): allow-discards
  _allows_ discarding, but only discard would make it such that
  the filesystem issues discards to the block layer, leaving the
  former case for manual discards.
 
 Hmm, and what the is the underlying between the two in pam_mount? I

^^^ difference is missing here... Sorry.
 
 mean, what does it translate to in mount options?
 
 Lennart
 


Lennart

-- 
Lennart Poettering - Red Hat, Inc.
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] logind: introduce session-devices

2013-09-17 Thread David Herrmann
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

Re: [systemd-devel] User journal corrupted or uncleanly shut down, renaming and replacing

2013-09-17 Thread Pedro Francisco
On Wed, Sep 11, 2013 at 6:33 PM, Lennart Poettering
lenn...@poettering.net wrote:
 On Mon, 12.08.13 14:58, Pedro Francisco (pedrogfranci...@gmail.com) wrote:

 Hi,
 Systemd complains frequently about corrupted journal. Do note: I don't
 have the default mount options.

 $ dmesg |grep corrupte
 [   51.766346] systemd-journald[181]: File
 /var/log/journal/06fde5edd4974fa9a343215f093f5aae/user-42.journal
 corrupted or uncleanly shut down, renaming and replacing.

 $ sudo rpm -qa systemd
 systemd-204-9.fc19.i686

 $ cat /proc/mounts
 (...)
 /dev/sda6 / ext4 rw,seclabel,noatime,nobarrier 0 0
 (...)

 In addition, I have an issue related to systemd-journald stopping
 logging after a while if there are lots of output, as I mentioned on
 http://thread.gmane.org/gmane.comp.sysutils.systemd.devel/12373 titled
 Journald stops logging when lots of output .

 Do you think:
 a) mount options can affect systemd logging and
 b) these two issues (the one on this email about corrupted journal and
 the one on the linked thread about journald crashing when there are
 lots of output) may be related?

 Thanks in Advance,

 My guess is that for some reason the file systems are not properly
 unmounted during shutdown. Can you maybe try to get shutdown logs as
 described here?

 http://freedesktop.org/wiki/Software/systemd/Debugging/#index2h1

 Are you using LVM or something else weird? Are you using Dracut? Does
 the issue go away if you drop nobarrier from your mount options?

Seems to be fixed on systemd-204-11.fc19.i686 (tried two boots,
changed nothing else).
If it happens again, I'll report back.

Anyway, for the record: no LVM and it was default boot process for
Fedora 19, so I guess I'm using dracut.

Thank you for your time!
-- 
Pedro
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [ANNOUNCE] systemd 207

2013-09-17 Thread Jan Engelhardt
On Wednesday 2013-09-18 00:15, Lennart Poettering wrote:
 
 In pam_mount where discard too had been feature-requested (and then
 implemented according to the way it sounds): allow-discards
 _allows_ discarding, but only discard would make it such that
 the filesystem issues discards to the block layer, leaving the
 former case for manual discards.

Hmm, and what the is the underlying between the two in pam_mount? I
mean, what does it translate to in mount options?

In pseudocode:

if (allow_discards || discards)
flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
crypt_activate_by_passphrase(, ..., flags);
if (discard)
system(mount -o discard /dev/foo /bar);
else
system(mount /dev/foo /bar);


Here is also some quoting from (another poster; not me) from the 
pam_mount archives.

[pam_mount's] discard [...] does two things: 1) allows the discard
FITRIM ioctl to be passed through to the underlying filesystem, and
2) actually passes the discard mount option down [...] 1) is
necessary to allow the fstrim command to work, and 2) is undesirable
because automatic discard incurs a significant performance penalty
(see e.g. https://patrick-nagel.net/blog/archives/337).
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] util: preserve get_process_capeff behavior

2013-09-17 Thread Shawn Landden
69ab80881552d5f79ca95f6b3be48ad122ab1ec2 tried to unify
parsing of status files, but removed the logic of skipping
extra '0's when getting the effective capabilities. Restore
that logic.
---
 src/shared/util.c | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/src/shared/util.c b/src/shared/util.c
index bf31511..b68f15c 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -694,7 +694,8 @@ int is_kernel_thread(pid_t pid) {
 }
 
 int get_process_capeff(pid_t pid, char **capeff) {
-const char *p;
+const char *p, *t;
+int r;
 
 assert(capeff);
 assert(pid = 0);
@@ -704,7 +705,18 @@ int get_process_capeff(pid_t pid, char **capeff) {
 else
 p = procfs_file_alloca(pid, status);
 
-return get_status_field(p, \nCapEff:, capeff);
+r = get_status_field(p, \nCapEff:, capeff);
+
+for (t = *capeff; t[0] == '0'; t++)
+continue;
+
+if (t[0] == '\0')
+t--;
+
+if (t != *capeff)
+memmove(*capeff, t, strlen(t) + 1);
+
+return r;
 }
 
 int get_process_exe(pid_t pid, char **name) {
-- 
1.8.4.rc3

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH] logind: fix build for ARM with sizeof(dev_t) sizeof(void*)

2013-09-17 Thread Zbigniew Jędrzejewski-Szmek
On Wed, Sep 18, 2013 at 01:00:02AM +0200, David Herrmann wrote:
 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.
Applied.

Zbyszek

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] logind: fix build for ARM with sizeof(dev_t) sizeof(void*)

2013-09-17 Thread David Herrmann
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 f793f99..5f6bafb 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 e92bb54..b45f9eb 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 eea0bfb..ce982ef 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 : 

Re: [systemd-devel] [PATCH] util: preserve get_process_capeff behavior

2013-09-17 Thread Zbigniew Jędrzejewski-Szmek
On Tue, Sep 17, 2013 at 03:48:46PM -0700, Shawn Landden wrote:
 69ab80881552d5f79ca95f6b3be48ad122ab1ec2 tried to unify
 parsing of status files, but removed the logic of skipping
 extra '0's when getting the effective capabilities. Restore
 that logic.
Oh, I removed the logic on purpose, because I didn't know what
it was for. I applied a different fix now, which is a bit hacky,
but simplifies our hot path a bit. I've also added some comments
to make it clearer why 0's are skipped.

Zbyszek
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH 1/3] Enable systemd to set/show limit of memory+Swap usage

2013-09-17 Thread Chen Hanxiao


 -Original Message-
 From: Lennart Poettering [mailto:lenn...@poettering.net]
 Sent: Wednesday, September 18, 2013 12:54 AM
 To: Chen Hanxiao
 Cc: systemd-devel@lists.freedesktop.org
 Subject: Re: [systemd-devel] [PATCH 1/3] Enable systemd to set/show limit
of
 memory+Swap usage
 
 On Tue, 17.09.13 17:36, Lennart Poettering (lenn...@poettering.net) wrote:
 
  On Tue, 17.09.13 14:21, Chen Hanxiao (chenhanx...@cn.fujitsu.com) wrote:
 
   From: Chen Hanxiao chenhanx...@cn.fujitsu.com
  
   @@ -89,6 +89,7 @@ $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.MemorySWLimit,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)
 
  OK, so here's another idea: I have the strong suspicion that people are
  much more likely using the new limit that includes the swap than the
  current MemoryLimit= that doesn't.
 
  Hence, to make this simpler, I'd propose to simply swap things around:
 
  MemoryLimit= would start writing to memory.memsw.limit_in_bytes. And a
  new MemoryRAMLimit= would controler the original memory.limit_in_bytes?
 
  This shifts things around a bit but I think it would be much nicer to
  use?
 
 OK, so I talked to Tejun here at LinuxCon and he said that we probably
 should not expose memory.memsw.limit_in_bytes for now since it's likely
 to change or go away soon. In fact, the only memory attribute we should
 expose for now is MemoryLimit= accorrding to him, and it should do what
 it already does.
 
 Also, he said that memory.use_hierarchy should be unconditionally set by
 systemd for all cgroups systemd creates.
 
 Lennart

Got it.  
Then let's see how cgroup would deal with it.

Thanks.

 
 --
 Lennart Poettering - Red Hat, Inc.


___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel