Re: [systemd-devel] MemoryLimit for user unit
On 2017년 11월 13일 09:53, Kai Krakow wrote: > Am Sun, 12 Nov 2017 18:14:38 +0100 > schrieb Stefan Schweter: > >> Hi systemd-users, >> >> I tried to add a memory limit for a user service unit (inspired by >> [1]), it looks like: >> >> [Service] >> # >> MemoryAccounting=true >> MemoryLimit=1G >> >> Now the problem is that the (user) service consumes more than 1G >> without being terminated. > > As far as I could see, this limits the amount of RAM occupied. It > doesn't stop the memory from being swapped out. You need to limit swap > memory, too. Take note that swap accounting may have noticeable > overheads and as such is not enabled by default on many systems. > By this reason, MemorySwapMax= option is introduced. https://github.com/systemd/systemd/pull/3659 Note, MemorySwapLimit= does not exist. Lennard does not want to add more options for legacy cgroup. Further, the swap limit operations different between legacy and unified cgroup. So adding MemorySwapLimit= was not good idea. > >> htop shows a memory consumption of 1.4 GB. The output of >> `systemd-cgtop` is: >> >> Control Group Tasks %CPU Memory >> Input/s Output/s >> / -1.5 >> 1.7G- >> >> /user.slice 460.4 >> 14.3M- >> >> /user.slice/user-1001.slice 460.4 >> 14.2M- >> >> /init.scope 1 - >> 1.4M- >> >> /system.slice >> >> >> So my question is how would MemoryLimit= work for a user unit? > > Maybe you want to apply the limit to a slice? Your output of cgtop > doesn't show any service units... > > ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] Supporting properties(configurations) system
Hi, As you may know, Android has properties. http://developer.android.com/reference/java/util/Properties.html In the desktop side, it maybe similar with configuration system such like gconf. I hope the configurations are supporting write protected(ro) and writable(rw). To control this, I think new daemon will be needed and the daemon has to be activated before the clients(user of the configuration system). If system has plan to this, we hope to do this. Thanks, WaLyong ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [RFC] exec: introduce StandardOutputFile/StandardErrorFile option
On 2015년 05월 19일 12:53, Andrei Borzenkov wrote: В Tue, 19 May 2015 11:49:45 +0900 WaLyong Cho walyong@samsung.com пишет: On 2015년 05월 19일 11:44, WaLyong Cho wrote: To redirect stdout/stderr to file add 'file' option to StandardOutput/StandardError. And to specify the file path, add StandardOutputFile/StandardErrorFile option. If only set StandardOutput/StandardError to 'file' without set of StandardOutputFile/StandardErrorFile option, then it will be redirected to '/dev/null'. I think this patch is not complete yet. But I'd like to check you think this facility is useful or not. You should start with describing your use case and what is missing in current logging. You can fetch all unit output from journal already. journal is already good logging infrastructure under systemd system. But the centralized logging is very heavy if there are many logging messages. I know, we should reduce the log messages. But it is really hard on short development lifecycle product. We should fix many problems with many logging message. I think, this can correspond to many of embedded system. By this reason, in Tizen, dlog is still main logging system. I'd never want to blame systemd journal logging. That just does not suit on our system(Tizen). Anyway, I think text file logging itself can be useful even if we can see the log from systemd journal for debugging or many other purpose such like shell redirecting. WaLyong ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [RFC] exec: introduce StandardOutputFile/StandardErrorFile option
On 2015년 05월 19일 11:44, WaLyong Cho wrote: To redirect stdout/stderr to file add 'file' option to StandardOutput/StandardError. And to specify the file path, add StandardOutputFile/StandardErrorFile option. If only set StandardOutput/StandardError to 'file' without set of StandardOutputFile/StandardErrorFile option, then it will be redirected to '/dev/null'. I think this patch is not complete yet. But I'd like to check you think this facility is useful or not. If you agree then I'd like to add StandardOutputFileMode/StandardErrorFileMode and StandardOutputFlag/StandardErrorFlag option. StandardOutputFileMode/StandardErrorFileMode will able to set the file mode such like 0644 and StandardOutputFlag/StandardErrorFlag will able to set the file open flag such like append or trunc. WaLyong ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [RFC] exec: introduce StandardOutputFile/StandardErrorFile option
To redirect stdout/stderr to file add 'file' option to StandardOutput/StandardError. And to specify the file path, add StandardOutputFile/StandardErrorFile option. If only set StandardOutput/StandardError to 'file' without set of StandardOutputFile/StandardErrorFile option, then it will be redirected to '/dev/null'. --- src/core/execute.c| 22 ++ src/core/execute.h| 3 +++ src/core/load-fragment-gperf.gperf.m4 | 2 ++ 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/core/execute.c b/src/core/execute.c index 0cca481..a1408e0 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -197,12 +197,12 @@ static bool is_terminal_output(ExecOutput o) { o == EXEC_OUTPUT_JOURNAL_AND_CONSOLE; } -static int open_null_as(int flags, int nfd) { +static int open_file_as(int flags, const char *file, int nfd) { int fd, r; assert(nfd = 0); -fd = open(/dev/null, flags|O_NOCTTY); +fd = open(file ? file : /dev/null, flags|O_NOCTTY); if (fd 0) return -errno; @@ -215,6 +215,10 @@ static int open_null_as(int flags, int nfd) { return r; } +static int open_null_as(int flags, int nfd) { +return open_file_as(flags, /dev/null, nfd); +} + static int connect_journal_socket(int fd, uid_t uid, gid_t gid) { union sockaddr_union sa = { .un.sun_family = AF_UNIX, @@ -420,7 +424,8 @@ static int setup_output(Unit *unit, const ExecContext *context, int fileno, int return fileno; /* Duplicate from stdout if possible */ -if (e == o || e == EXEC_OUTPUT_INHERIT) +if ((e == o || e == EXEC_OUTPUT_INHERIT) +e != EXEC_OUTPUT_FILE) return dup2(STDOUT_FILENO, fileno) 0 ? -errno : fileno; o = e; @@ -444,6 +449,9 @@ static int setup_output(Unit *unit, const ExecContext *context, int fileno, int switch (o) { +case EXEC_OUTPUT_FILE: +return open_file_as(O_WRONLY|O_CREAT|O_APPEND, fileno == STDOUT_FILENO ? context-std_output_file : context-std_error_file, fileno); + case EXEC_OUTPUT_NULL: return open_null_as(O_WRONLY, fileno); @@ -1967,6 +1975,11 @@ void exec_context_done(ExecContext *c) { free(c-root_directory); c-root_directory = NULL; +free(c-std_output_file); +c-std_output_file = NULL; +free(c-std_error_file); +c-std_error_file = NULL; + free(c-tty_path); c-tty_path = NULL; @@ -2933,7 +2946,8 @@ static const char* const exec_output_table[_EXEC_OUTPUT_MAX] = { [EXEC_OUTPUT_KMSG_AND_CONSOLE] = kmsg+console, [EXEC_OUTPUT_JOURNAL] = journal, [EXEC_OUTPUT_JOURNAL_AND_CONSOLE] = journal+console, -[EXEC_OUTPUT_SOCKET] = socket +[EXEC_OUTPUT_SOCKET] = socket, +[EXEC_OUTPUT_FILE] = file }; DEFINE_STRING_TABLE_LOOKUP(exec_output, ExecOutput); diff --git a/src/core/execute.h b/src/core/execute.h index f5d5c1d..327d711 100644 --- a/src/core/execute.h +++ b/src/core/execute.h @@ -59,6 +59,7 @@ typedef enum ExecOutput { EXEC_OUTPUT_JOURNAL, EXEC_OUTPUT_JOURNAL_AND_CONSOLE, EXEC_OUTPUT_SOCKET, +EXEC_OUTPUT_FILE, _EXEC_OUTPUT_MAX, _EXEC_OUTPUT_INVALID = -1 } ExecOutput; @@ -108,7 +109,9 @@ struct ExecContext { ExecInput std_input; ExecOutput std_output; +char *std_output_file; ExecOutput std_error; +char *std_error_file; nsec_t timer_slack_nsec; diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index 66c9145..fbcaa95 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -35,7 +35,9 @@ $1.Environment, config_parse_environ, 0, $1.EnvironmentFile, config_parse_unit_env_file, 0, offsetof($1, exec_context.environment_files) $1.StandardInput,config_parse_input, 0, offsetof($1, exec_context.std_input) $1.StandardOutput, config_parse_output,0, offsetof($1, exec_context.std_output) +$1.StandardOutputFile, config_parse_string,0, offsetof($1, exec_context.std_output_file) $1.StandardError,config_parse_output,0, offsetof($1, exec_context.std_error) +$1.StandardErrorFile,config_parse_string,0, offsetof($1, exec_context.std_error_file) $1.TTYPath, config_parse_unit_path_printf, 0, offsetof($1, exec_context.tty_path)
[systemd-devel] How can I map PID between host and container?
Hello, I'm looking for a proper way what method to map PID between host and container. In case of systemctl, if I know pid in container(let's call this pid_c) then I can find the pid in sight of host(let's call this pid_h) by using systemctl -M {container} pid_c in host shell. But I can not find pid_c when I know pid_h by using systemctl status pid_h. The former seems possible by parsing machine cgroup. In the latter case, can we also find the pid_c? And is there any other method to map between those? For example, when if I use lxc then how I find each pid? (lxc-ps?) According to my search, namespace can give me some of hints about this. I could not find more detail. Is there any proper libs or tools for this? Thanks, WaLyong ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [RFC] core: introduce ExitOnIdle= and ExitOnIdleSec=
If a service does not consume CPU during some time(can be configured by ExitOnIdleSec=) and set to stopped on idle state(ExitOnIdle=), the service will be stopped. This can be useful if the service provides some of activation methods. --- src/core/load-fragment-gperf.gperf.m4 | 2 + src/core/service.c| 97 +++ src/core/service.h| 5 ++ src/core/unit.h | 1 + 4 files changed, 105 insertions(+) diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index 5305984..60d573e 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -229,6 +229,8 @@ Service.BusName, config_parse_bus_name, 0, Service.FileDescriptorStoreMax, config_parse_unsigned, 0, offsetof(Service, n_fd_store_max) Service.NotifyAccess,config_parse_notify_access, 0, offsetof(Service, notify_access) Service.Sockets, config_parse_service_sockets, 0, 0 +Service.ExitOnIdle, config_parse_bool, 0, offsetof(Service, exit_on_idle) +Service.ExitOnIdleSec, config_parse_sec, 0, offsetof(Service, exit_on_idle_usec) m4_ifdef(`ENABLE_KDBUS', `Service.BusPolicy, config_parse_bus_endpoint_policy, 0, offsetof(Service, exec_context)', `Service.BusPolicy, config_parse_warn_compat, DISABLED_EXPERIMENTAL, 0') diff --git a/src/core/service.c b/src/core/service.c index fa818fc..c8752ae 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -91,6 +91,7 @@ static const UnitActiveState state_translation_table_idle[_SERVICE_STATE_MAX] = static int service_dispatch_io(sd_event_source *source, int fd, uint32_t events, void *userdata); static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata); static int service_dispatch_watchdog(sd_event_source *source, usec_t usec, void *userdata); +static int service_dispatch_exit_on_idle_timer(sd_event_source *source, usec_t usec, void *userdata); static void service_enter_signal(Service *s, ServiceState state, ServiceResult f); static void service_enter_reload_by_notify(Service *s); @@ -108,6 +109,8 @@ static void service_init(Unit *u) { s-socket_fd = -1; s-bus_endpoint_fd = -1; s-guess_main_pid = true; +s-exit_on_idle = false; +s-exit_on_idle_usec = 0; RATELIMIT_INIT(s-start_limit, u-manager-default_start_limit_interval, u-manager-default_start_limit_burst); @@ -279,6 +282,56 @@ static void service_release_resources(Unit *u) { assert(s-n_fd_store == 0); } +static void service_stop_exit_on_idle_timer(Service *s) { +assert(s); + +s-exit_on_idle_event_source = sd_event_source_unref(s-exit_on_idle_event_source); +s-exit_on_idle_timestamp = DUAL_TIMESTAMP_NULL; +} + +static void service_start_exit_on_idle_timer(Service *s) { +int r; + +assert(s); + +if (s-exit_on_idle_usec = 0) +return; + +if (s-exit_on_idle_event_source) { +r = sd_event_source_set_time(s-exit_on_idle_event_source, s-exit_on_idle_timestamp.monotonic + s-exit_on_idle_usec); +if (r 0) { +log_unit_warning(UNIT(s)-id, %s failed to reset exit-on-idle timer: %s, UNIT(s)-id, strerror(-r)); +return; +} + +r = sd_event_source_set_enabled(s-exit_on_idle_event_source, SD_EVENT_ON); +} else { +r = sd_event_add_time( +UNIT(s)-manager-event, +s-exit_on_idle_event_source, +CLOCK_MONOTONIC, +s-exit_on_idle_timestamp.monotonic + s-exit_on_idle_usec, 0, +service_dispatch_exit_on_idle_timer, s); +if (r 0) { +log_unit_warning(UNIT(s)-id, %s failed to add exit-on-idle timer: %s, UNIT(s)-id, strerror(-r)); +return; +} + +r = sd_event_source_set_priority(s-exit_on_idle_event_source, SD_EVENT_PRIORITY_IDLE); +} + +if (r 0) +log_unit_warning(UNIT(s)-id, %s failed to install exit-on-idle timer: %s, UNIT(s)-id, strerror(-r)); +return; +} + +static void service_reset_exit_on_idle_timer(Service *s) { +assert(s); + +dual_timestamp_get(s-exit_on_idle_timestamp); +service_start_exit_on_idle_timer(s); +} + static void service_done(Unit *u) { Service *s = SERVICE(u); @@ -518,6 +571,7 @@ static void
Re: [systemd-devel] [RFC] core: introduce ExitOnIdle= and ExitOnIdleSec=
On 04/21/2015 12:10 AM, Lennart Poettering wrote: On Mon, 20.04.15 23:56, WaLyong Cho (walyong@samsung.com) wrote: If a service does not consume CPU during some time(can be configured by ExitOnIdleSec=) and set to stopped on idle state(ExitOnIdle=), the service will be stopped. This can be useful if the service provides some of activation methods. Hmm, I am not convinced this would be a good idea, sorry. The crux of the issue is that it is really hard to detect from the outside if a daemon is really idle. Only the daemon itself knows whether it is truly idle or not. I mean, it could just be waiting for some timer to elapse, or some other external event. I doubt this is really useful unless you have really really simple daemons that purely react on client requests and nothing else, and you know the codebase and that it is OK to terminate the daemon just because its CPU usage is zero. But if you know the codebase that well it would probably be a better idea to just add support for exit-on-idle directly to the daemon in question. That's why I sent with [RFC] prefix. :) Thanks for reply. WaLyong ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] regarding to cgroup siblings mask
On 2015년 04월 09일 01:48, Lennart Poettering wrote: On Tue, 24.03.15 20:29, WaLyong Cho (walyong@samsung.com) wrote: Hi, In recent systemd(from some month ago), when a unit has a mask for cpu or blockio or memory, this mask is also propagated to siblings by unit_get_target_mask(). According to some of comments, it seems intentional. Could anyone explain why? I added this after talking to Tejun. It's basically what the kernel will effectively do in sane behaviour mode too. Basically, the kernel really wants to avoid having to compare individual processes against groups, because behaviour is unclear then. They want to comapre groups against groups and processes against processes, but not groups against processes, since in many cases behaviour is very unclear then. To avoid the ambighities this creates entirely the answer is to not allow this, and hence always propagate all controller memberships not only towards the root, but also sideways. OK, understood but I'm not sure the compare group properties came under for all of cgroup subsystem. In case of CPUShares=, BlockIOWeight= such like take weight as value, should be. But in case of CPUQuota=, MemoryLimit=, it just a problems of own. Those are not racing with other groups. So for this kind of properties do not need to be propagated to siblings. I'm not sure this make sense. But if yes, below patch will only propagate proportional or relative properties. http://lists.freedesktop.org/archives/systemd-devel/2015-March/029885.html Thanks, WaLyong ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [RFC] activate on DBus signal
On 2015년 04월 09일 02:05, Lennart Poettering wrote: On Mon, 23.03.15 17:54, WaLyong Cho (walyong@samsung.com) wrote: Hi, Now, I'm looking for a method to a service be activated on special DBus signal. If a process is running for waiting some of DBus signal this can be useful. I already told with Simon in DBus mailing list. see this thread: http://lists.freedesktop.org/archives/dbus/2015-March/016607.html Simon said: If it did, there are some nasty ordering constraints - I certainly wouldn't want to have to delay delivery of a broadcast until all interested services had started up! - so I don't think adding this feature would be a good idea. How about also support for DBus signal? Hmm, so this has come up before, but this is really nasty to support, and I am not convinced we really want this. First of all, in a kdbus world this would require kernel support, so that the kernel will listen and queue messages on behalf of userspace, and that would be quite a major change... In general, so far activation was limited to *explicit* messages sent to the service in question, services would never be activated as possibly unintended side-effect of unrelated broadcast messages, and that's a really good property... Then, make systemd to monitor DBus. And if a matched signal was sent, activate the service. Well, it's not that simple, we'd also have to queue the signal, and all following messages, and pass that on to the activated service... And that's pretty nasty. It's already pretty nasty for the current logic but it would be even more complex with a match logic... Is sd_bus_add_match() useful on here? I thought about... Add option for subscribe signal as SubscribeSignal= and can take option such like SubscribeSignal=path=/org/freedesktop/systemd1 interface=org.freedesktop.systemd1.Manager member=Subscribe. Then when the unit(busname seems to be suit but the busname is only supported for kdbus. So I'm not sure. anyway) is loaded, call the sd_bus_add_match() with the parsed strv and register its callback. To transport this missed signal(for who want to listen), another option will be required to specify method call what will be sent with missed signal. Because we really not wants duplicated signal is broadcasted. Assume the option is SubscribeCallback= and can take like SubscribeCallback=path=/foo/bar/waldo interface=foo.bar.waldo.quux member=missedsignal. On the callback(what is called by sd_bus_match()), will send a method call to the specified address with a argument for missed signal contents. I know, this is very strange and seems not cool. And maybe the activation will really slow. But seems not impossible. But, ahead, even if you agree this is possible, those option should be controlled by other unit(not service). busname seems to be suit but I'm not sure the busname unit can joint with currently used DBus1. Thanks, WaLyong ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] regarding to cgroup siblings mask
On 03/31/2015 05:13 AM, David Timothy Strauss wrote: On Fri, Mar 27, 2015 at 7:56 PM, WaLyong Cho walyong@gmail.com wrote: Hmm, it seems not. When I added MemoryLimit= option to just one service, cgroups for every unit were generated on memory cgroup. It looks like memory_limit and cpu_quota_per_sec_usec both have this potential issue. The other four controllers managed this way are clearly proportional (using weights or shares). Then, is this patch able to be a solution? http://lists.freedesktop.org/archives/systemd-devel/2015-March/029885.html ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH] cgroup: propagate cgroup mask only for proportional properties
Some of cgroup properties does not affect to sibling cgroups. CPUShares and BlockIOWeight are only needed to be propagated. --- src/core/cgroup.c | 29 - src/core/cgroup.h | 2 ++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 6b8abb4..b4b9678 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -458,6 +458,23 @@ void cgroup_context_apply(CGroupContext *c, CGroupControllerMask mask, const cha } } +CGroupControllerMask cgroup_context_get_proportional_mask(CGroupContext *c) { +CGroupControllerMask mask = 0; + +/* Get only proportional mask */ + +if (c-cpu_shares != (unsigned long) -1 || +c-startup_cpu_shares != (unsigned long) -1) +mask |= CGROUP_CPU; + +if (c-blockio_weight != (unsigned long) -1 || +c-startup_blockio_weight != (unsigned long) -1 || +c-blockio_device_weights) +mask |= CGROUP_BLKIO; + +return mask; +} + CGroupControllerMask cgroup_context_get_mask(CGroupContext *c) { CGroupControllerMask mask = 0; @@ -487,6 +504,16 @@ CGroupControllerMask cgroup_context_get_mask(CGroupContext *c) { return mask; } +CGroupControllerMask unit_get_cgroup_proportional_mask(Unit *u) { +CGroupContext *c; + +c = unit_get_cgroup_context(u); +if (!c) +return 0; + +return cgroup_context_get_proportional_mask(c); +} + CGroupControllerMask unit_get_cgroup_mask(Unit *u) { CGroupContext *c; @@ -531,7 +558,7 @@ CGroupControllerMask unit_get_members_mask(Unit *u) { continue; u-cgroup_members_mask |= -unit_get_cgroup_mask(member) | +unit_get_cgroup_proportional_mask(member) | unit_get_members_mask(member); } } diff --git a/src/core/cgroup.h b/src/core/cgroup.h index 869ddae..2371158 100644 --- a/src/core/cgroup.h +++ b/src/core/cgroup.h @@ -98,12 +98,14 @@ void cgroup_context_done(CGroupContext *c); void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix); void cgroup_context_apply(CGroupContext *c, CGroupControllerMask mask, const char *path, ManagerState state); +CGroupControllerMask cgroup_context_get_proportional_mask(CGroupContext *c); CGroupControllerMask cgroup_context_get_mask(CGroupContext *c); void cgroup_context_free_device_allow(CGroupContext *c, CGroupDeviceAllow *a); void cgroup_context_free_blockio_device_weight(CGroupContext *c, CGroupBlockIODeviceWeight *w); void cgroup_context_free_blockio_device_bandwidth(CGroupContext *c, CGroupBlockIODeviceBandwidth *b); +CGroupControllerMask unit_get_cgroup_proportional_mask(Unit *u); CGroupControllerMask unit_get_cgroup_mask(Unit *u); CGroupControllerMask unit_get_siblings_mask(Unit *u); CGroupControllerMask unit_get_members_mask(Unit *u); -- 1.9.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] regarding to cgroup siblings mask
On 03/28/2015 09:25 AM, David Timothy Strauss wrote: On Thu, Mar 26, 2015 at 7:33 PM, WaLyong Cho walyong@samsung.com wrote: Thanks, understood. But I think this propagation is needed only for taking weight argument such like CPUShares=weight, StartupCPUShares=weight, BlockIOWeight=weight, StartupBlockIOWeight=weight, BlockIODeviceWeight=device weight. For example, I don't think MemoryLimit= is not option of proportional. It just only limit of its cgroup and does not race with other cgroup. If I'm right, we need to modify unit_get_target_mask() to get only mask for proportional properties. I'm pretty sure we already do that. If not, it's a bug. Hmm, it seems not. When I added MemoryLimit= option to just one service, cgroups for every unit were generated on memory cgroup. ___ 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
Re: [systemd-devel] regarding to cgroup siblings mask
On 03/27/2015 05:33 AM, David Timothy Strauss wrote: On Tue, Mar 24, 2015 at 4:29 AM, WaLyong Cho walyong@samsung.com wrote: Could anyone explain why? An admin using CPUShares= or a similar proportional CGroup controller probably assumes that setting the shares to twice the default (for example) increases the relative proportion of resources for that unit. However, that is only true if other units competing for that resource have the same controller(s) enabled so that the kernel knows to balance the resources accordingly. The code in systemd ensures that if any unit uses a proportional CGroups controller in a slice, all other units in that same slice enable that controller as well, usually with the default proportions. Thanks, understood. But I think this propagation is needed only for taking weight argument such like CPUShares=weight, StartupCPUShares=weight, BlockIOWeight=weight, StartupBlockIOWeight=weight, BlockIODeviceWeight=device weight. For example, I don't think MemoryLimit= is not option of proportional. It just only limit of its cgroup and does not race with other cgroup. If I'm right, we need to modify unit_get_target_mask() to get only mask for proportional properties. unit_get_target_mask() is part of an optimization I added so that initializing CGroups controllers for a given unit doesn't require iterating through every other unit in a slice to figure out the necessary controllers. It provides a bitmask indicating the controllers in use by its siblings so the unit can enable, say, CPUShares= if one of its siblings is doing so. ___ 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] regarding to cgroup siblings mask
Hi, In recent systemd(from some month ago), when a unit has a mask for cpu or blockio or memory, this mask is also propagated to siblings by unit_get_target_mask(). According to some of comments, it seems intentional. Could anyone explain why? In our system, some of service have MemoryLimit= options. By this options, all of other services also create its own cgroup in memory. In mobile system(or some of other embedded system), this can be heavy load. If this can be configurable, how about add a configuration for cgroup mask propagation to siblings? Thanks, WaLyong ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [RFC] activate on DBus signal
Hi, Now, I'm looking for a method to a service be activated on special DBus signal. If a process is running for waiting some of DBus signal this can be useful. I already told with Simon in DBus mailing list. see this thread: http://lists.freedesktop.org/archives/dbus/2015-March/016607.html Simon said: If it did, there are some nasty ordering constraints - I certainly wouldn't want to have to delay delivery of a broadcast until all interested services had started up! - so I don't think adding this feature would be a good idea. How about also support for DBus signal? My idea is... Add new configuration directory. (e.g. /etc/systemd/active-by-signal) And service can install its configuration file on there with below format. (Please don't care of its detail. It just a example.) signal listen dest=org.freedesktop.DBus listen interface=org.freedesktop.DBus.Properties listen object=/org/freedesktop/systemd1/unit/systemd_2dlogind_2eservice listen member=PropertiesChanged /signal (I thought more appropriate .xml format better than .ini to define multiple signal.) Then, make systemd to monitor DBus. And if a matched signal was sent, activate the service. Until here, looks not much difficult. But the origin signal was already sent. So if the service has its own bus then send a method call for missed signal. Of course, the activated service has to handle those method call. This method can be seemed does not make sense. But I think, this facility obviously useful. Thank you in advance for comment. WaLyong ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] Needs help for on charging activation
Hi, I want to find best solution on our case. Our product is mobile device. But I don't think that is only problem of mobile device. That also can be problem of laptop. So, please comment to me. We have some of services are always running after system is started up as default. They don't need to be running always. They are just needed only charger is plugged in. So I thought lets only active them when only charger is plugged in. I thought two methods. method 1: Charger also can be detected by udev. So udev hardware activation can be used. I wrote below udev rules. SUBSYSTEM==power_supply, ENV{POWER_SUPPLY_CHARGE_NOW}==1, TAG+=systemd, ENV{SYSTEMD_WANTS}+=foo.service It looked working well. foo.service is only activated when charger was plugged in. But I have some of problems with hardware activation. I want to be stopped foo.service when the charger is plugged out. As I know, this is impossible with udev hardware activation. To do this, foo.service have to determine the charger state itself and if the charger is plugged out, it have to stop itself. And it is working only at the first time. After foo.service was activated, I stopped foo.service by systemctl stop foo.service. And plug out and plug in the charger again. Then foo.service was not activated. (Is it normal? I did not try to find the reason. If you say it's a problem, then I will try to find.) method 2: We have another device daemon. Let's call that as deviced and its service name is deviced.service. deviced know about plug in/out of the charger. So, I made a new charging.target. foo.service have Wants= dependency for charging.target. (Installed on charging.target.wants.) And I added BindsTo=charging.target to foo.service. Then foo.service is activated well when the charging.target is entered to active state. And also deactivated when charging.target was deactivated. In this method, there are limitations what some of other daemon is needed and new charging.target is needed. Is there any more good way for this? I want to find best appropriate way. Thank you in advance for comment. WaLyong ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH] bootchart: display each CPU utilization/wait
--- src/bootchart/bootchart.c| 38 +- src/bootchart/bootchart.conf | 1 + src/bootchart/bootchart.h| 1 + src/bootchart/svg.c | 65 +--- 4 files changed, 70 insertions(+), 35 deletions(-) diff --git a/src/bootchart/bootchart.c b/src/bootchart/bootchart.c index b49e2c9..2c2b329 100644 --- a/src/bootchart/bootchart.c +++ b/src/bootchart/bootchart.c @@ -87,6 +87,7 @@ bool arg_filter = true; bool arg_show_cmdline = false; bool arg_show_cgroup = false; bool arg_pss = false; +bool arg_percpu = false; int samples; int arg_samples_len = DEFAULT_SAMPLES_LEN; /* we record len+1 (1 start sample) */ double arg_hz = DEFAULT_HZ; @@ -122,6 +123,7 @@ static void parse_conf(void) { { Bootchart, ScaleX, config_parse_double, 0, arg_scale_x }, { Bootchart, ScaleY, config_parse_double, 0, arg_scale_y }, { Bootchart, ControlGroup, config_parse_bool, 0, arg_show_cgroup }, +{ Bootchart, PerCPU, config_parse_bool, 0, arg_percpu }, { NULL, NULL, NULL, 0, NULL } }; @@ -151,6 +153,7 @@ static void help(void) { -F, --no-filter Disable filtering of unimportant or ephemeral processes\n -C, --cmdline Display full command lines with arguments\n -c, --control-group Display process control group\n + --per-cpu Draw each CPU utilization and wait bar also\n -h, --helpDisplay this message\n\n See bootchart.conf for more information.\n, program_invocation_short_name, @@ -163,20 +166,26 @@ static void help(void) { } static int parse_argv(int argc, char *argv[]) { + +enum { +ARG_PERCPU, +}; + static const struct option options[] = { -{rel, no_argument,NULL, 'r'}, -{freq, required_argument, NULL, 'f'}, -{samples, required_argument, NULL, 'n'}, -{pss, no_argument,NULL, 'p'}, -{output,required_argument, NULL, 'o'}, -{init, required_argument, NULL, 'i'}, -{no-filter, no_argument,NULL, 'F'}, -{cmdline, no_argument,NULL, 'C'}, -{control-group, no_argument,NULL, 'c'}, -{help, no_argument,NULL, 'h'}, -{scale-x, required_argument, NULL, 'x'}, -{scale-y, required_argument, NULL, 'y'}, -{entropy, no_argument,NULL, 'e'}, +{rel, no_argument,NULL, 'r' }, +{freq, required_argument, NULL, 'f' }, +{samples, required_argument, NULL, 'n' }, +{pss, no_argument,NULL, 'p' }, +{output,required_argument, NULL, 'o' }, +{init, required_argument, NULL, 'i' }, +{no-filter, no_argument,NULL, 'F' }, +{cmdline, no_argument,NULL, 'C' }, +{control-group, no_argument,NULL, 'c' }, +{help, no_argument,NULL, 'h' }, +{scale-x, required_argument, NULL, 'x' }, +{scale-y, required_argument, NULL, 'y' }, +{entropy, no_argument,NULL, 'e' }, +{per-cpu, no_argument,NULL, ARG_PERCPU}, {} }; int c, r; @@ -237,6 +246,9 @@ static int parse_argv(int argc, char *argv[]) { case 'e': arg_entropy = true; break; +case ARG_PERCPU: +arg_percpu = true; +break; case 'h': help(); return 0; diff --git a/src/bootchart/bootchart.conf b/src/bootchart/bootchart.conf index c73328f..2d7cb61 100644 --- a/src/bootchart/bootchart.conf +++ b/src/bootchart/bootchart.conf @@ -22,3 +22,4 @@ #ScaleX=100 #ScaleY=20 #ControlGroup=no +#PerCPU=no diff --git a/src/bootchart/bootchart.h b/src/bootchart/bootchart.h index 2c37835..26de0dd 100644 --- a/src/bootchart/bootchart.h +++ b/src/bootchart/bootchart.h @@ -118,6 +118,7 @@ extern bool arg_show_cmdline; extern bool arg_show_cgroup; extern bool arg_pss; extern bool arg_entropy; +extern bool arg_percpu; extern bool initcall; extern int samples; extern int cpus; diff --git a/src/bootchart/svg.c b/src/bootchart/svg.c index e5569e1..e770625 100644 ---
[systemd-devel] [PATCH] unit: update unit dropin paths and time when dropin file is written.
If a unit is set property by systemctl set-property, a new dropin file is generated. But the unit's dropin_paths and dropin_mtime are not updated. So the unit is shown as need daemon reload. Update unit dropin_paths and dropin_mtime also when dropin file is written. --- src/core/unit.c | 21 +++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/core/unit.c b/src/core/unit.c index 43280ec..b3b0892 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -3272,7 +3272,7 @@ static int unit_drop_in_file(Unit *u, int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) { -_cleanup_free_ char *dir = NULL; +_cleanup_free_ char *dir = NULL, *p = NULL, *q = NULL; int r; assert(u); @@ -3284,7 +3284,24 @@ int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, co if (r 0) return r; -return write_drop_in(dir, u-id, 50, name, data); +r = write_drop_in(dir, u-id, 50, name, data); +if (r 0) +return r; + +r = drop_in_file(dir, u-id, 50, name, p, q); +if (r 0) +return r; + +r = strv_extend(u-dropin_paths, q); +if (r 0) +return r; + +strv_sort(u-dropin_paths); +strv_uniq(u-dropin_paths); + +u-dropin_mtime = now(CLOCK_REALTIME); + +return 0; } int unit_write_drop_in_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) { -- 1.9.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [PATCH v7] run: introduce timer support option
On 12/10/2014 02:25 AM, Lennart Poettering wrote: On Tue, 09.12.14 16:07, WaLyong Cho (walyong@samsung.com) wrote: Support timer options --on-active=, --on-boot=, --on-startup=, --on-unit-active=, --on-unit-inactive=, --on-calendar=. Each options corresponding with OnActiveSec=, OnBootSec=, OnStartupSec=, OnUnitActiveSec=, OnUnitInactiveSec=, OnCalendar= of timer respectively. And OnCalendar= and WakeSystem= supported by --timer-property= option like --property= of systemd-run. Looks good! Applied! Thanks! Do you have plan to crontab-generator? WaLyong Lennart ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH v5 1/4] bus: StartTransientUnit can have aux unit
--- src/core/dbus-manager.c | 98 +++-- 1 file changed, 86 insertions(+), 12 deletions(-) diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 0994d7b..5fe06f9 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -615,6 +615,90 @@ static int method_set_unit_properties(sd_bus *bus, sd_bus_message *message, void return bus_unit_method_set_properties(bus, message, u, error); } +static int transient_unit_from_message( +Manager *m, +sd_bus_message *message, +const char *name, +Unit **unit, +sd_bus_error *error) { + +Unit *u; +int r; + +assert(m); +assert(message); +assert(name); + +r = manager_load_unit(m, name, NULL, error, u); +if (r 0) +return r; + +if (u-load_state != UNIT_NOT_FOUND || +set_size(u-dependencies[UNIT_REFERENCED_BY]) 0) +return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, Unit %s already exists., name); + +/* OK, the unit failed to load and is unreferenced, now let's + * fill in the transient data instead */ +r = unit_make_transient(u); +if (r 0) +return r; + +/* Set our properties */ +r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error); +if (r 0) +return r; + +*unit = u; + +return 0; +} + +static int transient_aux_units_from_message( +Manager *m, +sd_bus_message *message, +sd_bus_error *error) { + +Unit *u; +char *name = NULL; +int r; + +assert(m); +assert(message); + +r = sd_bus_message_enter_container(message, 'a', (sa(sv))); +if (r 0) +return r; + +while ((r = sd_bus_message_enter_container(message, 'r', sa(sv))) 0) { +if (r = 0) +return r; + +r = sd_bus_message_read(message, s, name); +if (r 0) +return r; + +r = transient_unit_from_message(m, message, name, u, error); +if (r 0 r != -EEXIST) +return r; + +r = unit_load(u); +if (r 0) +return r; + +r = sd_bus_message_exit_container(message); +if (r 0) +return r; +} +if (r 0) +return r; + +r = sd_bus_message_exit_container(message); +if (r 0) +return r; + +return 0; +} + static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { const char *name, *smode; Manager *m = userdata; @@ -652,21 +736,11 @@ static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, voi if (r 0) return r; -r = manager_load_unit(m, name, NULL, error, u); -if (r 0) -return r; - -if (u-load_state != UNIT_NOT_FOUND || set_size(u-dependencies[UNIT_REFERENCED_BY]) 0) -return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, Unit %s already exists., name); - -/* OK, the unit failed to load and is unreferenced, now let's - * fill in the transient data instead */ -r = unit_make_transient(u); +r = transient_unit_from_message(m, message, name, u, error); if (r 0) return r; -/* Set our properties */ -r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error); +r = transient_aux_units_from_message(m, message, error); if (r 0) return r; -- 1.9.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH v5 2/4] util: introduce new sec_to_stringa()
--- src/shared/time-util.c | 52 ++ src/shared/time-util.h | 1 + src/test/test-time.c | 20 +++ 3 files changed, 73 insertions(+) diff --git a/src/shared/time-util.c b/src/shared/time-util.c index d3404af..d94be7e 100644 --- a/src/shared/time-util.c +++ b/src/shared/time-util.c @@ -861,6 +861,58 @@ int parse_nsec(const char *t, nsec_t *nsec) { return 0; } +int sec_to_stringa(const char *t, usec_t usec, const char **time) { +static const struct { +const char *suffix; +usec_t usec; +} table[] = { +{ seconds, USEC_PER_SEC }, +{ second, USEC_PER_SEC }, +{ sec, USEC_PER_SEC }, +{ s, USEC_PER_SEC }, +{ minutes, USEC_PER_MINUTE }, +{ minute, USEC_PER_MINUTE }, +{ min, USEC_PER_MINUTE }, +{ months, USEC_PER_MONTH }, +{ month, USEC_PER_MONTH }, +{ msec, USEC_PER_MSEC }, +{ ms, USEC_PER_MSEC }, +{ m, USEC_PER_MINUTE }, +{ hours, USEC_PER_HOUR }, +{ hour, USEC_PER_HOUR }, +{ hr, USEC_PER_HOUR }, +{ h, USEC_PER_HOUR }, +{ days, USEC_PER_DAY }, +{ day, USEC_PER_DAY }, +{ d, USEC_PER_DAY }, +{ weeks, USEC_PER_WEEK }, +{ week, USEC_PER_WEEK }, +{ w, USEC_PER_WEEK }, +{ years, USEC_PER_YEAR }, +{ year, USEC_PER_YEAR }, +{ y, USEC_PER_YEAR }, +{ usec, 1ULL }, +{ us, 1ULL }, +{ , USEC_PER_SEC }, /* default is sec */ +}; + +char *s = NULL; +unsigned i; + +for (i = 0; i ELEMENTSOF(table); i++) { +if (streq(t, table[i].suffix)) { +if (asprintf(s, %g%s, ((double) usec)/table[i].usec, t) 0) +return -ENOMEM; + +*time = s; + +return 0; +} +} + +return -EINVAL; +} + bool ntp_synced(void) { struct timex txc = {}; diff --git a/src/shared/time-util.h b/src/shared/time-util.h index b55a660..7d0eff9 100644 --- a/src/shared/time-util.h +++ b/src/shared/time-util.h @@ -100,6 +100,7 @@ int parse_timestamp(const char *t, usec_t *usec); int parse_sec(const char *t, usec_t *usec); int parse_nsec(const char *t, nsec_t *nsec); +int sec_to_stringa(const char *t, usec_t usec, const char **time); bool ntp_synced(void); diff --git a/src/test/test-time.c b/src/test/test-time.c index 8cfc4cc..b57639a 100644 --- a/src/test/test-time.c +++ b/src/test/test-time.c @@ -86,6 +86,25 @@ static void test_parse_nsec(void) { assert_se(parse_nsec(.s , u) 0); } +static void test_sec_to_stringa(void) { +_cleanup_free_ const char *time1 = NULL, *time2 = NULL, *time3 = NULL, *time4 = NULL, *time5 = NULL; + +assert_se(sec_to_stringa(, 27314123, time1) = 0); +puts(time1); + +assert_se(sec_to_stringa(sec, 27314123, time2) = 0); +puts(time2); + +assert_se(sec_to_stringa(ms, 27314123, time3) = 0); +puts(time3); + +assert_se(sec_to_stringa(days, 27314123, time4) = 0); +puts(time4); + +assert_se(sec_to_stringa(years, 27314123, time5) = 0); +puts(time5); +} + static void test_format_timespan_one(usec_t x, usec_t accuracy) { char *r; char l[FORMAT_TIMESPAN_MAX]; @@ -156,6 +175,7 @@ static void test_get_timezones(void) { int main(int argc, char *argv[]) { test_parse_sec(); test_parse_nsec(); +test_sec_to_stringa(); test_format_timespan(1); test_format_timespan(USEC_PER_MSEC); test_format_timespan(USEC_PER_SEC); -- 1.9.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH v5 4/4] run: introduce timer support option
Support timer options --on-active=, --on-boot=, --on-startup=, --on-unit-active=, --on-unit-inactive=, --on-calendar=. Each options corresponding with OnActiveSec=, OnBootSec=, OnStartupSec=, OnUnitActiveSec=, OnUnitInactiveSec=, OnCalendar= of timer respectively. And OnCalendar= and WakeSystem= supported by --timer-property= option like --property= of systemd-run. --- man/systemd-run.xml | 64 src/libsystemd/sd-bus/bus-util.c | 14 +- src/run/run.c| 619 +++ 3 files changed, 580 insertions(+), 117 deletions(-) diff --git a/man/systemd-run.xml b/man/systemd-run.xml index 28a9878..30e7783 100644 --- a/man/systemd-run.xml +++ b/man/systemd-run.xml @@ -210,6 +210,54 @@ along with systemd; If not, see http://www.gnu.org/licenses/. xi:include href=user-system-options.xml xpointer=host / xi:include href=user-system-options.xml xpointer=machine / + varlistentry +termoption--on-active=/option/term +termoption--on-boot=/option/term +termoption--on-startup=/option/term +termoption--on-unit-active=/option/term +termoption--on-unit-inactive=/option/term + +listitemparaDefines monotonic timers relative to different +starting points. Also see varnameOnActiveSec=/varname, +varnameOnBootSec=/varname, +varnameOnStartupSec=/varname, +varnameOnUnitActiveSec=/varname and +varnameOnUnitInactiveSec=/varname in + citerefentryrefentrytitlesystemd.timer/refentrytitlemanvolnum5/manvolnum/citerefentry. This +option has no effect in conjunction with +option--scope/option./para +/listitem + /varlistentry + + varlistentry +termoption--on-calendar=/option/term + +listitemparaDefines realtime (i.e. wallclock) timers with +calendar event expressions. Also see +varnameOnCalendar=/varname in + citerefentryrefentrytitlesystemd.timer/refentrytitlemanvolnum5/manvolnum/citerefentry. This +option has no effect in conjunction with +option--scope/option./para +/listitem + /varlistentry + + varlistentry +termoption--timer-property=/option/term + +listitemparaSets a timer unit property for the timer unit +that is created. It is similar with +option--property/option but only for created timer +unit. This option only has effect in conjunction with +option--on-active=/option, option--on-boot=/option, +option--on-startup=/option, +option--on-unit-active=/option, +option--on-unit-inactive=/option, +option--on-calendar=/option. This takes an assignment in +the same format as + citerefentryrefentrytitlesystemctl/refentrytitlemanvolnum1/manvolnum/citerefentry's +commandset-property/command command./para /listitem + /varlistentry + xi:include href=standard-options.xml xpointer=help / xi:include href=standard-options.xml xpointer=version / /variablelist @@ -250,6 +298,21 @@ Sep 08 07:37:21 bupkis env[19948]: BOOT_IMAGE=/vmlinuz-3.11.0-0.rc5.git6.2.fc20. property./para programlisting# systemd-run -p BlockIOWeight=10 updatedb/programlisting + +paraThe following command will touch a file after 10 seconds./para + +programlisting# date; systemd-run --on-active=30 --timer-property=AccuracySec=100ms /bin/touch /tmp/foo +Mon Dec 8 20:44:24 KST 2014 +Running as unit run-71.timer. +Will run as unit run-71.service. +# journalctl -b -u run-73.timer +-- Logs begin at Fri 2014-12-05 19:09:21 KST, end at Mon 2014-12-08 20:44:54 KST. -- +Dec 08 20:44:38 container systemd[1]: Starting /bin/touch /tmp/foo. +Dec 08 20:44:38 container systemd[1]: Started /bin/touch /tmp/foo. +# journalctl -b -u run-73.service +-- Logs begin at Fri 2014-12-05 19:09:21 KST, end at Mon 2014-12-08 20:44:54 KST. -- +Dec 08 20:44:48 container systemd[1]: Starting /bin/touch /tmp/foo... +Dec 08 20:44:48 container systemd[1]: Started /bin/touch /tmp/foo./programlisting /refsect1 refsect1 @@ -263,6 +326,7 @@ Sep 08 07:37:21 bupkis env[19948]: BOOT_IMAGE=/vmlinuz-3.11.0-0.rc5.git6.2.fc20. citerefentryrefentrytitlesystemd.slice/refentrytitlemanvolnum5/manvolnum/citerefentry, citerefentryrefentrytitlesystemd.exec/refentrytitlemanvolnum5/manvolnum/citerefentry, citerefentryrefentrytitlesystemd.resource-control/refentrytitlemanvolnum5/manvolnum/citerefentry, + citerefentryrefentrytitlesystemd.timer/refentrytitlemanvolnum5/manvolnum/citerefentry, citerefentryrefentrytitlemachinectl/refentrytitlemanvolnum1/manvolnum/citerefentry /para /refsect1 diff --git a/src/libsystemd/sd-bus/bus-util.c b/src/libsystemd/sd-bus/bus-util.c index bdaa449..0f1a89c 100644 --- a/src/libsystemd/sd-bus/bus-util.c +++ b/src/libsystemd/sd-bus/bus-util.c @@ -1372,7 +1372,8 @@ int bus_append_unit_property_assignment(sd_bus_message
[systemd-devel] [PATCH v5 2/4] util: introduce new sec_to_stringa()
--- src/shared/time-util.c | 63 ++ src/shared/time-util.h | 1 + src/test/test-time.c | 20 3 files changed, 84 insertions(+) diff --git a/src/shared/time-util.c b/src/shared/time-util.c index d3404af..a45341d 100644 --- a/src/shared/time-util.c +++ b/src/shared/time-util.c @@ -861,6 +861,69 @@ int parse_nsec(const char *t, nsec_t *nsec) { return 0; } +int sec_to_stringa(const char *t, usec_t usec, const char **time) { +static const struct { +const char *suffix; +usec_t usec; +} table[] = { +{ seconds, USEC_PER_SEC }, +{ second, USEC_PER_SEC }, +{ sec, USEC_PER_SEC }, +{ s, USEC_PER_SEC }, +{ minutes, USEC_PER_MINUTE }, +{ minute, USEC_PER_MINUTE }, +{ min, USEC_PER_MINUTE }, +{ months, USEC_PER_MONTH }, +{ month, USEC_PER_MONTH }, +{ msec, USEC_PER_MSEC }, +{ ms, USEC_PER_MSEC }, +{ m, USEC_PER_MINUTE }, +{ hours, USEC_PER_HOUR }, +{ hour, USEC_PER_HOUR }, +{ hr, USEC_PER_HOUR }, +{ h, USEC_PER_HOUR }, +{ days, USEC_PER_DAY }, +{ day, USEC_PER_DAY }, +{ d, USEC_PER_DAY }, +{ weeks, USEC_PER_WEEK }, +{ week, USEC_PER_WEEK }, +{ w, USEC_PER_WEEK }, +{ years, USEC_PER_YEAR }, +{ year, USEC_PER_YEAR }, +{ y, USEC_PER_YEAR }, +{ usec, 1ULL }, +{ us, 1ULL }, +{ , USEC_PER_SEC }, /* default is sec */ +}; + +char *s = NULL; +unsigned i; + +assert(time); + +if (!t) { +if (asprintf(s, %g, ((double) usec)/USEC_PER_SEC) 0) +return -ENOMEM; + +*time = s; + +return 0; +} + +for (i = 0; i ELEMENTSOF(table); i++) { +if (streq(t, table[i].suffix)) { +if (asprintf(s, %g%s, ((double) usec)/table[i].usec, t) 0) +return -ENOMEM; + +*time = s; + +return 0; +} +} + +return -EINVAL; +} + bool ntp_synced(void) { struct timex txc = {}; diff --git a/src/shared/time-util.h b/src/shared/time-util.h index b55a660..7d0eff9 100644 --- a/src/shared/time-util.h +++ b/src/shared/time-util.h @@ -100,6 +100,7 @@ int parse_timestamp(const char *t, usec_t *usec); int parse_sec(const char *t, usec_t *usec); int parse_nsec(const char *t, nsec_t *nsec); +int sec_to_stringa(const char *t, usec_t usec, const char **time); bool ntp_synced(void); diff --git a/src/test/test-time.c b/src/test/test-time.c index 8cfc4cc..09de8f0 100644 --- a/src/test/test-time.c +++ b/src/test/test-time.c @@ -86,6 +86,25 @@ static void test_parse_nsec(void) { assert_se(parse_nsec(.s , u) 0); } +static void test_sec_to_stringa(void) { +_cleanup_free_ const char *time1 = NULL, *time2 = NULL, *time3 = NULL, *time4 = NULL, *time5 = NULL; + +assert_se(sec_to_stringa(NULL, 27314123, time1) = 0); +puts(time1); + +assert_se(sec_to_stringa(sec, 27314123, time2) = 0); +puts(time2); + +assert_se(sec_to_stringa(ms, 27314123, time3) = 0); +puts(time3); + +assert_se(sec_to_stringa(days, 27314123, time4) = 0); +puts(time4); + +assert_se(sec_to_stringa(years, 27314123, time5) = 0); +puts(time5); +} + static void test_format_timespan_one(usec_t x, usec_t accuracy) { char *r; char l[FORMAT_TIMESPAN_MAX]; @@ -156,6 +175,7 @@ static void test_get_timezones(void) { int main(int argc, char *argv[]) { test_parse_sec(); test_parse_nsec(); +test_sec_to_stringa(); test_format_timespan(1); test_format_timespan(USEC_PER_MSEC); test_format_timespan(USEC_PER_SEC); -- 1.9.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [PATCH v5 2/4] util: introduce new sec_to_stringa()
On 12/08/2014 11:41 PM, Lennart Poettering wrote: On Mon, 08.12.14 21:18, WaLyong Cho (walyong@samsung.com) wrote: +int sec_to_stringa(const char *t, usec_t usec, const char **time) { +static const struct { +const char *suffix; +usec_t usec; +} table[] = { +{ seconds, USEC_PER_SEC }, +{ second, USEC_PER_SEC }, +{ sec, USEC_PER_SEC }, +{ s, USEC_PER_SEC }, +{ minutes, USEC_PER_MINUTE }, +{ minute, USEC_PER_MINUTE }, +{ min, USEC_PER_MINUTE }, +{ months, USEC_PER_MONTH }, +{ month, USEC_PER_MONTH }, +{ msec, USEC_PER_MSEC }, +{ ms, USEC_PER_MSEC }, +{ m, USEC_PER_MINUTE }, +{ hours, USEC_PER_HOUR }, +{ hour, USEC_PER_HOUR }, +{ hr, USEC_PER_HOUR }, +{ h, USEC_PER_HOUR }, +{ days, USEC_PER_DAY }, +{ day, USEC_PER_DAY }, +{ d, USEC_PER_DAY }, +{ weeks, USEC_PER_WEEK }, +{ week, USEC_PER_WEEK }, +{ w, USEC_PER_WEEK }, +{ years, USEC_PER_YEAR }, +{ year, USEC_PER_YEAR }, +{ y, USEC_PER_YEAR }, +{ usec, 1ULL }, +{ us, 1ULL }, +{ , USEC_PER_SEC }, /* default is sec */ +}; + +char *s = NULL; +unsigned i; + +for (i = 0; i ELEMENTSOF(table); i++) { +if (streq(t, table[i].suffix)) { +if (asprintf(s, %g%s, ((double) usec)/table[i].usec, t) 0) +return -ENOMEM; + +*time = s; + +return 0; +} +} + +return -EINVAL; +} Why this call? format_timespan() already does this, no? I didn't know that. I will send change. Thanks, WaLyong Lennart ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH v6 2/3] timer: timer can be a transient unit
--- src/core/dbus-timer.c | 143 ++ src/core/dbus-timer.h | 3 ++ src/core/timer.c | 4 ++ 3 files changed, 150 insertions(+) diff --git a/src/core/dbus-timer.c b/src/core/dbus-timer.c index f1f8c54..43e7852 100644 --- a/src/core/dbus-timer.c +++ b/src/core/dbus-timer.c @@ -24,6 +24,8 @@ #include dbus-unit.h #include dbus-timer.h #include bus-util.h +#include errno-list.h +#include strv.h static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, timer_result, TimerResult); @@ -183,3 +185,144 @@ const sd_bus_vtable bus_timer_vtable[] = { SD_BUS_PROPERTY(WakeSystem, b, bus_property_get_bool, offsetof(Timer, wake_system), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_VTABLE_END }; + +static int bus_timer_set_transient_property( +Timer *t, +const char *name, +sd_bus_message *message, +UnitSetPropertiesMode mode, +sd_bus_error *error) { + +int r; + +assert(t); +assert(name); +assert(message); + +if (STR_IN_SET(name, + OnActiveSec, + OnBootSec, + OnStartupSec, + OnUnitActiveSec, + OnUnitInactiveSec)) { + +TimerValue *v; +TimerBase b = _TIMER_BASE_INVALID; +usec_t u = 0; + +b = timer_base_from_string(name); +if (b 0) +return -EINVAL; + +r = sd_bus_message_read(message, t, u); +if (r 0) +return r; + +if (mode != UNIT_CHECK) { +char time[FORMAT_TIMESPAN_MAX]; + +unit_write_drop_in_private_format(UNIT(t), mode, name, %s=%s\n, name, format_timespan(time, sizeof(time), u, USEC_PER_MSEC)); + +v = new0(TimerValue, 1); +if (!v) +return -ENOMEM; + +v-base = b; +v-value = u; + +LIST_PREPEND(value, t-values, v); +} + +return 1; + +} else if (streq(name, OnCalendar)) { + +TimerValue *v; +CalendarSpec *c = NULL; +const char *str; + +r = sd_bus_message_read(message, s, str); +if (r 0) +return r; + +if (mode != UNIT_CHECK) { +r = calendar_spec_from_string(str, c); +if (r 0) +return r; + +unit_write_drop_in_private_format(UNIT(t), mode, name, %s=%s\n, name, str); + +v = new0(TimerValue, 1); +if (!v) { +if (c) +calendar_spec_free(c); +return -ENOMEM; +} + +v-base = TIMER_CALENDAR; +v-calendar_spec = c; + +LIST_PREPEND(value, t-values, v); +} + +return 1; + +} else if (streq(name, AccuracySec)) { + +usec_t u = 0; + +r = sd_bus_message_read(message, t, u); +if (r 0) +return r; + +if (mode != UNIT_CHECK) { +char time[FORMAT_TIMESPAN_MAX]; + +t-accuracy_usec = u; +unit_write_drop_in_private_format(UNIT(t), mode, name, %s=%s\n, name, format_timespan(time, sizeof(time), u, USEC_PER_MSEC)); +} + +return 1; + +} else if (streq(name, WakeSystem)) { + +int b; + +r = sd_bus_message_read(message, b, b); +if (r 0) +return r; + +if (mode != UNIT_CHECK) { +t-wake_system = b; +unit_write_drop_in_private_format(UNIT(t), mode, name, %s=%s\n, name, yes_no(t-wake_system)); +} + +return 1; + +} + +return 0; +} + +int bus_timer_set_property( +Unit *u, +const char *name, +sd_bus_message *message, +UnitSetPropertiesMode mode, +sd_bus_error *error) { + +Timer *t = TIMER(u); +int r; + +assert(t); +assert(name); +assert(message); + +if (u-transient u-load_state == UNIT_STUB) { +r = bus_timer_set_transient_property(t, name, message, mode, error); +if (r != 0) +return r; +} + +return 0; +} diff --git a/src/core/dbus-timer.h b/src/core/dbus-timer.h index
[systemd-devel] [PATCH v6 1/3] bus: StartTransientUnit can have aux unit
--- src/core/dbus-manager.c | 98 +++-- 1 file changed, 86 insertions(+), 12 deletions(-) diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 0994d7b..5fe06f9 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -615,6 +615,90 @@ static int method_set_unit_properties(sd_bus *bus, sd_bus_message *message, void return bus_unit_method_set_properties(bus, message, u, error); } +static int transient_unit_from_message( +Manager *m, +sd_bus_message *message, +const char *name, +Unit **unit, +sd_bus_error *error) { + +Unit *u; +int r; + +assert(m); +assert(message); +assert(name); + +r = manager_load_unit(m, name, NULL, error, u); +if (r 0) +return r; + +if (u-load_state != UNIT_NOT_FOUND || +set_size(u-dependencies[UNIT_REFERENCED_BY]) 0) +return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, Unit %s already exists., name); + +/* OK, the unit failed to load and is unreferenced, now let's + * fill in the transient data instead */ +r = unit_make_transient(u); +if (r 0) +return r; + +/* Set our properties */ +r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error); +if (r 0) +return r; + +*unit = u; + +return 0; +} + +static int transient_aux_units_from_message( +Manager *m, +sd_bus_message *message, +sd_bus_error *error) { + +Unit *u; +char *name = NULL; +int r; + +assert(m); +assert(message); + +r = sd_bus_message_enter_container(message, 'a', (sa(sv))); +if (r 0) +return r; + +while ((r = sd_bus_message_enter_container(message, 'r', sa(sv))) 0) { +if (r = 0) +return r; + +r = sd_bus_message_read(message, s, name); +if (r 0) +return r; + +r = transient_unit_from_message(m, message, name, u, error); +if (r 0 r != -EEXIST) +return r; + +r = unit_load(u); +if (r 0) +return r; + +r = sd_bus_message_exit_container(message); +if (r 0) +return r; +} +if (r 0) +return r; + +r = sd_bus_message_exit_container(message); +if (r 0) +return r; + +return 0; +} + static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { const char *name, *smode; Manager *m = userdata; @@ -652,21 +736,11 @@ static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, voi if (r 0) return r; -r = manager_load_unit(m, name, NULL, error, u); -if (r 0) -return r; - -if (u-load_state != UNIT_NOT_FOUND || set_size(u-dependencies[UNIT_REFERENCED_BY]) 0) -return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, Unit %s already exists., name); - -/* OK, the unit failed to load and is unreferenced, now let's - * fill in the transient data instead */ -r = unit_make_transient(u); +r = transient_unit_from_message(m, message, name, u, error); if (r 0) return r; -/* Set our properties */ -r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error); +r = transient_aux_units_from_message(m, message, error); if (r 0) return r; -- 1.9.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [RFC] [PATCH] core: avoid duplicate unit property set
On 12/09/2014 12:10 AM, Lennart Poettering wrote: On Mon, 08.12.14 15:32, WaLyong Cho (walyong@samsung.com) wrote: Hi, First, I'd like to ask unit property should be applied immediately when systemctl set-property is called? If yes, after systemctl set-property, why we can see the message for daemon-reload. I think that should be re-loaded automatically. If no, some of unit properties are set immediatly. See below: # systemctl set-property dbus.service CPUShares=1200 # systemctl status dbus.service * dbus.service - D-Bus System Message Bus Loaded: loaded (/usr/lib/systemd/system/dbus.service; enabled; vendor preset: disabled) Active: active (running) since Mon 2014-12-08 14:59:12 KST; 1min 30s ago Docs: man:dbus-daemon(1) Main PID: 31 (dbus-daemon) CGroup: /machine.slice/machine-container.scope/system.slice/dbus.service `-31 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation Dec 08 14:59:12 container systemd[1]: Starting D-Bus System Message Bus... Dec 08 14:59:12 container systemd[1]: Started D-Bus System Message Bus. Dec 08 14:59:12 container dbus[31]: [system] Successfully activated service 'org.freedesktop.systemd1' Warning: Unit file changed on disk, 'systemctl daemon-reload' recommended. systemctl status saied systemctl daemon-reload is needed. It sound something is changed and to apply that daemon-reload is needed. But I can notice that property already applied. Hmm, yeah, that message shouldn't be shown. Are you sure it was triggered by the set-property call though? Maybe it was there already before? See this log: [root@container ~]# systemctl status dbus.service * dbus.service - D-Bus System Message Bus Loaded: loaded (/usr/lib/systemd/system/dbus.service; enabled; vendor preset: disabled) Active: active (running) since Tue 2014-12-09 00:22:50 KST; 10s ago Docs: man:dbus-daemon(1) Main PID: 32 (dbus-daemon) CGroup: /machine.slice/machine-container.scope/system.slice/dbus.service `-32 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation Dec 09 00:22:50 container systemd[1]: Starting D-Bus System Message Bus... Dec 09 00:22:50 container systemd[1]: Started D-Bus System Message Bus. Dec 09 00:22:50 container dbus[32]: [system] Successfully activated service 'org.freedesktop.systemd1' [root@container ~]# [root@container ~]# systemctl set-property dbus.service CPUShares=777 [root@container ~]# [root@container ~]# systemctl status dbus.service * dbus.service - D-Bus System Message Bus Loaded: loaded (/usr/lib/systemd/system/dbus.service; enabled; vendor preset: disabled) Active: active (running) since Tue 2014-12-09 00:22:50 KST; 29s ago Docs: man:dbus-daemon(1) Main PID: 32 (dbus-daemon) CGroup: /machine.slice/machine-container.scope/system.slice/dbus.service `-32 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation Dec 09 00:22:50 container systemd[1]: Starting D-Bus System Message Bus... Dec 09 00:22:50 container systemd[1]: Started D-Bus System Message Bus. Dec 09 00:22:50 container dbus[32]: [system] Successfully activated service 'org.freedesktop.systemd1' Warning: Unit file changed on disk, 'systemctl daemon-reload' recommended. [root@container ~]# [root@container ~]# cat /sys/fs/cgroup/cpu/machine.slice/machine-container.scope/system.slice/dbus.service/cpu.shares 777 set-property is applied immediately well. I will try to prepare patch for this. And if the property set should be applied immediately then it seems there are duplicate property set by unit_load_dropin(). Should we skip unit_load_dropin() if the unit is transient? WaLyong Lennart ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [PATCH v6 3/3] run: introduce timer support option
On 12/09/2014 12:38 AM, Lennart Poettering wrote: On Tue, 09.12.14 00:03, WaLyong Cho (walyong@samsung.com) wrote: } else { log_error(Unknown assignment %s., assignment); return -EINVAL; diff --git a/src/run/run.c b/src/run/run.c index 85eb052..e145784 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -30,6 +30,7 @@ #include env-util.h #include path-util.h #include bus-error.h +#include calendarspec.h static bool arg_scope = false; static bool arg_remain_after_exit = false; @@ -47,27 +48,45 @@ static int arg_nice = 0; static bool arg_nice_set = false; static char **arg_environment = NULL; static char **arg_property = NULL; +static bool with_timer = false; Hmm, maybe we should turn this boolean into a function? I mean, static variables are something we should keep at a minimum. We do them for command line arguments, since they are kinda global anyway, but I think we should otherwise avoid them, especially if they are effectively redundant anyway. Hence, my suggestions would be to turn this into a call: static bool with_timer(void) { return arg_on_active || arg_on_boot || arg_on_startup || arg_on_unit_active || arg_on_unit_inactive || arg_on_calendar; } Or so? Yes, it should be. +static int start_transient_service( +sd_bus *bus, +char **argv, +sd_bus_error *error) { + +_cleanup_bus_message_unref_ sd_bus_message *m = NULL; +_cleanup_free_ char *service = NULL; +char *state = NULL; +int r; + +assert(bus); +assert(argv); + +if (arg_unit) { +service = unit_name_mangle_with_suffix(arg_unit, MANGLE_NOGLOB, .service); +if (!service) +return log_oom(); + +if (get_unit_state_by_name(bus, service, state) == 0) { +log_error(Unit %s is already exist with %s state., service, state); +return -EEXIST; +} What's the rationale for checking the unit state here? I mean, PID 1 should fail anyway in this case, do we realy need to check this name in advance? I mean, such a check is necessarily racy, since the unit might appear while between our client-side check and the actual execution of the service, no? I had plan to generate transient timer unit for already existing service. To do that I needed get_unit_state_by_name() and I used that also here. with_aux = get_unit_state_by_name(bus, service, state) 0 ? true : false; Above is to determine that. Honestly, some of codes are removed during rebase. I will rework for that. Anyway, as you said, it is role of server side not client. I will remove on here. WaLyong Lennart ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH v7] run: introduce timer support option
Support timer options --on-active=, --on-boot=, --on-startup=, --on-unit-active=, --on-unit-inactive=, --on-calendar=. Each options corresponding with OnActiveSec=, OnBootSec=, OnStartupSec=, OnUnitActiveSec=, OnUnitInactiveSec=, OnCalendar= of timer respectively. And OnCalendar= and WakeSystem= supported by --timer-property= option like --property= of systemd-run. And if --unit= option and timer options are specified the command can be omitted. In this case, systemd-run assumes the target service is already loaded. And just try to generate transient timer unit only. --- man/systemd-run.xml | 94 +- src/core/dbus-manager.c | 8 +- src/libsystemd/sd-bus/bus-util.c | 14 +- src/run/run.c| 628 ++- 4 files changed, 596 insertions(+), 148 deletions(-) diff --git a/man/systemd-run.xml b/man/systemd-run.xml index 28a9878..b9cec91 100644 --- a/man/systemd-run.xml +++ b/man/systemd-run.xml @@ -45,7 +45,7 @@ along with systemd; If not, see http://www.gnu.org/licenses/. refnamediv refnamesystemd-run/refname -refpurposeRun programs in transient scope or service units/refpurpose +refpurposeRun programs in transient scope or service or timer units/refpurpose /refnamediv refsynopsisdiv @@ -56,15 +56,23 @@ along with systemd; If not, see http://www.gnu.org/licenses/. arg choice=opt rep=repeatARGS/arg /arg /cmdsynopsis +cmdsynopsis + commandsystemd-run/command + arg choice=opt rep=repeatOPTIONS/arg + arg choice=opt rep=repeatTIMER OPTIONS/arg + arg choice=reqreplaceableCOMMAND/replaceable/arg + arg choice=opt rep=repeatARGS/arg +/cmdsynopsis /refsynopsisdiv refsect1 titleDescription/title -paracommandsystemd-run/command may be used to create and start -a transient filename.service/filename or a -filename.scope/filename unit and run the specified -replaceableCOMMAND/replaceable in it./para +paracommandsystemd-run/command may be used to create and +start a transient filename.service/filename or a transient +filename.timer/filename or a filename.scope/filename unit +and run the specified replaceableCOMMAND/replaceable in +it./para paraIf a command is run as transient service unit, it will be started and managed by the service manager like any other service, @@ -74,6 +82,18 @@ along with systemd; If not, see http://www.gnu.org/licenses/. will start the service asynchronously in the background and immediately return./para +paraIf a command is run with timer options, transient timer unit +also be created with transient service unit. But the transient +timer unit is only started immediately. The transient service unit +will be started when the transient timer is elapsed. If +option--unit=/option is specified with timer options, the +replaceableCOMMAND/replaceable can be omitted. In this case, +commandsystemd-run/command assumes service unit is already +loaded and creates transient timer unit only. To successfully +create timer unit, already loaded service unit should be specified +with option--unit=/option. This transient timer unit can +activate the existing service unit like any other timer./para + paraIf a command is run as transient scope unit, it will be started directly by commandsystemd-run/command and thus inherit the execution environment of the caller. It is however @@ -210,6 +230,54 @@ along with systemd; If not, see http://www.gnu.org/licenses/. xi:include href=user-system-options.xml xpointer=host / xi:include href=user-system-options.xml xpointer=machine / + varlistentry +termoption--on-active=/option/term +termoption--on-boot=/option/term +termoption--on-startup=/option/term +termoption--on-unit-active=/option/term +termoption--on-unit-inactive=/option/term + +listitemparaDefines monotonic timers relative to different +starting points. Also see varnameOnActiveSec=/varname, +varnameOnBootSec=/varname, +varnameOnStartupSec=/varname, +varnameOnUnitActiveSec=/varname and +varnameOnUnitInactiveSec=/varname in + citerefentryrefentrytitlesystemd.timer/refentrytitlemanvolnum5/manvolnum/citerefentry. This +options have no effect in conjunction with +option--scope/option./para +/listitem + /varlistentry + + varlistentry +termoption--on-calendar=/option/term + +listitemparaDefines realtime (i.e. wallclock) timers with +calendar event expressions. Also see +varnameOnCalendar=/varname in + citerefentryrefentrytitlesystemd.timer/refentrytitlemanvolnum5/manvolnum/citerefentry. This +option has no effect in conjunction with +option--scope/option./para +/listitem + /varlistentry + + varlistentry +
[systemd-devel] [RFC] [PATCH] core: avoid duplicate unit property set
Currently, unit property set apis set unit property and also make a dropin files in each dbus-xyz.c. And the dropin will set its properties again in unit_load(). So don't need to set property immediatly. That will be set next unit_load(). Just write dropin files only. --- src/core/dbus-cgroup.c | 325 ++- src/core/dbus-cgroup.h | 2 +- src/core/dbus-execute.c | 77 +++ src/core/dbus-execute.h | 2 +- src/core/dbus-kill.c | 26 ++-- src/core/dbus-kill.h | 2 +- src/core/dbus-mount.c| 8 +- src/core/dbus-scope.c| 6 +- src/core/dbus-service.c | 77 +-- src/core/dbus-slice.c| 6 +- src/core/dbus-socket.c | 6 +- src/core/dbus-swap.c | 6 +- src/core/dbus-unit.c | 12 +- src/core/load-fragment.c | 61 ++--- 14 files changed, 227 insertions(+), 389 deletions(-) diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c index db99834..ffbd8d5 100644 --- a/src/core/dbus-cgroup.c +++ b/src/core/dbus-cgroup.c @@ -24,6 +24,7 @@ #include cgroup-util.h #include cgroup.h #include dbus-cgroup.h +#include strv.h static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_cgroup_device_policy, cgroup_device_policy, CGroupDevicePolicy); @@ -173,16 +174,15 @@ const sd_bus_vtable bus_cgroup_vtable[] = { static int bus_cgroup_set_transient_property( Unit *u, -CGroupContext *c, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error) { + int r; assert(u); -assert(c); assert(name); assert(message); @@ -194,8 +194,9 @@ static int bus_cgroup_set_transient_property( return r; if (mode != UNIT_CHECK) { -c-delegate = b; -unit_write_drop_in_private(u, mode, name, b ? Delegate=yes : Delegate=no); +r = unit_write_drop_in_private(u, mode, name, b ? Delegate=yes : Delegate=no); +if (r 0) +return r; } return 1; @@ -206,7 +207,6 @@ static int bus_cgroup_set_transient_property( int bus_cgroup_set_property( Unit *u, -CGroupContext *c, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, @@ -215,7 +215,6 @@ int bus_cgroup_set_property( int r; assert(u); -assert(c); assert(name); assert(message); @@ -227,9 +226,9 @@ int bus_cgroup_set_property( return r; if (mode != UNIT_CHECK) { -c-cpu_accounting = b; -u-cgroup_realized_mask = ~CGROUP_CPUACCT; -unit_write_drop_in_private(u, mode, name, b ? CPUAccounting=yes : CPUAccounting=no); +r = unit_write_drop_in_private(u, mode, name, b ? CPUAccounting=yes : CPUAccounting=no); +if (r 0) +return r; } return 1; @@ -251,9 +250,9 @@ int bus_cgroup_set_property( } if (mode != UNIT_CHECK) { -c-cpu_shares = ul; -u-cgroup_realized_mask = ~CGROUP_CPU; -unit_write_drop_in_private_format(u, mode, name, CPUShares=%lu, ul); +r = unit_write_drop_in_private_format(u, mode, name, CPUShares=%lu, ul); +if (r 0) +return r; } return 1; @@ -275,9 +274,9 @@ int bus_cgroup_set_property( } if (mode != UNIT_CHECK) { -c-startup_cpu_shares = ul; -u-cgroup_realized_mask = ~CGROUP_CPU; -unit_write_drop_in_private_format(u, mode, name, StartupCPUShares=%lu, ul); +r = unit_write_drop_in_private_format(u, mode, name, StartupCPUShares=%lu, ul); +if (r 0) +return r; } return 1; @@ -293,9 +292,9 @@ int bus_cgroup_set_property( return sd_bus_error_set_errnof(error, EINVAL, CPUQuotaPerSecUSec value out of range); if (mode != UNIT_CHECK) { -c-cpu_quota_per_sec_usec = u64; -u-cgroup_realized_mask = ~CGROUP_CPU; -unit_write_drop_in_private_format(u, mode, CPUQuota, CPUQuota=%0.f%%, (double) (c-cpu_quota_per_sec_usec / 1)); +r = unit_write_drop_in_private_format(u, mode, CPUQuota, CPUQuota=%0.f%%, (double) (u64 / 1)); +if (r 0) +
Re: [systemd-devel] [RFC] [PATCH] core: avoid duplicate unit property set
Hi, First, I'd like to ask unit property should be applied immediately when systemctl set-property is called? If yes, after systemctl set-property, why we can see the message for daemon-reload. I think that should be re-loaded automatically. If no, some of unit properties are set immediatly. See below: # systemctl set-property dbus.service CPUShares=1200 # systemctl status dbus.service * dbus.service - D-Bus System Message Bus Loaded: loaded (/usr/lib/systemd/system/dbus.service; enabled; vendor preset: disabled) Active: active (running) since Mon 2014-12-08 14:59:12 KST; 1min 30s ago Docs: man:dbus-daemon(1) Main PID: 31 (dbus-daemon) CGroup: /machine.slice/machine-container.scope/system.slice/dbus.service `-31 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation Dec 08 14:59:12 container systemd[1]: Starting D-Bus System Message Bus... Dec 08 14:59:12 container systemd[1]: Started D-Bus System Message Bus. Dec 08 14:59:12 container dbus[31]: [system] Successfully activated service 'org.freedesktop.systemd1' Warning: Unit file changed on disk, 'systemctl daemon-reload' recommended. systemctl status saied systemctl daemon-reload is needed. It sound something is changed and to apply that daemon-reload is needed. But I can notice that property already applied. # systemctl show dbus.service | grep CPUShares CPUShares=1200 StartupCPUShares=18446744073709551615 This immediate property set make duplicate operation when systemd-run is called. The first will be set by transient property set in method call handler. The second will be set by unit_load_dropin() the last actual load. What it the most proper way? WaLyong On 12/08/2014 03:12 PM, WaLyong Cho wrote: Currently, unit property set apis set unit property and also make a dropin files in each dbus-xyz.c. And the dropin will set its properties again in unit_load(). So don't need to set property immediatly. That will be set next unit_load(). Just write dropin files only. --- src/core/dbus-cgroup.c | 325 ++- src/core/dbus-cgroup.h | 2 +- src/core/dbus-execute.c | 77 +++ src/core/dbus-execute.h | 2 +- src/core/dbus-kill.c | 26 ++-- src/core/dbus-kill.h | 2 +- src/core/dbus-mount.c| 8 +- src/core/dbus-scope.c| 6 +- src/core/dbus-service.c | 77 +-- src/core/dbus-slice.c| 6 +- src/core/dbus-socket.c | 6 +- src/core/dbus-swap.c | 6 +- src/core/dbus-unit.c | 12 +- src/core/load-fragment.c | 61 ++--- 14 files changed, 227 insertions(+), 389 deletions(-) diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c index db99834..ffbd8d5 100644 --- a/src/core/dbus-cgroup.c +++ b/src/core/dbus-cgroup.c @@ -24,6 +24,7 @@ #include cgroup-util.h #include cgroup.h #include dbus-cgroup.h +#include strv.h static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_cgroup_device_policy, cgroup_device_policy, CGroupDevicePolicy); @@ -173,16 +174,15 @@ const sd_bus_vtable bus_cgroup_vtable[] = { static int bus_cgroup_set_transient_property( Unit *u, -CGroupContext *c, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error) { + int r; assert(u); -assert(c); assert(name); assert(message); @@ -194,8 +194,9 @@ static int bus_cgroup_set_transient_property( return r; if (mode != UNIT_CHECK) { -c-delegate = b; -unit_write_drop_in_private(u, mode, name, b ? Delegate=yes : Delegate=no); +r = unit_write_drop_in_private(u, mode, name, b ? Delegate=yes : Delegate=no); +if (r 0) +return r; } return 1; @@ -206,7 +207,6 @@ static int bus_cgroup_set_transient_property( int bus_cgroup_set_property( Unit *u, -CGroupContext *c, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, @@ -215,7 +215,6 @@ int bus_cgroup_set_property( int r; assert(u); -assert(c); assert(name); assert(message); @@ -227,9 +226,9 @@ int bus_cgroup_set_property( return r; if (mode != UNIT_CHECK) { -c-cpu_accounting = b; -u-cgroup_realized_mask = ~CGROUP_CPUACCT; -unit_write_drop_in_private(u, mode, name, b ? CPUAccounting=yes : CPUAccounting=no); +r = unit_write_drop_in_private(u, mode, name, b ? CPUAccounting=yes : CPUAccounting
Re: [systemd-devel] [PATCH v4 3/4] unit: add UnitMask enum and get unit scope(mask) api from property
On 12/04/2014 03:43 AM, Lennart Poettering wrote: On Tue, 02.12.14 23:29, WaLyong Cho (walyong@samsung.com) wrote: Hmm, what's the rationale for this? Can you elaborate? As you already noticed(on the 4th mail), this hash table is used to find unit can have a given property. As you said on 4th mail, if we use a special option for timer then this will not be needed. This can be also used in systemctl set-property and we can detect given property is supported by that unit or not before sending dbus. But, in most of case, systemctl set-property is called by user command line. And they will know which unit support which property. So, maybe this is not much needed. If you feel messy, I will add --timer-property= option. WaLyong --- Makefile.am | 7 ++ src/shared/.gitignore| 1 + src/shared/unit-name.c | 22 src/shared/unit-name.h | 26 + src/shared/unit-property-scope.gperf | 202 +++ 5 files changed, 258 insertions(+) create mode 100644 src/shared/unit-property-scope.gperf diff --git a/Makefile.am b/Makefile.am index 38d320f..3cec5fb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -819,6 +819,7 @@ libsystemd_shared_la_SOURCES = \ src/shared/cgroup-show.h \ src/shared/unit-name.c \ src/shared/unit-name.h \ +src/shared/unit-property-scope.c \ src/shared/utmp-wtmp.h \ src/shared/watchdog.c \ src/shared/watchdog.h \ @@ -907,6 +908,12 @@ libsystemd_shared_la_CFLAGS = \ $(SECCOMP_CFLAGS) \ -pthread +EXTRA_DIST += \ +src/shared/unit-property-scope.gperf + +CLEANFILES += \ +src/shared/unit-property-scope.c + libsystemd_shared_la_LIBADD = \ $(CAP_LIBS) diff --git a/src/shared/.gitignore b/src/shared/.gitignore index 61709e8..e7faa23 100644 --- a/src/shared/.gitignore +++ b/src/shared/.gitignore @@ -10,3 +10,4 @@ /arphrd-from-name.h /arphrd-list.txt /arphrd-to-name.h +/unit-property-scope.c diff --git a/src/shared/unit-name.c b/src/shared/unit-name.c index 21b6691..7cf0160 100644 --- a/src/shared/unit-name.c +++ b/src/shared/unit-name.c @@ -602,3 +602,25 @@ static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = { }; DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency); + +static UnitMask unit_get_mask_from_property(const char *property) { +const unit_property_scope_mapping *m; + +assert(property); + +m = unit_property_scope_mapping_lookup(property, strlen(property)); +if (m) +return m-scope; + +return _UNIT_MASK_MAX; + +} + +bool unit_can_have_property(UnitType t, const char *property) { +UnitMask m; + +assert(property); + +m = unit_get_mask_from_property(property); +return !!((1ULL t) m); +} diff --git a/src/shared/unit-name.h b/src/shared/unit-name.h index 6f139cc..191c930 100644 --- a/src/shared/unit-name.h +++ b/src/shared/unit-name.h @@ -28,6 +28,7 @@ #define UNIT_NAME_MAX 256 typedef enum UnitType UnitType; +typedef enum UnitMask UnitMask; typedef enum UnitLoadState UnitLoadState; typedef enum UnitDependency UnitDependency; @@ -49,6 +50,23 @@ enum UnitType { _UNIT_TYPE_INVALID = -1 }; +enum UnitMask { +UNIT_MASK_SERVICE = 1ULL UNIT_SERVICE, +UNIT_MASK_SOCKET= 1ULL UNIT_SOCKET, +UNIT_MASK_BUSNAME = 1ULL UNIT_BUSNAME, +UNIT_MASK_TARGET= 1ULL UNIT_TARGET, +UNIT_MASK_SNAPSHOT = 1ULL UNIT_SNAPSHOT, +UNIT_MASK_DEVICE= 1ULL UNIT_DEVICE, +UNIT_MASK_MOUNT = 1ULL UNIT_MOUNT, +UNIT_MASK_AUTOMOUNT = 1ULL UNIT_AUTOMOUNT, +UNIT_MASK_SWAP = 1ULL UNIT_SWAP, +UNIT_MASK_TIMER = 1ULL UNIT_TIMER, +UNIT_MASK_PATH = 1ULL UNIT_PATH, +UNIT_MASK_SLICE = 1ULL UNIT_SLICE, +UNIT_MASK_SCOPE = 1ULL UNIT_SCOPE, +_UNIT_MASK_MAX = 1ULL _UNIT_TYPE_MAX, +}; + enum UnitLoadState { UNIT_STUB = 0, UNIT_LOADED, @@ -165,3 +183,11 @@ int build_subslice(const char *slice, const char*name, char **subslice); const char *unit_dependency_to_string(UnitDependency i) _const_; UnitDependency unit_dependency_from_string(const char *s) _pure_; + +struct unit_property_scope_mapping { +const char* property; +UnitMask scope; +}; +typedef struct unit_property_scope_mapping unit_property_scope_mapping; +const unit_property_scope_mapping* unit_property_scope_mapping_lookup (register const char *str, register unsigned int len); +bool unit_can_have_property(UnitType t, const char *property); diff --git a/src/shared/unit-property-scope.gperf b/src/shared/unit-property-scope.gperf new file mode 100644 index 000..bbcfcba --- /dev/null +++ b/src/shared
Re: [systemd-devel] [PATCH v4] run: introduce timer support option
On 12/04/2014 03:44 AM, Lennart Poettering wrote: On Tue, 02.12.14 23:35, WaLyong Cho (walyong@samsung.com) wrote: Supported timer options --on-active=, --on-boot=, --on-startup=, --on-unit-active=, --on-unit-inactive=, --on-calendar=. Each options corresponding with OnActiveSec=, OnBootSec=, OnStartupSec=, OnUnitActiveSec=, OnUnitInactiveSec= of timer respectively. I think a nice way to make both the properties of the service and of the timer unit configurable would be to introduce --timer-property= in addition to --property= as parameter. --property= would then always be applied to the service/scope being created, and --timer-property= would apply to the timer unit instead. Do we need the tables of the 3rd patch which a simple scheme like that? I replied on 3rd patch email. If we don't need 3rd patch then I will change it to --timer-property=. WaLyong Lennart ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH] unit: ignore generated systemd-bootchart.service
--- units/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/units/.gitignore b/units/.gitignore index e12d299..3613cee 100644 --- a/units/.gitignore +++ b/units/.gitignore @@ -21,6 +21,7 @@ /systemd-ask-password-wall.service /systemd-backlight@.service /systemd-binfmt.service +/systemd-bootchart.service /systemd-bus-proxyd@.service /systemd-firstboot.service /systemd-fsck-root.service -- 1.9.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [PATCH v4 1/4] bus: StartTransientUnit can have aux unit
On 12/04/2014 03:00 AM, Lennart Poettering wrote: On Tue, 02.12.14 23:29, WaLyong Cho (walyong@samsung.com) wrote: --- src/core/dbus-manager.c | 123 +--- 1 file changed, 105 insertions(+), 18 deletions(-) diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 0994d7b..643aa8b 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -615,6 +615,93 @@ static int method_set_unit_properties(sd_bus *bus, sd_bus_message *message, void return bus_unit_method_set_properties(bus, message, u, error); } +static int transient_unit_from_message( +Manager *m, +sd_bus_message *message, +const char *name, +Unit **unit, +sd_bus_error *error) { + +Unit *u; +int r; + +assert(m); +assert(message); +assert(name); + +r = manager_load_unit(m, name, NULL, error, u); +if (r 0) +return r; + +if (u-load_state != UNIT_NOT_FOUND || +set_size(u-dependencies[UNIT_REFERENCED_BY]) 0) +return sd_bus_error_setf(error, + BUS_ERROR_UNIT_EXISTS, + Unit %s already exists., + name); Please do not line-break so eagerly. See CODING_STYLE, we do no follow a 80ch regime. + +static int try_aux_units_in_message( +Manager *m, +sd_bus_message *message, +sd_bus_error *error) { Why call this try? Maybe invoke it transient_aux_units_from_message() or so? if (r 0) return r; if (r == 0) -return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ +/* No authorization for now, but the async polkit + * stuff will call us again when it has it */ +return 1; Please don't rearrange lines that your patch doesn't really change. Please don't break lines too eagerly. r = sd_bus_message_read(message, ss, name, smode); if (r 0) @@ -639,34 +728,32 @@ static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, voi t = unit_name_to_type(name); if (t 0) -return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, Invalid unit type.); +return sd_bus_error_setf(error, + SD_BUS_ERROR_INVALID_ARGS, + Invalid unit type.); Same here... if (!unit_vtable[t]-can_transient) -return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, Unit type %s does not support transient units., unit_type_to_string(t)); - -mode = job_mode_from_string(smode); -if (mode 0) -return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, Job mode %s is invalid., smode); +return sd_bus_error_setf(error, + SD_BUS_ERROR_INVALID_ARGS, + Unit type %s does not support transient units., + unit_type_to_string(t)); Same here. r = mac_selinux_access_check(message, start, error); if (r 0) return r; -r = manager_load_unit(m, name, NULL, error, u); -if (r 0) -return r; - -if (u-load_state != UNIT_NOT_FOUND || set_size(u-dependencies[UNIT_REFERENCED_BY]) 0) -return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, Unit %s already exists., name); +mode = job_mode_from_string(smode); +if (mode 0) +return sd_bus_error_setf(error, + SD_BUS_ERROR_INVALID_ARGS, + Job mode %s is invalid., + smode); Why did you move the parsing of the job mode after the selinux access check? I think we should validate all args before doing any further checks. -/* OK, the unit failed to load and is unreferenced, now let's - * fill in the transient data instead */ -r = unit_make_transient(u); +r = transient_unit_from_message(m, message, name, u, error); if (r 0) return r; -/* Set our properties */ -r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error); +r = try_aux_units_in_message(m, message, error); if (r 0) return r; Hmm, the unit_load() invocation, isn't that something that should move into transient_unit_from_message() as well? The main transient unit should have
[systemd-devel] [PATCH v4 1/4] bus: StartTransientUnit can have aux unit
--- src/core/dbus-manager.c | 123 +--- 1 file changed, 105 insertions(+), 18 deletions(-) diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 0994d7b..643aa8b 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -615,6 +615,93 @@ static int method_set_unit_properties(sd_bus *bus, sd_bus_message *message, void return bus_unit_method_set_properties(bus, message, u, error); } +static int transient_unit_from_message( +Manager *m, +sd_bus_message *message, +const char *name, +Unit **unit, +sd_bus_error *error) { + +Unit *u; +int r; + +assert(m); +assert(message); +assert(name); + +r = manager_load_unit(m, name, NULL, error, u); +if (r 0) +return r; + +if (u-load_state != UNIT_NOT_FOUND || +set_size(u-dependencies[UNIT_REFERENCED_BY]) 0) +return sd_bus_error_setf(error, + BUS_ERROR_UNIT_EXISTS, + Unit %s already exists., + name); + +/* OK, the unit failed to load and is unreferenced, now let's + * fill in the transient data instead */ +r = unit_make_transient(u); +if (r 0) +return r; + +/* Set our properties */ +r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error); +if (r 0) +return r; + +*unit = u; + +return 0; +} + +static int try_aux_units_in_message( +Manager *m, +sd_bus_message *message, +sd_bus_error *error) { + +Unit *u; +char *name = NULL; +int r; + +assert(m); +assert(message); + +r = sd_bus_message_enter_container(message, 'a', (sa(sv))); +if (r 0) +return r; + +while ((r = sd_bus_message_enter_container(message, 'r', sa(sv))) 0) { +if (r = 0) +return r; + +r = sd_bus_message_read(message, s, name); +if (r 0) +return r; + +r = transient_unit_from_message(m, message, name, u, error); +if (r 0 r != -EEXIST) +return r; + +r = sd_bus_message_exit_container(message); +if (r 0) +return r; + +r = unit_load(u); +if (r 0) +return r; +} +if (r 0) +return r; + +r = sd_bus_message_exit_container(message); +if (r 0) +return r; + +return 0; +} + static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { const char *name, *smode; Manager *m = userdata; @@ -631,7 +718,9 @@ static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, voi if (r 0) return r; if (r == 0) -return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ +/* No authorization for now, but the async polkit + * stuff will call us again when it has it */ +return 1; r = sd_bus_message_read(message, ss, name, smode); if (r 0) @@ -639,34 +728,32 @@ static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, voi t = unit_name_to_type(name); if (t 0) -return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, Invalid unit type.); +return sd_bus_error_setf(error, + SD_BUS_ERROR_INVALID_ARGS, + Invalid unit type.); if (!unit_vtable[t]-can_transient) -return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, Unit type %s does not support transient units., unit_type_to_string(t)); - -mode = job_mode_from_string(smode); -if (mode 0) -return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, Job mode %s is invalid., smode); +return sd_bus_error_setf(error, + SD_BUS_ERROR_INVALID_ARGS, + Unit type %s does not support transient units., + unit_type_to_string(t)); r = mac_selinux_access_check(message, start, error); if (r 0) return r; -r = manager_load_unit(m, name, NULL, error, u); -if (r 0) -return r; - -if (u-load_state != UNIT_NOT_FOUND || set_size(u-dependencies[UNIT_REFERENCED_BY]) 0) -
[systemd-devel] [PATCH v4 2/4] timer: timer can be a transient unit
--- src/core/dbus-timer.c | 159 ++ src/core/dbus-timer.h | 3 + src/core/timer.c | 4 ++ 3 files changed, 166 insertions(+) diff --git a/src/core/dbus-timer.c b/src/core/dbus-timer.c index f1f8c54..e916f5a 100644 --- a/src/core/dbus-timer.c +++ b/src/core/dbus-timer.c @@ -24,6 +24,8 @@ #include dbus-unit.h #include dbus-timer.h #include bus-util.h +#include errno-list.h +#include strv.h static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, timer_result, TimerResult); @@ -183,3 +185,160 @@ const sd_bus_vtable bus_timer_vtable[] = { SD_BUS_PROPERTY(WakeSystem, b, bus_property_get_bool, offsetof(Timer, wake_system), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_VTABLE_END }; + +static int bus_timer_set_transient_property( +Timer *t, +const char *name, +sd_bus_message *message, +UnitSetPropertiesMode mode, +sd_bus_error *error) { + +const char *str; +int r; + +assert(t); +assert(name); +assert(message); + +if (STR_IN_SET(name, + OnActiveSec, + OnBootSec, + OnStartupSec, + OnUnitActiveSec, + OnUnitInactiveSec)) { + +TimerValue *v; +TimerBase b = _TIMER_BASE_INVALID; +usec_t u = 0; + +b = timer_base_from_string(name); +if (b 0) +return 0; + +r = sd_bus_message_read(message, t, u); +if (r 0) +return r; + +if (mode != UNIT_CHECK) { +unit_write_drop_in_private_format(UNIT(t), + mode, + name, + %s=%lu\n, + name, + u); + +v = new0(TimerValue, 1); +if (!v) +return -ENOMEM; + +v-base = b; +v-value = u; + +LIST_PREPEND(value, t-values, v); +} + +return 1; + +} else if (streq(name, OnCalendar)) { + +TimerValue *v; +CalendarSpec *c = NULL; + +r = sd_bus_message_read(message, s, str); +if (r 0) +return r; + +if (mode != UNIT_CHECK) { +r = calendar_spec_from_string(str, c); +if (r 0) +return r; + +unit_write_drop_in_private_format(UNIT(t), + mode, + name, + %s=%s\n, + name, + str); + +v = new0(TimerValue, 1); +if (!v) { +if (c) +calendar_spec_free(c); +return -ENOMEM; +} + +v-base = TIMER_CALENDAR; +v-calendar_spec = c; + +LIST_PREPEND(value, t-values, v); +} + +return 1; + +} else if (streq(name, AccuracySec)) { + +usec_t u = 0; + +r = sd_bus_message_read(message, t, u); +if (r 0) +return r; + +if (mode != UNIT_CHECK) { +t-accuracy_usec = u; +unit_write_drop_in_private_format(UNIT(t), + mode, + name, + %s=%lu\n, + name, + u); +} + +return 1; + +} else if (streq(name, WakeSystem)) { + +int b; + +r = sd_bus_message_read(message, b, b); +if (r 0) +return r; + +if (mode != UNIT_CHECK) { +t-wake_system = b; +unit_write_drop_in_private_format(UNIT(t), + mode, + name, +
[systemd-devel] [PATCH v4 4/4] run: introduce timer support option
Supported timer options --on-active=, --on-boot=, --on-startup=, --on-unit-active=, --on-unit-inactive=, --on-calendar=. Each options corresponding with OnActiveSec=, OnBootSec=, OnStartupSec=, OnUnitActiveSec=, OnUnitInactiveSec= of timer respectively. --- man/systemd-run.xml | 42 +++ src/libsystemd/sd-bus/bus-util.c | 14 +- src/run/run.c| 583 --- 3 files changed, 539 insertions(+), 100 deletions(-) diff --git a/man/systemd-run.xml b/man/systemd-run.xml index 28a9878..abac26c 100644 --- a/man/systemd-run.xml +++ b/man/systemd-run.xml @@ -210,6 +210,37 @@ along with systemd; If not, see http://www.gnu.org/licenses/. xi:include href=user-system-options.xml xpointer=host / xi:include href=user-system-options.xml xpointer=machine / + varlistentry +termoption--on-active=/option/term +termoption--on-boot=/option/term +termoption--on-startup=/option/term +termoption--on-unit-active=/option/term +termoption--on-unit-inactive=/option/term + +listitemparaDefines monotonic timers relative to different +starting points. Also see varnameOnActiveSec=/varname, +varnameOnBootSec=/varname, +varnameOnStartupSec=/varname, +varnameOnUnitActiveSec=/varname and +varnameOnUnitInactiveSec=/varname in + citerefentryrefentrytitlesystemd.timer/refentrytitlemanvolnum5/manvolnum/citerefentry. This +option has no effect in conjunction with +option--scope/option./para +/listitem + /varlistentry + + varlistentry +termoption--on-calendar=/option/term + +listitemparaDefines realtime (i.e. wallclock) timers with +calendar event expressions. Also see +varnameOnCalendar=/varname in + citerefentryrefentrytitlesystemd.timer/refentrytitlemanvolnum5/manvolnum/citerefentry. This +option has no effect in conjunction with +option--scope/option./para +/listitem + /varlistentry + xi:include href=standard-options.xml xpointer=help / xi:include href=standard-options.xml xpointer=version / /variablelist @@ -250,6 +281,16 @@ Sep 08 07:37:21 bupkis env[19948]: BOOT_IMAGE=/vmlinuz-3.11.0-0.rc5.git6.2.fc20. property./para programlisting# systemd-run -p BlockIOWeight=10 updatedb/programlisting + +paraThe following command will touch a file after 10 seconds./para + +programlisting# date; systemd-run --on-active=10 touch /tmp/hello +Mon Oct 27 20:02:57 KST 2014 +Running as unit run-66.timer. +# journalctl -u run-115.service +-- Logs begin at Mon 2014-10-27 19:44:57 KST, end at Mon 2014-10-27 20:03:15 KST. -- +Oct 27 20:03:15 container systemd[1]: Starting /bin/touch /tmp/hello... +Oct 27 20:03:15 container systemd[1]: Started /bin/touch /tmp/hello./programlisting /refsect1 refsect1 @@ -263,6 +304,7 @@ Sep 08 07:37:21 bupkis env[19948]: BOOT_IMAGE=/vmlinuz-3.11.0-0.rc5.git6.2.fc20. citerefentryrefentrytitlesystemd.slice/refentrytitlemanvolnum5/manvolnum/citerefentry, citerefentryrefentrytitlesystemd.exec/refentrytitlemanvolnum5/manvolnum/citerefentry, citerefentryrefentrytitlesystemd.resource-control/refentrytitlemanvolnum5/manvolnum/citerefentry, + citerefentryrefentrytitlesystemd.timer/refentrytitlemanvolnum5/manvolnum/citerefentry, citerefentryrefentrytitlemachinectl/refentrytitlemanvolnum1/manvolnum/citerefentry /para /refsect1 diff --git a/src/libsystemd/sd-bus/bus-util.c b/src/libsystemd/sd-bus/bus-util.c index bdaa449..0f1a89c 100644 --- a/src/libsystemd/sd-bus/bus-util.c +++ b/src/libsystemd/sd-bus/bus-util.c @@ -1372,7 +1372,8 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen if (STR_IN_SET(field, CPUAccounting, MemoryAccounting, BlockIOAccounting, - SendSIGHUP, SendSIGKILL)) { + SendSIGHUP, SendSIGKILL, + WakeSystem)) { r = parse_boolean(eq); if (r 0) { @@ -1533,6 +1534,17 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen r = sd_bus_message_append(m, v, i, sig); +} else if (streq(field, AccuracySec)) { +usec_t u; + +r = parse_sec(eq, u); +if (r 0) { +log_error(Failed to parse %s value %s, field, eq); +return -EINVAL; +} + +r = sd_bus_message_append(m, v, t, u); + } else { log_error(Unknown assignment %s., assignment); return -EINVAL; diff --git a/src/run/run.c b/src/run/run.c index 85eb052..03f49df 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -30,6 +30,7 @@ #include env-util.h #include path-util.h #include bus-error.h +#include calendarspec.h static
[systemd-devel] [PATCH v4 3/4] unit: add UnitMask enum and get unit scope(mask) api from property
--- Makefile.am | 7 ++ src/shared/.gitignore| 1 + src/shared/unit-name.c | 22 src/shared/unit-name.h | 26 + src/shared/unit-property-scope.gperf | 202 +++ 5 files changed, 258 insertions(+) create mode 100644 src/shared/unit-property-scope.gperf diff --git a/Makefile.am b/Makefile.am index 38d320f..3cec5fb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -819,6 +819,7 @@ libsystemd_shared_la_SOURCES = \ src/shared/cgroup-show.h \ src/shared/unit-name.c \ src/shared/unit-name.h \ + src/shared/unit-property-scope.c \ src/shared/utmp-wtmp.h \ src/shared/watchdog.c \ src/shared/watchdog.h \ @@ -907,6 +908,12 @@ libsystemd_shared_la_CFLAGS = \ $(SECCOMP_CFLAGS) \ -pthread +EXTRA_DIST += \ + src/shared/unit-property-scope.gperf + +CLEANFILES += \ + src/shared/unit-property-scope.c + libsystemd_shared_la_LIBADD = \ $(CAP_LIBS) diff --git a/src/shared/.gitignore b/src/shared/.gitignore index 61709e8..e7faa23 100644 --- a/src/shared/.gitignore +++ b/src/shared/.gitignore @@ -10,3 +10,4 @@ /arphrd-from-name.h /arphrd-list.txt /arphrd-to-name.h +/unit-property-scope.c diff --git a/src/shared/unit-name.c b/src/shared/unit-name.c index 21b6691..7cf0160 100644 --- a/src/shared/unit-name.c +++ b/src/shared/unit-name.c @@ -602,3 +602,25 @@ static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = { }; DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency); + +static UnitMask unit_get_mask_from_property(const char *property) { +const unit_property_scope_mapping *m; + +assert(property); + +m = unit_property_scope_mapping_lookup(property, strlen(property)); +if (m) +return m-scope; + +return _UNIT_MASK_MAX; + +} + +bool unit_can_have_property(UnitType t, const char *property) { +UnitMask m; + +assert(property); + +m = unit_get_mask_from_property(property); +return !!((1ULL t) m); +} diff --git a/src/shared/unit-name.h b/src/shared/unit-name.h index 6f139cc..191c930 100644 --- a/src/shared/unit-name.h +++ b/src/shared/unit-name.h @@ -28,6 +28,7 @@ #define UNIT_NAME_MAX 256 typedef enum UnitType UnitType; +typedef enum UnitMask UnitMask; typedef enum UnitLoadState UnitLoadState; typedef enum UnitDependency UnitDependency; @@ -49,6 +50,23 @@ enum UnitType { _UNIT_TYPE_INVALID = -1 }; +enum UnitMask { +UNIT_MASK_SERVICE = 1ULL UNIT_SERVICE, +UNIT_MASK_SOCKET= 1ULL UNIT_SOCKET, +UNIT_MASK_BUSNAME = 1ULL UNIT_BUSNAME, +UNIT_MASK_TARGET= 1ULL UNIT_TARGET, +UNIT_MASK_SNAPSHOT = 1ULL UNIT_SNAPSHOT, +UNIT_MASK_DEVICE= 1ULL UNIT_DEVICE, +UNIT_MASK_MOUNT = 1ULL UNIT_MOUNT, +UNIT_MASK_AUTOMOUNT = 1ULL UNIT_AUTOMOUNT, +UNIT_MASK_SWAP = 1ULL UNIT_SWAP, +UNIT_MASK_TIMER = 1ULL UNIT_TIMER, +UNIT_MASK_PATH = 1ULL UNIT_PATH, +UNIT_MASK_SLICE = 1ULL UNIT_SLICE, +UNIT_MASK_SCOPE = 1ULL UNIT_SCOPE, +_UNIT_MASK_MAX = 1ULL _UNIT_TYPE_MAX, +}; + enum UnitLoadState { UNIT_STUB = 0, UNIT_LOADED, @@ -165,3 +183,11 @@ int build_subslice(const char *slice, const char*name, char **subslice); const char *unit_dependency_to_string(UnitDependency i) _const_; UnitDependency unit_dependency_from_string(const char *s) _pure_; + +struct unit_property_scope_mapping { +const char* property; +UnitMask scope; +}; +typedef struct unit_property_scope_mapping unit_property_scope_mapping; +const unit_property_scope_mapping* unit_property_scope_mapping_lookup (register const char *str, register unsigned int len); +bool unit_can_have_property(UnitType t, const char *property); diff --git a/src/shared/unit-property-scope.gperf b/src/shared/unit-property-scope.gperf new file mode 100644 index 000..bbcfcba --- /dev/null +++ b/src/shared/unit-property-scope.gperf @@ -0,0 +1,202 @@ +%{ +#include unit-name.h +#include bus-util.h +%} +unit_property_scope_mapping; +%null_strings +%language=ANSI-C +%define slot-name property +%define hash-function-name bus_property_scope_mapping_hash +%define lookup-function-name unit_property_scope_mapping_lookup +%readonly-tables +%omit-struct-type +%struct-type +%includes +%% +Description, UNIT_MASK_SERVICE|UNIT_MASK_SOCKET|UNIT_MASK_DEVICE|UNIT_MASK_MOUNT|UNIT_MASK_AUTOMOUNT|UNIT_MASK_SWAP|UNIT_MASK_TARGET|UNIT_MASK_PATH|UNIT_MASK_TIMER|UNIT_MASK_SNAPSHOT|UNIT_MASK_SLICE|UNIT_MASK_SCOPE +Documentation,
[systemd-devel] [PATCH v4] run: introduce timer support option
Supported timer options --on-active=, --on-boot=, --on-startup=, --on-unit-active=, --on-unit-inactive=, --on-calendar=. Each options corresponding with OnActiveSec=, OnBootSec=, OnStartupSec=, OnUnitActiveSec=, OnUnitInactiveSec= of timer respectively. --- man/systemd-run.xml | 42 +++ src/libsystemd/sd-bus/bus-util.c | 14 +- src/run/run.c| 581 --- 3 files changed, 538 insertions(+), 99 deletions(-) diff --git a/man/systemd-run.xml b/man/systemd-run.xml index 28a9878..abac26c 100644 --- a/man/systemd-run.xml +++ b/man/systemd-run.xml @@ -210,6 +210,37 @@ along with systemd; If not, see http://www.gnu.org/licenses/. xi:include href=user-system-options.xml xpointer=host / xi:include href=user-system-options.xml xpointer=machine / + varlistentry +termoption--on-active=/option/term +termoption--on-boot=/option/term +termoption--on-startup=/option/term +termoption--on-unit-active=/option/term +termoption--on-unit-inactive=/option/term + +listitemparaDefines monotonic timers relative to different +starting points. Also see varnameOnActiveSec=/varname, +varnameOnBootSec=/varname, +varnameOnStartupSec=/varname, +varnameOnUnitActiveSec=/varname and +varnameOnUnitInactiveSec=/varname in + citerefentryrefentrytitlesystemd.timer/refentrytitlemanvolnum5/manvolnum/citerefentry. This +option has no effect in conjunction with +option--scope/option./para +/listitem + /varlistentry + + varlistentry +termoption--on-calendar=/option/term + +listitemparaDefines realtime (i.e. wallclock) timers with +calendar event expressions. Also see +varnameOnCalendar=/varname in + citerefentryrefentrytitlesystemd.timer/refentrytitlemanvolnum5/manvolnum/citerefentry. This +option has no effect in conjunction with +option--scope/option./para +/listitem + /varlistentry + xi:include href=standard-options.xml xpointer=help / xi:include href=standard-options.xml xpointer=version / /variablelist @@ -250,6 +281,16 @@ Sep 08 07:37:21 bupkis env[19948]: BOOT_IMAGE=/vmlinuz-3.11.0-0.rc5.git6.2.fc20. property./para programlisting# systemd-run -p BlockIOWeight=10 updatedb/programlisting + +paraThe following command will touch a file after 10 seconds./para + +programlisting# date; systemd-run --on-active=10 touch /tmp/hello +Mon Oct 27 20:02:57 KST 2014 +Running as unit run-66.timer. +# journalctl -u run-115.service +-- Logs begin at Mon 2014-10-27 19:44:57 KST, end at Mon 2014-10-27 20:03:15 KST. -- +Oct 27 20:03:15 container systemd[1]: Starting /bin/touch /tmp/hello... +Oct 27 20:03:15 container systemd[1]: Started /bin/touch /tmp/hello./programlisting /refsect1 refsect1 @@ -263,6 +304,7 @@ Sep 08 07:37:21 bupkis env[19948]: BOOT_IMAGE=/vmlinuz-3.11.0-0.rc5.git6.2.fc20. citerefentryrefentrytitlesystemd.slice/refentrytitlemanvolnum5/manvolnum/citerefentry, citerefentryrefentrytitlesystemd.exec/refentrytitlemanvolnum5/manvolnum/citerefentry, citerefentryrefentrytitlesystemd.resource-control/refentrytitlemanvolnum5/manvolnum/citerefentry, + citerefentryrefentrytitlesystemd.timer/refentrytitlemanvolnum5/manvolnum/citerefentry, citerefentryrefentrytitlemachinectl/refentrytitlemanvolnum1/manvolnum/citerefentry /para /refsect1 diff --git a/src/libsystemd/sd-bus/bus-util.c b/src/libsystemd/sd-bus/bus-util.c index bdaa449..0f1a89c 100644 --- a/src/libsystemd/sd-bus/bus-util.c +++ b/src/libsystemd/sd-bus/bus-util.c @@ -1372,7 +1372,8 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen if (STR_IN_SET(field, CPUAccounting, MemoryAccounting, BlockIOAccounting, - SendSIGHUP, SendSIGKILL)) { + SendSIGHUP, SendSIGKILL, + WakeSystem)) { r = parse_boolean(eq); if (r 0) { @@ -1533,6 +1534,17 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen r = sd_bus_message_append(m, v, i, sig); +} else if (streq(field, AccuracySec)) { +usec_t u; + +r = parse_sec(eq, u); +if (r 0) { +log_error(Failed to parse %s value %s, field, eq); +return -EINVAL; +} + +r = sd_bus_message_append(m, v, t, u); + } else { log_error(Unknown assignment %s., assignment); return -EINVAL; diff --git a/src/run/run.c b/src/run/run.c index 85eb052..e1ef7b4 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -30,6 +30,7 @@ #include env-util.h #include path-util.h #include bus-error.h +#include calendarspec.h static
Re: [systemd-devel] [PATCH] bootchart: add standalone bootchart service
On 12/03/2014 08:30 AM, Lennart Poettering wrote: On Sat, 15.11.14 15:42, WaLyong Cho (walyong@samsung.com) wrote: Heya, The suggested way to run boot chart is by specifying init=/usr/lib/systemd/systemd-bootchart on the kernel cmdline. What's the rationale behind making this a service? I mean, if it is started as service it races against other services and might thus not be able track services run in early boot. Can you please elaborate on the rationale for this patch? Yes, right. I'm also generate bootchart using kernel command line. But, in some kind of bootloader, it can be hard to modify the kernel command line. In our mobile phone, we do not allow to modify kernel command line to protect from hacking. In this case, this service can be useful even if some of processes can not be shown. But according to this service dependency, I think this bootchart service will be activated quite ahead of boot sequence. And as you said, this will race against others. That why this should NOT be enabled as default. But if someone want to get bootchart easily then he can get bootchart after just enable this. And also I think this can be useful to newbie. Isn't it? WaLyong --- Makefile.am| 9 + units/systemd-bootchart.service.in | 17 + 2 files changed, 26 insertions(+) create mode 100644 units/systemd-bootchart.service.in diff --git a/Makefile.am b/Makefile.am index 1aef242..b682606 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4428,6 +4428,15 @@ rootlibexec_PROGRAMS += \ dist_pkgsysconf_DATA += \ src/bootchart/bootchart.conf + +nodist_systemunit_DATA += \ +units/systemd-bootchart.service + +EXTRA_DIST += \ +units/systemd-bootchart.service.in + +CLEANFILES += \ +units/systemd-bootchart.service endif # -- diff --git a/units/systemd-bootchart.service.in b/units/systemd-bootchart.service.in new file mode 100644 index 000..aafc1ea --- /dev/null +++ b/units/systemd-bootchart.service.in @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Standalone Bootchart +Documentation=man:systemd-bootchart.service(1) man:bootchart.conf(5) +DefaultDependencies=no + +[Service] +ExecStart=@rootlibexecdir@/systemd-bootchart -r + +[Install] +WantedBy=sysinit.target -- 1.9.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel Lennart ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH] add configuration for smackfs root
The smackfs root was changed few month ago. But some of systems are still using old smackfs root. For compatibility, add smackfs root configure option. Default is /sys/fs/smackfs. --- Makefile.am | 1 + configure.ac| 7 +++ src/core/mount-setup.c | 2 +- src/core/smack-setup.c | 4 ++-- src/shared/smack-util.c | 2 +- 5 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Makefile.am b/Makefile.am index b52ff8e..c91c1b7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -192,6 +192,7 @@ AM_CPPFLAGS = \ -DUDEVLIBEXECDIR=\$(udevlibexecdir)\ \ -DPOLKIT_AGENT_BINARY_PATH=\$(bindir)/pkttyagent\ \ -DQUOTACHECK=\$(QUOTACHECK)\ \ + -DSMACKFSROOT=\$(SMACKFSROOT)\ \ -DKEXEC=\$(KEXEC)\ \ -DLIBDIR=\$(libdir)\ \ -DROOTLIBDIR=\$(rootlibdir)\ \ diff --git a/configure.ac b/configure.ac index a4e91e3..97cd5ad 100644 --- a/configure.ac +++ b/configure.ac @@ -661,6 +661,13 @@ AS_HELP_STRING([--with-smack-run-label=STRING], [AC_DEFINE_UNQUOTED(SMACK_RUN_LABEL, [$withval], [Run with a smack label])], []) +AC_ARG_WITH(smackfs-root, +AS_HELP_STRING([--with-smackfs-root=PATH], +[Specify the smackfs root [/sys/fs/smackfs]]), +[SMACKFSROOT=$withval], +[SMACKFSROOT=/sys/fs/smackfs]) +AC_SUBST(SMACKFSROOT) + if test x${have_smack} = xyes ; then AC_DEFINE(HAVE_SMACK, 1, [Define if SMACK is available]) fi diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c index df9d9da..01fed83 100644 --- a/src/core/mount-setup.c +++ b/src/core/mount-setup.c @@ -81,7 +81,7 @@ static const MountPoint mount_table[] = { { securityfs, /sys/kernel/security, securityfs, NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL, MNT_NONE }, #ifdef HAVE_SMACK -{ smackfs,/sys/fs/smackfs, smackfs, smackfsdef=*, MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME, +{ smackfs,SMACKFSROOT, smackfs, smackfsdef=*, MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME, mac_smack_use, MNT_FATAL }, { tmpfs, /dev/shm, tmpfs, mode=1777,smackfsroot=*, MS_NOSUID|MS_NODEV|MS_STRICTATIME, mac_smack_use, MNT_FATAL }, diff --git a/src/core/smack-setup.c b/src/core/smack-setup.c index d0fd180..b81d76f 100644 --- a/src/core/smack-setup.c +++ b/src/core/smack-setup.c @@ -124,7 +124,7 @@ int mac_smack_setup(bool *loaded_policy) { assert(loaded_policy); -r = write_rules(/sys/fs/smackfs/load2, SMACK_CONFIG); +r = write_rules(SMACKFSROOT /load2, SMACK_CONFIG); switch(r) { case -ENOENT: log_debug(Smack is not enabled in the kernel.); @@ -148,7 +148,7 @@ int mac_smack_setup(bool *loaded_policy) { SMACK_RUN_LABEL, strerror(-r)); #endif -r = write_rules(/sys/fs/smackfs/cipso2, CIPSO_CONFIG); +r = write_rules(SMACKFSROOT /cipso2, CIPSO_CONFIG); switch(r) { case -ENOENT: log_debug(Smack/CIPSO is not enabled in the kernel.); diff --git a/src/shared/smack-util.c b/src/shared/smack-util.c index b6c9643..551a234 100644 --- a/src/shared/smack-util.c +++ b/src/shared/smack-util.c @@ -36,7 +36,7 @@ bool mac_smack_use(void) { static int cached_use = -1; if (cached_use 0) -cached_use = access(/sys/fs/smackfs/, F_OK) = 0; +cached_use = access(SMACKFSROOT, F_OK) = 0; return cached_use; #else -- 1.9.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH v3] smack: introduce new SmackProcessLabel option
In service file, if the file has some of special SMACK label in ExecStart= and systemd has no permission for the special SMACK label then permission error will occurred. To resolve this, systemd should be able to set its SMACK label to something accessible of ExecStart=. So introduce new SmackProcessLabel. If label is specified with SmackProcessLabel= then the child systemd will set its label to that. To successfully execute the ExecStart=, accessible label should be specified with SmackProcessLabel=. Additionally, by SMACK policy, if the file in ExecStart= has no SMACK64EXEC then the executed process will have given label by SmackProcessLabel=. But if the file has SMACK64EXEC then the SMACK64EXEC label will be overridden. --- man/systemd.exec.xml | 19 + src/core/dbus-execute.c | 19 + src/core/execute.c| 11 src/core/execute.h| 3 +++ src/core/load-fragment-gperf.gperf.m4 | 7 +++-- src/core/load-fragment.c | 50 +++ src/core/load-fragment.h | 1 + src/shared/exit-status.h | 1 + src/shared/smack-util.c | 20 ++ src/shared/smack-util.h | 1 + 10 files changed, 130 insertions(+), 2 deletions(-) diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index e9af4ab..ea2130d 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -1138,6 +1138,25 @@ /varlistentry varlistentry + termvarnameSmackProcessLabel=/varname/term + +listitemparaSet the SMACK security +label to run given executable file in +varnameExecStart=/varname. The +executable file has no SMACK64EXEC +label then the executed process run +with this label. But if the file has +SMACK64EXEC label then executed +process run with its own SMACK64EXEC +label. If no label set, defaults to +label of systemd by SMACK policy. This +directive is ignored if SMACK is +disabled. If prefixed +byliteral-/literal, all +errorswillbe ignored./para/listitem +/varlistentry + +varlistentry termvarnameIgnoreSIGPIPE=/varname/term listitemparaTakes a boolean diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index 9276da4..bbcd610 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -508,6 +508,24 @@ static int property_get_apparmor_profile( return sd_bus_message_append(reply, (bs), c-apparmor_profile_ignore, c-apparmor_profile); } +static int property_get_smack_process_label( +sd_bus *bus, +const char *path, +const char *interface, +const char *property, +sd_bus_message *reply, +void *userdata, +sd_bus_error *error) { + +ExecContext *c = userdata; + +assert(bus); +assert(reply); +assert(c); + +return sd_bus_message_append(reply, (bs), c-smack_process_label_ignore, c-smack_process_label); +} + static int property_get_personality( sd_bus *bus, const char *path, @@ -636,6 +654,7 @@ const sd_bus_vtable bus_exec_vtable[] = { SD_BUS_PROPERTY(UtmpIdentifier, s, NULL, offsetof(ExecContext, utmp_id), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY(SELinuxContext, (bs), property_get_selinux_context, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY(AppArmorProfile, (bs), property_get_apparmor_profile, 0, SD_BUS_VTABLE_PROPERTY_CONST), +SD_BUS_PROPERTY(SmackProcessLabel, (bs), property_get_smack_process_label, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY(IgnoreSIGPIPE, b, bus_property_get_bool, offsetof(ExecContext, ignore_sigpipe), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY(NoNewPrivileges, b, bus_property_get_bool, offsetof(ExecContext, no_new_privileges), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY(SystemCallFilter, (bas), property_get_syscall_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST), diff --git a/src/core/execute.c b/src/core/execute.c index 5cfd4a1..e6c1999 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -83,6 +83,7 @@ #include af-list.h #include mkdir.h #include apparmor-util.h +#include smack-util.h #include bus-kernel.h #include label.h @@ -1618,6 +1619,16 @@ static int
Re: [systemd-devel] [PATCH v2] smack: introduce new SmackLabelAccess option
On 11/24/2014 02:36 AM, Zbigniew Jędrzejewski-Szmek wrote: On Fri, Nov 21, 2014 at 03:16:01PM +0900, WaLyong Cho wrote: In case of systemd has _ label and run as root, if a service file has User= option and the command line file has a special SMACK label then systemd will fail to access to given file. SMACK label is ignored for root uid processes. But if a service has a User= then systemd will call setresuid() in the child process. After then it no more root uid. So it should have some of accessable label for the command. To set the before the uid is changed, introduce new SmackLabelAccess=. ^ This provides the motivation. Please add a paragraph which describes the functionality. I'm still bothered by the name SmackLabelAccess. To recap the discussion, SMACK64EXEC is set on a file and it is an analogue of setuid bit, except that it changes the 'current' smack label instead of the UID. The analogy goes pretty far, since the value set with User= may be overriden by the setuid bit on the file, and SmackLabelAccess= may be be overriden by SMACK64EXEC on the file. We use User= to set the user, so the name SmackLabel= would be the most appropriate. But like Lennart said, SmackLabel= is already used to label the socket file, so we need something different. By process of elimination you arrived as SmackLabelAccess=. I don't like the name because Access is misleading, because it suggests that the label is only used when starting the process. But the normal case is that SMACK64EXEC is *not* set, so the process will run with this label until the end. Please just call it SmackProcessLabel. I'm agree. I will change. --- man/systemd.exec.xml | 15 +++ src/core/dbus-execute.c | 19 + src/core/execute.c| 11 src/core/execute.h| 3 +++ src/core/load-fragment-gperf.gperf.m4 | 7 +++-- src/core/load-fragment.c | 50 +++ src/core/load-fragment.h | 1 + src/shared/exit-status.h | 1 + src/shared/smack-util.c | 20 ++ src/shared/smack-util.h | 1 + 10 files changed, 126 insertions(+), 2 deletions(-) diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index e9af4ab..5381946 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -1138,6 +1138,21 @@ /varlistentry varlistentry + termvarnameSmackLabelAccess=/varname/term + +listitemparaSet the SMACK security +label to access given executable file in +varnameExecStart=/varname. If my analysis above is correct this should be reworded - it's not just for access. Yes, if the file has SMACK64EXEC then the label only be used for access checking. But if that file has no SMACK64EXEC then the label is also set as the subject of executed process. The label is used also for checking so I'd like to just add when if the file has no SMACK64EXEC then the executed process will have specified label. This option only has effect with +varnameUser=/varname. Is this entirely true? If User= is not given, and SMACK64EXEC is not set, then this will determine the label of the process iiuc. You are totally right. I just focused on accessing to execute. As you said, if the file has no SMACK64EXEC and SmackProcessLabel= is given then the executed process will has given label. I will change this. Because, SMACK access checking is ignored +for root uid processes. If varnameSmackLabelAccess=/varname is +specified with varnameUser=/varname, forked child systemd process +set its /proc/$PID/attr/current to specified label in +varnameSmackLabelAccess=/varname. This directive is ignored if +SMACK is disabled. If prefixed by literal-/literal, all errors +will be ignored./para/listitem Please describe the functionality in higher level language, what the option does. Don't go into the details of SMACK. OK, I will. Please mention that empty rhs can be used to unset. Oh, I didn't imagine this. But I can't find some other proper operation. So I think if rhs was empty then just do like the config was not given. Really thanks to read. WaLyong +/varlistentry + +varlistentry termvarnameIgnoreSIGPIPE=/varname/term listitemparaTakes a boolean diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index 9276da4..0764a42 100644
[systemd-devel] [PATCH v2] smack: introduce new SmackLabelAccess option
In case of systemd has _ label and run as root, if a service file has User= option and the command line file has a special SMACK label then systemd will fail to access to given file. SMACK label is ignored for root uid processes. But if a service has a User= then systemd will call setresuid() in the child process. After then it no more root uid. So it should have some of accessable label for the command. To set the before the uid is changed, introduce new SmackLabelAccess=. --- man/systemd.exec.xml | 15 +++ src/core/dbus-execute.c | 19 + src/core/execute.c| 11 src/core/execute.h| 3 +++ src/core/load-fragment-gperf.gperf.m4 | 7 +++-- src/core/load-fragment.c | 50 +++ src/core/load-fragment.h | 1 + src/shared/exit-status.h | 1 + src/shared/smack-util.c | 20 ++ src/shared/smack-util.h | 1 + 10 files changed, 126 insertions(+), 2 deletions(-) diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index e9af4ab..5381946 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -1138,6 +1138,21 @@ /varlistentry varlistentry + termvarnameSmackLabelAccess=/varname/term + +listitemparaSet the SMACK security +label to access given executable file in +varnameExecStart=/varname. This option only has effect with +varnameUser=/varname. Because, SMACK access checking is ignored +for root uid processes. If varnameSmackLabelAccess=/varname is +specified with varnameUser=/varname, forked child systemd process +set its /proc/$PID/attr/current to specified label in +varnameSmackLabelAccess=/varname. This directive is ignored if +SMACK is disabled. If prefixed by literal-/literal, all errors +will be ignored./para/listitem +/varlistentry + +varlistentry termvarnameIgnoreSIGPIPE=/varname/term listitemparaTakes a boolean diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index 9276da4..0764a42 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -508,6 +508,24 @@ static int property_get_apparmor_profile( return sd_bus_message_append(reply, (bs), c-apparmor_profile_ignore, c-apparmor_profile); } +static int property_get_smack_label_access( +sd_bus *bus, +const char *path, +const char *interface, +const char *property, +sd_bus_message *reply, +void *userdata, +sd_bus_error *error) { + +ExecContext *c = userdata; + +assert(bus); +assert(reply); +assert(c); + +return sd_bus_message_append(reply, (bs), c-smack_label_access_ignore, c-smack_label_access); +} + static int property_get_personality( sd_bus *bus, const char *path, @@ -636,6 +654,7 @@ const sd_bus_vtable bus_exec_vtable[] = { SD_BUS_PROPERTY(UtmpIdentifier, s, NULL, offsetof(ExecContext, utmp_id), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY(SELinuxContext, (bs), property_get_selinux_context, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY(AppArmorProfile, (bs), property_get_apparmor_profile, 0, SD_BUS_VTABLE_PROPERTY_CONST), +SD_BUS_PROPERTY(SmackLabelAccess, (bs), property_get_smack_label_access, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY(IgnoreSIGPIPE, b, bus_property_get_bool, offsetof(ExecContext, ignore_sigpipe), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY(NoNewPrivileges, b, bus_property_get_bool, offsetof(ExecContext, no_new_privileges), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY(SystemCallFilter, (bas), property_get_syscall_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST), diff --git a/src/core/execute.c b/src/core/execute.c index 5cfd4a1..6dd4cdd 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -83,6 +83,7 @@ #include af-list.h #include mkdir.h #include apparmor-util.h +#include smack-util.h #include bus-kernel.h #include label.h @@ -1618,6 +1619,16 @@ static int exec_child(ExecCommand *command, } } +#ifdef HAVE_SMACK +if (context-smack_label_access) { +err = mac_smack_apply_pid(0, context-smack_label_access); +if (err 0) { +*error =
Re: [systemd-devel] Starting configurable set of services first
On 10/28/2014 01:06 AM, Umut Tezduyar Lindskog wrote: On Wed, Oct 22, 2014 at 7:44 PM, Lennart Poettering lenn...@poettering.net wrote: On Tue, 02.09.14 10:06, Umut Tezduyar Lindskog (u...@tezduyar.com) wrote: Hi, I would like to start a configurable set of services first and the services are wanted by multi-user.target. I am using a service to jump to multi-user.target and I was wondering if we can support this use case natively by systemd. multi-user.target.wants A.service B.service C.service D.service default.target stage.target stage.target.wants (These are set by generator) A.service C.service switcher.service switcher.service (This is generated by generator) [Unit] Description=Switch to multi-user.targe After=A.service C.service [Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/bin/systemctl --no-block start multi-user.target This way I am jumping from one target to another target during runtime. - What stage.target wants is dynamic. If it was static, my job would have been very simple. - I am aware of StartupCPUShares but it is not the ultimate solution A) there is a configurable minimum quota in CFS which still gives CPU to other processes. B) We still fork other processes and this causes changes in timeout values of other processes. - Adding dynamically After= to B and D service files is not the ultimate solution either because B and D might be socket/dbus activated by A or C. Should this be something we should support natively by systemd? As discussed at th systemd hackfest: I am a bit conservative about this as it introduces plenty chance for deadlocks, where services might trigger/request some other unit but we'd delay it until the later stage... I think the implementation you chose is actually pretty good. I am not sure though that we should do this upstream. I mean, I really would prefer if we'd dump as much work as possible on the IO elevator and CPU scheduler, and then adjust the priorities of it to give hints what matters more. Trying to second-guess the elevator and scheduler in userspace feels a bit like chickening out to me, even though I am sure that it might be something that one has to do for now, in the real world... I am not agreeing on this. Once you fork the process, it will always get some CPU even though you play with cpu.shares, sched_latency_ns, sched_min_granularity_ns. My goal is not forking it at all until high priority services are activated. Just like Before=, After=. I have similar problem with this. And I'd introduced extra dependencies. But Lennard said same like. :) http://lists.freedesktop.org/archives/systemd-devel/2014-February/017457.html http://lists.freedesktop.org/archives/systemd-devel/2014-March/017524.html So I just keep that as our downstream patch. (Some was enhanced. Using hash to avoid compare line by line. just trivial. basic concept is same.) The summary is.. I add an option and named that default extra dependency. (I couldn't imagine any abbreviation.) And make if service was not listed on ignore extra dependency and has no DefaultDependencies=no option then that service is started after all of default extra dependency units. But we also still have many After=/Before= options in many unit files. :) I agree about Lennard's thought. I can easily break a ordering cycle or make circular dependencies. But we don't have other option. In our system, cpu usage go up to 100% almost just after systemd start dispatching from job queue. Until default.target is activated. If new unit come up to the race round then that will make more and more slower. I hope we can find some of general way to resolve. WaLyong There's one change I'd really like to see done though in systemd, that might make things nicer for you. Currently, it's undefined in systemd which job is dispatched first, if multiple jobs can be executed. That means when we are about to fork off a number of processes there's no way to control which one gets forked off first. I'd be willing to merge a patch that turns this into a prioq, so that some priority value can be configured (or automatically derived) for each unit, and the one with the highest priority would win, and be processed first. This would not provide you with everything what you want, but would make things a bit nicer when we dump all possible work on the scheduler/elevator, because after all we cannot really dump all work at the same time, and hence should at least give you control in which order to dump it, if you follow what I mean. I have understood your propose with the exception of one thing. When do we start dispatching low priority jobs? When the high priority jobs are dispatched/forked or when the high priority jobs are dispatched/activated? Umut Lennart -- Lennart Poettering, Red Hat ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org
[systemd-devel] [PATCH] README: notice kernel config for CPUQuota
--- README | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README b/README index aefb349..70d1105 100644 --- a/README +++ b/README @@ -82,6 +82,9 @@ REQUIREMENTS: CONFIG_CGROUP_SCHED CONFIG_FAIR_GROUP_SCHED +Required for CPUQuota in resource control unit settings + CONFIG_CFS_BANDWIDTH + For systemd-bootchart, several proc debug interfaces are required: CONFIG_SCHEDSTATS CONFIG_SCHED_DEBUG -- 1.9.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] set rr scheduler failed with cpushares
Hello, I'd made two different services. One has *CPUSchedulingPolicy=rr* and the others has *CPUShares=*. # cat foo.service [Unit] Description=foo has CPUSchedulingPolicy= [Service] RemainAfterExit=yes ExecStart=/bin/true CPUSchedulingPolicy=rr # cat bar.service [Unit] Description=bar has CPUShares= [Service] RemainAfterExit=yes ExecStart=/usr/bin/hello.sh CPUShares=100 foo.service is activated well if bar.service is not activated. # systemctl start foo.service; systemctl status foo.service bar.service foo.service - foo has CPUSchedulingPolicy= Loaded: loaded (/usr/lib/systemd/system/foo.service; static) Active: active (exited) since Mon 2014-11-17 23:32:44 KST; 5s ago Process: 2702 ExecStart=/bin/true (code=exited, status=0/SUCCESS) Main PID: 2702 (code=exited, status=0/SUCCESS) bar.service - bar has CPUShares= Loaded: loaded (/usr/lib/systemd/system/bar.service; static) Active: inactive (dead) But if bar.service(what has CPUShares=) then foo.service failed on sched_setscheduler(). EPERM was returned. # systemctl start bar.service; systemctl restart foo.service; systemctl status foo.service bar.service foo.service - foo has CPUSchedulingPolicy= Loaded: loaded (/usr/lib/systemd/system/foo.service; static) Active: active (exited) (Result: exit-code) since Mon 2014-11-17 23:34:48 KST; 75ms ago Process: 3222 ExecStart=/bin/true (code=exited, status=214/SETSCHEDULER) Main PID: 3222 (code=exited, status=214/SETSCHEDULER) Nov 17 23:34:48 KIRAN systemd[1]: Started foo has CPUSchedulingPolicy=. Nov 17 23:34:48 KIRAN systemd[1]: foo.service: main process exited, code=ex...ER bar.service - bar has CPUShares= Loaded: loaded (/usr/lib/systemd/system/bar.service; static) Active: active (running) since Mon 2014-11-17 23:34:48 KST; 296ms ago Main PID: 3218 (hello.sh) CGroup: /system.slice/bar.service ├─3218 /bin/bash /usr/bin/hello.sh └─3221 sleep 1 Could anyone help me? Thanks, WaLyong ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH] bootchart: add standalone bootchart service
--- Makefile.am| 9 + units/systemd-bootchart.service.in | 17 + 2 files changed, 26 insertions(+) create mode 100644 units/systemd-bootchart.service.in diff --git a/Makefile.am b/Makefile.am index 1aef242..b682606 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4428,6 +4428,15 @@ rootlibexec_PROGRAMS += \ dist_pkgsysconf_DATA += \ src/bootchart/bootchart.conf + +nodist_systemunit_DATA += \ + units/systemd-bootchart.service + +EXTRA_DIST += \ + units/systemd-bootchart.service.in + +CLEANFILES += \ + units/systemd-bootchart.service endif # -- diff --git a/units/systemd-bootchart.service.in b/units/systemd-bootchart.service.in new file mode 100644 index 000..aafc1ea --- /dev/null +++ b/units/systemd-bootchart.service.in @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Standalone Bootchart +Documentation=man:systemd-bootchart.service(1) man:bootchart.conf(5) +DefaultDependencies=no + +[Service] +ExecStart=@rootlibexecdir@/systemd-bootchart -r + +[Install] +WantedBy=sysinit.target -- 1.9.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH v2 2/2] bootchart: escape non printable process name
--- src/bootchart/svg.c | 10 +++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/bootchart/svg.c b/src/bootchart/svg.c index faf377e..e5569e1 100644 --- a/src/bootchart/svg.c +++ b/src/bootchart/svg.c @@ -39,6 +39,7 @@ #include svg.h #include bootchart.h #include list.h +#include utf8.h #define time_to_graph(t) ((t) * arg_scale_x) #define ps_to_graph(n) ((n) * arg_scale_y) @@ -1006,12 +1007,15 @@ static void svg_ps_bars(void) { /* pass 2 - ps boxes */ ps = ps_first; while ((ps = get_next_ps(ps))) { -_cleanup_free_ char *enc_name = NULL; +_cleanup_free_ char *enc_name = NULL, *escaped = NULL; double endtime; double starttime; int t; -enc_name = xml_comment_encode(ps-name); +if (!utf8_is_printable(ps-name, strlen(ps-name))) +escaped = utf8_escape_non_printable(ps-name); + +enc_name = xml_comment_encode(escaped ? escaped : ps-name); if (!enc_name) continue; @@ -1100,7 +1104,7 @@ static void svg_ps_bars(void) { svg( text x=\%.03f\ y=\%.03f\![CDATA[%s]] [%i]tspan class=\run\%.03fs/tspan %s/text\n, time_to_graph(w - graph_start) + 5.0, ps_to_graph(j) + 14.0, -ps-name, +escaped ? escaped : ps-name, ps-pid, (ps-last-runtime - ps-first-runtime) / 10.0, arg_show_cgroup ? ps-cgroup : ); -- 1.9.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH v2 1/2] utf8: intruduce utf8_escape_non_printable
--- src/shared/utf8.c| 39 +++ src/shared/utf8.h| 1 + src/test/test-utf8.c | 25 + 3 files changed, 65 insertions(+) diff --git a/src/shared/utf8.c b/src/shared/utf8.c index 8702ceb..0b6c38e 100644 --- a/src/shared/utf8.c +++ b/src/shared/utf8.c @@ -212,6 +212,45 @@ char *utf8_escape_invalid(const char *str) { return p; } +char *utf8_escape_non_printable(const char *str) { +char *p, *s; + +assert(str); + +p = s = malloc(strlen(str) * 4 + 1); +if (!p) +return NULL; + +while (*str) { +int len; + +len = utf8_encoded_valid_unichar(str); +if (len 0) { +if (utf8_is_printable(str, len)) { +s = mempcpy(s, str, len); +str += len; +} else { +if ((*str ' ') || (*str = 127)) { +*(s++) = '\\'; +*(s++) = 'x'; +*(s++) = hexchar((int) *str 4); +*(s++) = hexchar((int) *str); +} else +*(s++) = *str; + +str += 1; +} +} else { +s = mempcpy(s, UTF8_REPLACEMENT_CHARACTER, strlen(UTF8_REPLACEMENT_CHARACTER)); +str += 1; +} +} + +*s = '\0'; + +return p; +} + char *ascii_is_valid(const char *str) { const char *p; diff --git a/src/shared/utf8.h b/src/shared/utf8.h index c087995..1fe1a35 100644 --- a/src/shared/utf8.h +++ b/src/shared/utf8.h @@ -30,6 +30,7 @@ const char *utf8_is_valid(const char *s) _pure_; char *ascii_is_valid(const char *s) _pure_; char *utf8_escape_invalid(const char *s); +char *utf8_escape_non_printable(const char *str); bool utf8_is_printable_newline(const char* str, size_t length, bool newline) _pure_; _pure_ static inline bool utf8_is_printable(const char* str, size_t length) { diff --git a/src/test/test-utf8.c b/src/test/test-utf8.c index b7d988f..6dde63c 100644 --- a/src/test/test-utf8.c +++ b/src/test/test-utf8.c @@ -66,12 +66,37 @@ static void test_utf8_escaping(void) { assert_se(utf8_is_valid(p3)); } +static void test_utf8_escaping_printable(void) { +_cleanup_free_ char *p1, *p2, *p3, *p4, *p5; + +p1 = utf8_escape_non_printable(goo goo goo); +puts(p1); +assert_se(utf8_is_valid(p1)); + +p2 = utf8_escape_non_printable(\341\204\341\204); +puts(p2); +assert_se(utf8_is_valid(p2)); + +p3 = utf8_escape_non_printable(\341\204); +puts(p3); +assert_se(utf8_is_valid(p3)); + +p4 = utf8_escape_non_printable(ąę\n가너도루\n1234\n\341\204\341\204\n\001 \019\20\a); +puts(p4); +assert_se(utf8_is_valid(p4)); + +p5 = utf8_escape_non_printable(\001 \019\20\a); +puts(p5); +assert_se(utf8_is_valid(p5)); +} + int main(int argc, char *argv[]) { test_utf8_is_valid(); test_utf8_is_printable(); test_ascii_is_valid(); test_utf8_encoded_valid_unichar(); test_utf8_escaping(); +test_utf8_escaping_printable(); return 0; } -- 1.9.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH v3 3/4] unit: add UnitMask enum and get unit scope(mask) api from property
--- Makefile.am | 7 ++ src/shared/.gitignore| 1 + src/shared/unit-name.c | 22 src/shared/unit-name.h | 26 + src/shared/unit-property-scope.gperf | 202 +++ 5 files changed, 258 insertions(+) create mode 100644 src/shared/unit-property-scope.gperf diff --git a/Makefile.am b/Makefile.am index 0b32639..a221a69 100644 --- a/Makefile.am +++ b/Makefile.am @@ -819,6 +819,7 @@ libsystemd_shared_la_SOURCES = \ src/shared/cgroup-show.h \ src/shared/unit-name.c \ src/shared/unit-name.h \ + src/shared/unit-property-scope.c \ src/shared/utmp-wtmp.h \ src/shared/watchdog.c \ src/shared/watchdog.h \ @@ -907,6 +908,12 @@ libsystemd_shared_la_CFLAGS = \ $(SECCOMP_CFLAGS) \ -pthread +EXTRA_DIST += \ + src/shared/unit-property-scope.gperf + +CLEANFILES += \ + src/shared/unit-property-scope.c + libsystemd_shared_la_LIBADD = \ $(CAP_LIBS) diff --git a/src/shared/.gitignore b/src/shared/.gitignore index 61709e8..e7faa23 100644 --- a/src/shared/.gitignore +++ b/src/shared/.gitignore @@ -10,3 +10,4 @@ /arphrd-from-name.h /arphrd-list.txt /arphrd-to-name.h +/unit-property-scope.c diff --git a/src/shared/unit-name.c b/src/shared/unit-name.c index 2ef8545..e4669dd 100644 --- a/src/shared/unit-name.c +++ b/src/shared/unit-name.c @@ -621,3 +621,25 @@ static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = { }; DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency); + +static UnitMask unit_get_mask_from_property(const char *property) { +const unit_property_scope_mapping *m; + +assert(property); + +m = unit_property_scope_mapping_lookup(property, strlen(property)); +if (m) +return m-scope; + +return _UNIT_MASK_MAX; + +} + +bool unit_can_have_property(UnitType t, const char *property) { +UnitMask m; + +assert(property); + +m = unit_get_mask_from_property(property); +return !!((1ULL t) m); +} diff --git a/src/shared/unit-name.h b/src/shared/unit-name.h index daeb56a..e1d4e27 100644 --- a/src/shared/unit-name.h +++ b/src/shared/unit-name.h @@ -28,6 +28,7 @@ #define UNIT_NAME_MAX 256 typedef enum UnitType UnitType; +typedef enum UnitMask UnitMask; typedef enum UnitLoadState UnitLoadState; typedef enum UnitDependency UnitDependency; @@ -49,6 +50,23 @@ enum UnitType { _UNIT_TYPE_INVALID = -1 }; +enum UnitMask { +UNIT_MASK_SERVICE = 1ULL UNIT_SERVICE, +UNIT_MASK_SOCKET= 1ULL UNIT_SOCKET, +UNIT_MASK_BUSNAME = 1ULL UNIT_BUSNAME, +UNIT_MASK_TARGET= 1ULL UNIT_TARGET, +UNIT_MASK_SNAPSHOT = 1ULL UNIT_SNAPSHOT, +UNIT_MASK_DEVICE= 1ULL UNIT_DEVICE, +UNIT_MASK_MOUNT = 1ULL UNIT_MOUNT, +UNIT_MASK_AUTOMOUNT = 1ULL UNIT_AUTOMOUNT, +UNIT_MASK_SWAP = 1ULL UNIT_SWAP, +UNIT_MASK_TIMER = 1ULL UNIT_TIMER, +UNIT_MASK_PATH = 1ULL UNIT_PATH, +UNIT_MASK_SLICE = 1ULL UNIT_SLICE, +UNIT_MASK_SCOPE = 1ULL UNIT_SCOPE, +_UNIT_MASK_MAX = 1ULL _UNIT_TYPE_MAX, +}; + enum UnitLoadState { UNIT_STUB = 0, UNIT_LOADED, @@ -163,3 +181,11 @@ int build_subslice(const char *slice, const char*name, char **subslice); const char *unit_dependency_to_string(UnitDependency i) _const_; UnitDependency unit_dependency_from_string(const char *s) _pure_; + +struct unit_property_scope_mapping { +const char* property; +UnitMask scope; +}; +typedef struct unit_property_scope_mapping unit_property_scope_mapping; +const unit_property_scope_mapping* unit_property_scope_mapping_lookup (register const char *str, register unsigned int len); +bool unit_can_have_property(UnitType t, const char *property); diff --git a/src/shared/unit-property-scope.gperf b/src/shared/unit-property-scope.gperf new file mode 100644 index 000..bbcfcba --- /dev/null +++ b/src/shared/unit-property-scope.gperf @@ -0,0 +1,202 @@ +%{ +#include unit-name.h +#include bus-util.h +%} +unit_property_scope_mapping; +%null_strings +%language=ANSI-C +%define slot-name property +%define hash-function-name bus_property_scope_mapping_hash +%define lookup-function-name unit_property_scope_mapping_lookup +%readonly-tables +%omit-struct-type +%struct-type +%includes +%% +Description, UNIT_MASK_SERVICE|UNIT_MASK_SOCKET|UNIT_MASK_DEVICE|UNIT_MASK_MOUNT|UNIT_MASK_AUTOMOUNT|UNIT_MASK_SWAP|UNIT_MASK_TARGET|UNIT_MASK_PATH|UNIT_MASK_TIMER|UNIT_MASK_SNAPSHOT|UNIT_MASK_SLICE|UNIT_MASK_SCOPE +Documentation,
[systemd-devel] [PATCH v3 1/4] bus: StartTransientUnit can have aux unit
--- src/core/dbus-manager.c | 123 +--- 1 file changed, 105 insertions(+), 18 deletions(-) diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index c54abd3..bba4b27 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -615,6 +615,93 @@ static int method_set_unit_properties(sd_bus *bus, sd_bus_message *message, void return bus_unit_method_set_properties(bus, message, u, error); } +static int transient_unit_from_message( +Manager *m, +sd_bus_message *message, +const char *name, +Unit **unit, +sd_bus_error *error) { + +Unit *u; +int r; + +assert(m); +assert(message); +assert(name); + +r = manager_load_unit(m, name, NULL, error, u); +if (r 0) +return r; + +if (u-load_state != UNIT_NOT_FOUND || +set_size(u-dependencies[UNIT_REFERENCED_BY]) 0) +return sd_bus_error_setf(error, + BUS_ERROR_UNIT_EXISTS, + Unit %s already exists., + name); + +/* OK, the unit failed to load and is unreferenced, now let's + * fill in the transient data instead */ +r = unit_make_transient(u); +if (r 0) +return r; + +/* Set our properties */ +r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error); +if (r 0) +return r; + +*unit = u; + +return 0; +} + +static int try_aux_units_in_message( +Manager *m, +sd_bus_message *message, +sd_bus_error *error) { + +Unit *u; +char *name = NULL; +int r; + +assert(m); +assert(message); + +r = sd_bus_message_enter_container(message, 'a', (sa(sv))); +if (r 0) +return r; + +while ((r = sd_bus_message_enter_container(message, 'r', sa(sv))) 0) { +if (r = 0) +return r; + +r = sd_bus_message_read(message, s, name); +if (r 0) +return r; + +r = transient_unit_from_message(m, message, name, u, error); +if (r 0 r != -EEXIST) +return r; + +r = sd_bus_message_exit_container(message); +if (r 0) +return r; + +r = unit_load(u); +if (r 0) +return r; +} +if (r 0) +return r; + +r = sd_bus_message_exit_container(message); +if (r 0) +return r; + +return 0; +} + static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { const char *name, *smode; Manager *m = userdata; @@ -631,7 +718,9 @@ static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, voi if (r 0) return r; if (r == 0) -return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ +/* No authorization for now, but the async polkit + * stuff will call us again when it has it */ +return 1; r = sd_bus_message_read(message, ss, name, smode); if (r 0) @@ -639,34 +728,32 @@ static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, voi t = unit_name_to_type(name); if (t 0) -return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, Invalid unit type.); +return sd_bus_error_setf(error, + SD_BUS_ERROR_INVALID_ARGS, + Invalid unit type.); if (!unit_vtable[t]-can_transient) -return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, Unit type %s does not support transient units., unit_type_to_string(t)); - -mode = job_mode_from_string(smode); -if (mode 0) -return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, Job mode %s is invalid., smode); +return sd_bus_error_setf(error, + SD_BUS_ERROR_INVALID_ARGS, + Unit type %s does not support transient units., + unit_type_to_string(t)); r = mac_selinux_access_check(message, start, error); if (r 0) return r; -r = manager_load_unit(m, name, NULL, error, u); -if (r 0) -return r; - -if (u-load_state != UNIT_NOT_FOUND || set_size(u-dependencies[UNIT_REFERENCED_BY]) 0) -
[systemd-devel] [PATCH v3 2/4] timer: timer can be a transient unit
--- src/core/dbus-timer.c | 159 ++ src/core/dbus-timer.h | 3 + src/core/timer.c | 4 ++ 3 files changed, 166 insertions(+) diff --git a/src/core/dbus-timer.c b/src/core/dbus-timer.c index f1f8c54..e916f5a 100644 --- a/src/core/dbus-timer.c +++ b/src/core/dbus-timer.c @@ -24,6 +24,8 @@ #include dbus-unit.h #include dbus-timer.h #include bus-util.h +#include errno-list.h +#include strv.h static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, timer_result, TimerResult); @@ -183,3 +185,160 @@ const sd_bus_vtable bus_timer_vtable[] = { SD_BUS_PROPERTY(WakeSystem, b, bus_property_get_bool, offsetof(Timer, wake_system), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_VTABLE_END }; + +static int bus_timer_set_transient_property( +Timer *t, +const char *name, +sd_bus_message *message, +UnitSetPropertiesMode mode, +sd_bus_error *error) { + +const char *str; +int r; + +assert(t); +assert(name); +assert(message); + +if (STR_IN_SET(name, + OnActiveSec, + OnBootSec, + OnStartupSec, + OnUnitActiveSec, + OnUnitInactiveSec)) { + +TimerValue *v; +TimerBase b = _TIMER_BASE_INVALID; +usec_t u = 0; + +b = timer_base_from_string(name); +if (b 0) +return 0; + +r = sd_bus_message_read(message, t, u); +if (r 0) +return r; + +if (mode != UNIT_CHECK) { +unit_write_drop_in_private_format(UNIT(t), + mode, + name, + %s=%lu\n, + name, + u); + +v = new0(TimerValue, 1); +if (!v) +return -ENOMEM; + +v-base = b; +v-value = u; + +LIST_PREPEND(value, t-values, v); +} + +return 1; + +} else if (streq(name, OnCalendar)) { + +TimerValue *v; +CalendarSpec *c = NULL; + +r = sd_bus_message_read(message, s, str); +if (r 0) +return r; + +if (mode != UNIT_CHECK) { +r = calendar_spec_from_string(str, c); +if (r 0) +return r; + +unit_write_drop_in_private_format(UNIT(t), + mode, + name, + %s=%s\n, + name, + str); + +v = new0(TimerValue, 1); +if (!v) { +if (c) +calendar_spec_free(c); +return -ENOMEM; +} + +v-base = TIMER_CALENDAR; +v-calendar_spec = c; + +LIST_PREPEND(value, t-values, v); +} + +return 1; + +} else if (streq(name, AccuracySec)) { + +usec_t u = 0; + +r = sd_bus_message_read(message, t, u); +if (r 0) +return r; + +if (mode != UNIT_CHECK) { +t-accuracy_usec = u; +unit_write_drop_in_private_format(UNIT(t), + mode, + name, + %s=%lu\n, + name, + u); +} + +return 1; + +} else if (streq(name, WakeSystem)) { + +int b; + +r = sd_bus_message_read(message, b, b); +if (r 0) +return r; + +if (mode != UNIT_CHECK) { +t-wake_system = b; +unit_write_drop_in_private_format(UNIT(t), + mode, + name, +
[systemd-devel] [PATCH v3 4/4] run: introduce timer support option
Supported timer options --on-active=, --on-boot=, --on-startup=, --on-unit-active=, --on-unit-inactive=, --on-calendar=. Each options corresponding with OnActiveSec=, OnBootSec=, OnStartupSec=, OnUnitActiveSec=, OnUnitInactiveSec= of timer respectively. --- man/systemd-run.xml | 42 +++ src/libsystemd/sd-bus/bus-util.c | 14 +- src/run/run.c| 634 +++ 3 files changed, 571 insertions(+), 119 deletions(-) diff --git a/man/systemd-run.xml b/man/systemd-run.xml index c92c324..c9d5c46 100644 --- a/man/systemd-run.xml +++ b/man/systemd-run.xml @@ -210,6 +210,37 @@ along with systemd; If not, see http://www.gnu.org/licenses/. xi:include href=user-system-options.xml xpointer=host / xi:include href=user-system-options.xml xpointer=machine / + varlistentry +termoption--on-active=/option/term +termoption--on-boot=/option/term +termoption--on-startup=/option/term +termoption--on-unit-active=/option/term +termoption--on-unit-inactive=/option/term + +listitemparaDefines monotonic timers relative to different +starting points. Also see varnameOnActiveSec=/varname, +varnameOnBootSec=/varname, +varnameOnStartupSec=/varname, +varnameOnUnitActiveSec=/varname and +varnameOnUnitInactiveSec=/varname in + citerefentryrefentrytitlesystemd.timer/refentrytitlemanvolnum5/manvolnum/citerefentry. This +option has no effect in conjunction with +option--scope/option./para +/listitem + /varlistentry + + varlistentry +termoption--on-calendar=/option/term + +listitemparaDefines realtime (i.e. wallclock) timers with +calendar event expressions. Also see +varnameOnCalendar=/varname in + citerefentryrefentrytitlesystemd.timer/refentrytitlemanvolnum5/manvolnum/citerefentry. This +option has no effect in conjunction with +option--scope/option./para +/listitem + /varlistentry + xi:include href=standard-options.xml xpointer=help / xi:include href=standard-options.xml xpointer=version / /variablelist @@ -250,6 +281,16 @@ Sep 08 07:37:21 bupkis env[19948]: BOOT_IMAGE=/vmlinuz-3.11.0-0.rc5.git6.2.fc20. property./para programlisting# systemd-run -p BlockIOWeight=10 updatedb/programlisting + +paraThe following command will touch a file after 10 seconds./para + +programlisting# date; systemd-run --on-active=10 touch /tmp/hello +Mon Oct 27 20:02:57 KST 2014 +Running as unit run-66.timer. +# journalctl -u run-115.service +-- Logs begin at Mon 2014-10-27 19:44:57 KST, end at Mon 2014-10-27 20:03:15 KST. -- +Oct 27 20:03:15 container systemd[1]: Starting /bin/touch /tmp/hello... +Oct 27 20:03:15 container systemd[1]: Started /bin/touch /tmp/hello./programlisting /refsect1 refsect1 @@ -263,6 +304,7 @@ Sep 08 07:37:21 bupkis env[19948]: BOOT_IMAGE=/vmlinuz-3.11.0-0.rc5.git6.2.fc20. citerefentryrefentrytitlesystemd.slice/refentrytitlemanvolnum5/manvolnum/citerefentry, citerefentryrefentrytitlesystemd.exec/refentrytitlemanvolnum5/manvolnum/citerefentry, citerefentryrefentrytitlesystemd.resource-control/refentrytitlemanvolnum5/manvolnum/citerefentry, + citerefentryrefentrytitlesystemd.timer/refentrytitlemanvolnum5/manvolnum/citerefentry, citerefentryrefentrytitlemachinectl/refentrytitlemanvolnum1/manvolnum/citerefentry /para /refsect1 diff --git a/src/libsystemd/sd-bus/bus-util.c b/src/libsystemd/sd-bus/bus-util.c index 5345526..f4cef5e 100644 --- a/src/libsystemd/sd-bus/bus-util.c +++ b/src/libsystemd/sd-bus/bus-util.c @@ -1374,7 +1374,8 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen if (STR_IN_SET(field, CPUAccounting, MemoryAccounting, BlockIOAccounting, - SendSIGHUP, SendSIGKILL)) { + SendSIGHUP, SendSIGKILL, + WakeSystem)) { r = parse_boolean(eq); if (r 0) { @@ -1535,6 +1536,17 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen r = sd_bus_message_append(m, v, i, sig); +} else if (streq(field, AccuracySec)) { +usec_t u; + +r = parse_sec(eq, u); +if (r 0) { +log_error(Failed to parse %s value %s, field, eq); +return -EINVAL; +} + +r = sd_bus_message_append(m, v, t, u); + } else { log_error(Unknown assignment %s., assignment); return -EINVAL; diff --git a/src/run/run.c b/src/run/run.c index e3b6293..12b5280 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -30,6 +30,7 @@ #include env-util.h #include path-util.h #include bus-error.h +#include calendarspec.h static
Re: [systemd-devel] [PATCH] smack: introduce new SmackLabelExec option
On 11/10/2014 08:57 PM, Simon McVittie wrote: On 09/11/14 02:08, Casey Schaufler wrote: Thus, dbus is a fine example where SMACK64EXEC is a bad idea. Because you want a system bus and a user bus with different attributes you want it to get the Smack label at launch time, just like you do for UID and capability sets. I think there's a much more fundamental reason why SMACK64EXEC would be a bad idea for dbus[1], which is that dbus-daemon has not been designed to distrust its caller and prevent privilege escalation from its caller's privileges to its own privileges. I think an executable can only safely be setuid, or other frameworks' equivalents of setuid (setcap, SMACK64EXEC, etc.), if the developers of that executable are fully aware that it is a privilege boundary in that way, and are designing it (and choosing its library dependencies!) with that in mind. This is not the case for dbus-daemon. It is entirely possible (although IMO unlikely) that, by coincidence, dbus-daemon does not currently have privilege escalations from its caller's privileges to its own privileges; but if we introduced such a thing (executing a command given by an environment variable, perhaps), I would not consider that to be a regression, because we never claimed it was suitable for that use. This is not unique to dbus; it applies equally to any project that releases executables. Note that dbus-daemon --system is designed to be a different sort of privilege boundary: it enforces differing privilege levels for applications that connect to it via D-Bus, and we do treat holes in that policy as security flaws. That still doesn't mean it is designed to be suitable for setuid. S [1] I assume you mean dbus-daemon, which is an executable; dbus is a package containing dbus-daemon, some other executables, and the libdbus library. There is no such thing as /usr/bin/dbus. Ah..dbus-daemon was just a example as a well known daemon. Actually, this problem was occurred on email-service daemon. Currently, that has system::email SMACK label. Please forgot I'd mentioned about dbus-daemon. Currently, we are using daemon-daemon with _ label like other system daemon. I wonder about other guys also confused about this. Thanks WaLyong ___ 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
Re: [systemd-devel] [PATCH] smack: introduce new SmackLabelExec option
On 11/10/2014 10:26 PM, Lennart Poettering wrote: On Fri, 07.11.14 10:03, Casey Schaufler (ca...@schaufler-ca.com) wrote: Calling it SmackLabel= instead of SmackLabelExec= would be fine as far as I'm concerned. SmackLabel= is more consistent with SELinuxContext= and AppArmorProfile=, as you point out. OK! WaLyong, let's name it SmackLabel= then! I think I had made you to bother. Excuse me, but I'm asking you again. And I think introducing new config should be careful. Hmm, I'm still confusing. We're already using SmackLabel= as socket config item. Yeah, it can possible as both exec/socket config. But each purposes are different. In socket config, this config is used to set SMACK64 of socket file. In exec config, this config is used to set child systemd attribute when User= config is given. And does we have to explain each man page? Or drop from socket package and move that to exec page? I'm not sure it make sense. Thanks WaLyong Lennart ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [PATCH] smack: introduce new SmackLabelExec option
On 11/11/2014 04:10 AM, Lennart Poettering wrote: On Tue, 11.11.14 00:43, WaLyong Cho (walyong@samsung.com) wrote: On 11/10/2014 10:26 PM, Lennart Poettering wrote: On Fri, 07.11.14 10:03, Casey Schaufler (ca...@schaufler-ca.com) wrote: Calling it SmackLabel= instead of SmackLabelExec= would be fine as far as I'm concerned. SmackLabel= is more consistent with SELinuxContext= and AppArmorProfile=, as you point out. OK! WaLyong, let's name it SmackLabel= then! I think I had made you to bother. Excuse me, but I'm asking you again. And I think introducing new config should be careful. Hmm, I'm still confusing. We're already using SmackLabel= as socket config item. Yeah, it can possible as both exec/socket config. But each purposes are different. In socket config, this config is used to set SMACK64 of socket file. In exec config, this config is used to set child systemd attribute when User= config is given. And does we have to explain each man page? Or drop from socket package and move that to exec page? I'm not sure it make sense. Hmm, OK, so you might actually have a point. And this is because .socket units may carry ExecStartPre= command lines which are execute before we start listening to a socket. If we'd just have SmackLabel= then it would not be clear whether it applies as file system label to the socket fds, or if it applies as process label to the ExecStartPre= processes. Hmm, I guess I am fine with SmackLabelExec= then! Hmm, I'd thouth about this again. The name SmackLabelExec= can be shown as the value will be set to the target processes what will be executed by child systemd. But acctually the label only be used to access the executable file. I think just read the SMACK64 of the executable file and set child systemd itself will reduce our naming pain. But Casey said it way is sneaky. How do you think? WaLyong Lennart ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [PATCH] smack: introduce new SmackLabelExec option
On 11/08/2014 01:36 AM, Lennart Poettering wrote: On Fri, 07.11.14 15:43, WaLyong Cho (walyong@samsung.com) wrote: On 11/07/2014 09:35 AM, Lennart Poettering wrote: On Fri, 07.11.14 04:17, WaLyong Cho (walyong@gmail.com) wrote: SMACK64 Used to make access control decisions. In almost all cases the label given to a new filesystem object will be the label of the process that created it. SMACK64EXEC The Smack label of a process that execs a program file with this attribute set will run with this attribute's value. I am sorry, but I cannot parse this. The smack label will run with this attribute's value? smack labels run? That sentence makes no sense to me at all... Again, what kind of objects are SMACK64 and SMACK64EXEC applied to? files? processes? Sorry, I'm also confused. OK, I asked some about this to my security friend. And I add Casey Schaufler who the Author of smack. I hope my below explain it not wrong. But if not, please point out. Quoting the Wikipedia: In practice, a subject is usually a process or thread; objects are constructs such as files, directories, TCP/UDP ports, shared memory segments, IO devices etc. In case of SMACK, subject is SMACK64EXEC and object is SMACK64. Assume like this: /usr/bin/dbus-daemon has both label. SMACK64 is foo and SMACK64EXEC is bar. And current process (what will execute the /usr/bin/dbus-daemon) has foo label. Let's assume the current process So, here you are talking about *files* that have the SMACK64EXEC and SMACK64 type labels, while the *process* only as one generic label type. With your patch you want to introduce SmackLabelExec= now. It's a label applied to a *process* however, not to a *file*, right? This appears incompatible to me: I mean, if a process only has one single generic label, and doesn't distuingish between SMACK64 and SMACK64EXEC type labels, why would you call the option SmackLabelExec= and not the more generic SmackLabel=? Previous mail just a explaination for the difference SMACK64 and SMACK64EXEC. OK, well I think you also understood well about that. Now time to explain my patch. There was execution problems with User= option. Precondition in systemd: 1. systemd is running as root uid. 2. systemd has _ SMACK attribute. Precondition in SMACK side: 1. SMACK access permission checking is by-passed for root uid processes. Problem case: 1. a system session systemd service has User= option. 2. The file on ExecStart= has some special access label and that can NOT be accessed by _ label. The problem occurred procedure: 1. systemd(pid 1) is running as root uid. 2. fork()-ed child systemd still has root uid. (be fork()-ed in exec_spawn()) 3. fork()-ed child systemd process do permission appying. (in the exec_child()) 4. If the target service has User= option the child systemd process will call enforce_user(). 5. After exit of enforce_user() the child systemd no more root uid. 6. Finally, the child systemd process try to execve the given process. 7. (At my case:) the execution was failed because of SMACK access error. Cause: The fork()-ed child systemd process has _ SMACK label what same with parent. And after enforce_user() the child has no more root uid. So that can not be by-passed. (As I wrote as above problem case:) The given process file has some special SMACK label and that can NOT be access-ed by _ attribute. So filnally the child systemd process can NOT access the given ExecStart= file. To resolve this, I tought two method. The first is what I sent patch. Introduce new SMACK option and the given label by new option is applied to child systemd process. Please, do *NOT* confuse. The given label is not applied to will be executed process on ExecStart. Just be applied to child systemd process to successfully access the file on ExecStart=. (The reason why I named the option name as SmackLabelExec, the given label by the option, is applied to child systemd. That is not file. That is currenlty running process. Not other reason.) The second. This method do *NOT* need any new option. Before systemd is calling enforce_user(), systemd still has root uid and can read SMACK64 of the file on ExecStart. So the child systemd process can set /proc/$PID/attr/current of itself to same label what was red. Then alwasy the child systemd process can access the given file on ExecStart=. This really doesn't make sense to me. I have no understanding of SMACK, and I am not sure I want to understand it, and I figure I'd merge the patch regardless which name you pick for the option, but this is a bit too blatantly contradictory for me to completely ignore. Let my simplify my questions: a) Why would you call a setting that controls a label is written into /proc/$PID/attr/current SmackLabelExec= instead of just SmackLabel=? I don't care much this. But I menthioned above. The given label is applied on child systemd. That is not file. That is running
Re: [systemd-devel] [PATCH] smack: introduce new SmackLabelExec option
On 11/06/2014 11:54 PM, Lennart Poettering wrote: On Tue, 04.11.14 17:35, WaLyong Cho (walyong@samsung.com) wrote: In case of systemd has _ label and run as root, if a service file has User= option and the command line file has a special SMACK label then systemd will fail to execute the command. Generally, SMACK label is ignored for the root. But if a service has a User= then systemd will call setresuid() in the child process. After then it no more root. So it should have some of executable label for the command. To set the SMACK64EXEC before the uid is changed introduce new SmackLabelExec option. Hmm, I am not sure I like the abbreviation of this. Can't we just call this SmackLabel=? SmackLabel is already used as socket. Can we use that also here? By the way, I hope to discuss about the naming of the SMACK options. SmackLabel/SmackLabelIPIn/SmackLabelIPOut are. They are used in socket group. According to SMACK description, SMACK64/SMACK64EXEC/SMACK64MMAP/SMACK64TRANSMUTE/SMACK64IPIN/SMACK64IPOUT are the origin attribute name. I think using origin name is most make sense. If you agree, then in this case, SMACK64EXEC will be. +#ifdef HAVE_SMACK +#include smack-util.h +#endif + ifdeffing the include is unnecessary. YOu can just include it without ifdef protectionn, there's nothing in it that we need to avoid pullin in. SELINUX/APPARMOR also use #ifdef. But can SMACK use without that? #define SMACK_FLOOR_LABEL _ @@ -123,6 +124,31 @@ int mac_smack_apply_ip_in_fd(int fd, const char *label) { return r; } +int mac_smack_apply_pid(pid_t pid, const char *label) { +int r = 0; +_cleanup_free_ char *path = NULL; + +assert(label); + +#ifdef HAVE_SMACK +if (!mac_smack_use()) +return 0; + +if (pid) +r = asprintf(path, /proc/%lu/attr/current, (unsigned long) pid); +else +r = asprintf(path, /proc/self/attr/current); +if (r 0) +return -ENOMEM; Please use procfs_file_alloca() for this. It makes this much nicer! Thanks for advising. I will change. WaLyong Lennart ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [PATCH] smack: introduce new SmackLabelExec option
On 11/07/2014 03:30 AM, Lennart Poettering wrote: On Fri, 07.11.14 03:18, WaLyong Cho (walyong@gmail.com) wrote: On 11/06/2014 11:54 PM, Lennart Poettering wrote: On Tue, 04.11.14 17:35, WaLyong Cho (walyong@samsung.com) wrote: In case of systemd has _ label and run as root, if a service file has User= option and the command line file has a special SMACK label then systemd will fail to execute the command. Generally, SMACK label is ignored for the root. But if a service has a User= then systemd will call setresuid() in the child process. After then it no more root. So it should have some of executable label for the command. To set the SMACK64EXEC before the uid is changed introduce new SmackLabelExec option. Hmm, I am not sure I like the abbreviation of this. Can't we just call this SmackLabel=? SmackLabel is already used as socket. Can we use that also here? Well, sure. I mean, SmackLabel= on a socket unit applies to the socket, and SmackLabel= on a service unit applies to the processes forked off, that feels quite natural I think. Overloading the field in this way appears to be quite appropriate to me in this case. By the way, I hope to discuss about the naming of the SMACK options. SmackLabel/SmackLabelIPIn/SmackLabelIPOut are. They are used in socket group. According to SMACK description, SMACK64/SMACK64EXEC/SMACK64MMAP/SMACK64TRANSMUTE/SMACK64IPIN/SMACK64IPOUT are the origin attribute name. I think using origin name is most make sense. If you agree, then in this case, SMACK64EXEC will be. What precisely is the SMACK64 label, and in which way does it differ from SMACK64EXEC? The former is the xattr field on files, the latter the current procfs file on processes? What is SMACK64MMAP for? Does any of the other labels apply to processes? Sorry, I missed attaching URL: http://www.webcitation.org/6AqzohCXq SMACK64 Used to make access control decisions. In almost all cases the label given to a new filesystem object will be the label of the process that created it. SMACK64EXEC The Smack label of a process that execs a program file with this attribute set will run with this attribute's value. SMACK64MMAP Don't allow the file to be mmapped by a process whose Smack label does not allow all of the access permitted to a process with the label contained in this attribute. This is a very specific use case for shared libraries. SMACK64TRANSMUTE Can only have the value TRUE. If this attribute is present on a directory when an object is created in the directory and the Smack rule (more below) that permitted the write access to the directory includes the transmute (t) mode the object gets the label of the directory instead of the label of the creating process. If the object being created is a directory the SMACK64TRANSMUTE attribute is set as well. Maybe SMACK64MMAP/SMACK64TRANSMUTE wasn't used in systemd. So we don't need to discuss about SMACK64MMAP/SMACK64TRANSMUTE on here. I'm not an expert on SMACK, but if I add some explain, we generally assign three kind of label to filesystem object. We usally call them as label, execute label and transmute. transmute has only effect on directory. So we just need to think about label and execute label. Every filesystem objects have to have a label. That can be some string or be _ or *...but the execute label is excuted process's attribute label. That can be none. If a object has none execute label then the object will be run as caller processes label. (I think I'd confused. We should use SMACK64 or SmackLabel instead SMACK64EXEC or SmackLabelExec in here.) Auke, what do you think? Naming things is always one of the most difficult problems in computer science I guesss... In general we try to not do unnecessary abbreviations, especially for more exotic functionality. It's certainly a good idea to stay close to the low-level concepts, but then again dropping components of a low-level name doesn't sound too bad to me. ifdeffing the include is unnecessary. YOu can just include it without ifdef protectionn, there's nothing in it that we need to avoid pullin in. SELINUX/APPARMOR also use #ifdef. But can SMACK use without that? Well, they import system headers, but smack-util.h is not a system header, it's shipped in systemd itself... Lennart ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [PATCH] smack: introduce new SmackLabelExec option
On 11/07/2014 09:35 AM, Lennart Poettering wrote: On Fri, 07.11.14 04:17, WaLyong Cho (walyong@gmail.com) wrote: SMACK64 Used to make access control decisions. In almost all cases the label given to a new filesystem object will be the label of the process that created it. SMACK64EXEC The Smack label of a process that execs a program file with this attribute set will run with this attribute's value. I am sorry, but I cannot parse this. The smack label will run with this attribute's value? smack labels run? That sentence makes no sense to me at all... Again, what kind of objects are SMACK64 and SMACK64EXEC applied to? files? processes? Sorry, I'm also confused. OK, I asked some about this to my security friend. And I add Casey Schaufler who the Author of smack. I hope my below explain it not wrong. But if not, please point out. Quoting the Wikipedia: In practice, a subject is usually a process or thread; objects are constructs such as files, directories, TCP/UDP ports, shared memory segments, IO devices etc. In case of SMACK, subject is SMACK64EXEC and object is SMACK64. Assume like this: /usr/bin/dbus-daemon has both label. SMACK64 is foo and SMACK64EXEC is bar. And current process (what will execute the /usr/bin/dbus-daemon) has foo label. Let's assume the current process is sh. Then /proc/$$/attr/current of sh is foo. There is no problems to sh execute the /usr/bin/dbus-daemon because the sh has same label with /usr/bin/dbus-daemon. Now /usr/bin/dbus-daemon will be executed by sh. But it has SMACK64EXEC label bar. So executed attr/current of /usr/bin/dbus-daemon is bar. If the sh has label waldo, then maybe two case can be existed. If label waldo has executable rule for label foo then the sh can execute the /usr/bin/dbus-daemon. But if label waldo has no rule for that, then sh can not execute the /usr/bin/dbus-daemon. EACCESS will be occurred. If label waldo has executable rule for label foo and /usr/bin/dbus-daemon was executed. Then the executed dbus-daemon process has attribute bar at /proc/{pid of dbus-daemon}/attr/current. # attr -l /bin/sleep Attribute SMACK64 has a 4 byte value for /bin/sleep Attribute SMACK64EXEC has a 3 byte value for /bin/sleep # attr -S -g SMACK64 /bin/sleep Attribute SMACK64 had a 4 byte value for /bin/sleep: foo # attr -S -g SMACK64EXEC /bin/sleep Attribute SMACK64EXEC had a 3 byte value for /bin/sleep: bar # cat /proc/$$/attr/current waldo # /bin/sleep 100 [1] 15263 sh-3.2# cat /proc/15263/attr/current bar Additionally, SMACK64EXEC can be none. Then the executed process inherit attribute from the caller process. So sh has attribute waldo and /bin/sleep has only SMACK64 foo then the executed /bin/sleep process has waldo attribute. # cat /proc/$$/attr/current waldo # attr -l /bin/sleep Attribute SMACK64 has a 4 byte value for /bin/sleep # attr -S -g SMACK64 /bin/sleep Attribute SMACK64 had a 4 byte value for /bin/sleep: foo # /bin/sleep 100 [1] 4509 # cat /proc/4509/attr/current waldo Back to the systemd execute problem with User= option. Exclude Netlabel, the access checking is ignored for all root uid processes. So there is no problems to execute the ExecStart= without User= option. But if a service has User= option and executable binary on ExecStart= has label foo then the fork()-ed systemd child process has no root uid. And the child systemd process has _ label.(see below predefined labels.) If _ has no executable rule for foo then access deny will be occurred. So to successfully execute the ExecStart=, the child systemd process have to has attribute something what can has executable rule for the label of ExecStart= file. Regarding to new option's naming, we will set attribute of process(child systemd). So that is subject. So I think SmackLabelExec= or SMACK64EXEC= are more appropriate. I think we can consider another method. If we don't want to add new SMACK option then we can do like this. Read the access label of executable file of ExecStart=. And just set the label to attribute of fork()-ed child systemd process. Then we don't need to add new SMACK option. I'm not sure this is right way. Regarding to the predefined labels: https://www.kernel.org/doc/Documentation/security/Smack.txt There are some predefined labels: _ Pronounced floor, a single underscore character. ^ Pronounced hat, a single circumflex character. * Pronounced star, a single asterisk character. ? Pronounced huh, a single question mark character. @ Pronounced web, a single at sign character. Every task on a Smack system is assigned a label. System tasks, such as init(8) and systems daemons, are run with the floor (_) label. User tasks are assigned labels according to the specification found in the /etc/smack/user configuration file. Thanks for reading, WaLyong (I think I'd confused. We should use SMACK64 or SmackLabel instead SMACK64EXEC or SmackLabelExec
[systemd-devel] [PATCH] smack: introduce new SmackLabelExec option
In case of systemd has _ label and run as root, if a service file has User= option and the command line file has a special SMACK label then systemd will fail to execute the command. Generally, SMACK label is ignored for the root. But if a service has a User= then systemd will call setresuid() in the child process. After then it no more root. So it should have some of executable label for the command. To set the SMACK64EXEC before the uid is changed introduce new SmackLabelExec option. --- man/systemd.exec.xml | 9 +++ src/core/dbus-execute.c | 19 + src/core/execute.c| 14 ++ src/core/execute.h| 3 +++ src/core/load-fragment-gperf.gperf.m4 | 7 +++-- src/core/load-fragment.c | 50 +++ src/core/load-fragment.h | 1 + src/shared/exit-status.h | 1 + src/shared/smack-util.c | 26 ++ src/shared/smack-util.h | 1 + 10 files changed, 129 insertions(+), 2 deletions(-) diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index e9af4ab..27e6fae 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -1138,6 +1138,15 @@ /varlistentry varlistentry +termvarnameSmackLabelExec=/varname/term + +listitemparaSet the SMACK security +label of the executed process. This directive is ignored if SMACK is +disabled. If prefixed by literal-/literal, all errors will be +ignored./para/listitem +/varlistentry + +varlistentry termvarnameIgnoreSIGPIPE=/varname/term listitemparaTakes a boolean diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index 9276da4..5c56824 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -508,6 +508,24 @@ static int property_get_apparmor_profile( return sd_bus_message_append(reply, (bs), c-apparmor_profile_ignore, c-apparmor_profile); } +static int property_get_smack_exec_label( +sd_bus *bus, +const char *path, +const char *interface, +const char *property, +sd_bus_message *reply, +void *userdata, +sd_bus_error *error) { + +ExecContext *c = userdata; + +assert(bus); +assert(reply); +assert(c); + +return sd_bus_message_append(reply, (bs), c-smack_exec_label_ignore, c-smack_exec_label); +} + static int property_get_personality( sd_bus *bus, const char *path, @@ -636,6 +654,7 @@ const sd_bus_vtable bus_exec_vtable[] = { SD_BUS_PROPERTY(UtmpIdentifier, s, NULL, offsetof(ExecContext, utmp_id), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY(SELinuxContext, (bs), property_get_selinux_context, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY(AppArmorProfile, (bs), property_get_apparmor_profile, 0, SD_BUS_VTABLE_PROPERTY_CONST), +SD_BUS_PROPERTY(SmackLabelExec, (bs), property_get_smack_exec_label, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY(IgnoreSIGPIPE, b, bus_property_get_bool, offsetof(ExecContext, ignore_sigpipe), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY(NoNewPrivileges, b, bus_property_get_bool, offsetof(ExecContext, no_new_privileges), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY(SystemCallFilter, (bas), property_get_syscall_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST), diff --git a/src/core/execute.c b/src/core/execute.c index c41aec2..5222aee 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -90,6 +90,10 @@ #include seccomp-util.h #endif +#ifdef HAVE_SMACK +#include smack-util.h +#endif + #define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC) #define IDLE_TIMEOUT2_USEC (1*USEC_PER_SEC) @@ -1617,6 +1621,16 @@ static int exec_child(ExecCommand *command, } } +#ifdef HAVE_SMACK +if (context-smack_exec_label) { +err = mac_smack_apply_pid(0, context-smack_exec_label); +if (err 0) { +*error = EXIT_SMACK_LABEL; +return err; +} +} +#endif + if (context-user) { err = enforce_user(context, uid); if (err 0) { diff --git a/src/core/execute.h b/src/core/execute.h index c45dde5..e6b9122 100644 --- a/src/core/execute.h +++ b/src/core/execute.h @@ -142,6 +142,9 @@ struct ExecContext { bool apparmor_profile_ignore; char *apparmor_profile; +bool
[systemd-devel] [PATCH v2 1/2] utf8: intruduce utf8_escape_non_printable
--- src/shared/utf8.c| 87 src/shared/utf8.h| 1 + src/test/test-utf8.c | 30 ++ 3 files changed, 118 insertions(+) diff --git a/src/shared/utf8.c b/src/shared/utf8.c index 9353559..5245604 100644 --- a/src/shared/utf8.c +++ b/src/shared/utf8.c @@ -210,6 +210,93 @@ char *utf8_escape_invalid(const char *str) { return p; } +char *utf8_escape_non_printable(const char *str) { +char *p, *s; + +assert(str); + +p = s = malloc(strlen(str) * 4 + 1); +if (!p) +return NULL; + +while (*str) { +int len; + +len = utf8_encoded_valid_unichar(str); +if (len 0) { +if (utf8_is_printable(str, len)) { +s = mempcpy(s, str, len); +str += len; +} else { +switch (*str) { + +case '\a': +*(s++) = '\\'; +*(s++) = 'a'; +break; +case '\b': +*(s++) = '\\'; +*(s++) = 'b'; +break; +case '\f': +*(s++) = '\\'; +*(s++) = 'f'; +break; +case '\n': +*(s++) = '\\'; +*(s++) = 'n'; +break; +case '\r': +*(s++) = '\\'; +*(s++) = 'r'; +break; +case '\t': +*(s++) = '\\'; +*(s++) = 't'; +break; +case '\v': +*(s++) = '\\'; +*(s++) = 'v'; +break; +case '\\': +*(s++) = '\\'; +*(s++) = '\\'; +break; +case '': +*(s++) = '\\'; +*(s++) = ''; +break; +case '\'': +*(s++) = '\\'; +*(s++) = '\''; +break; + +default: +/* For special chars we prefer octal over + * hexadecimal encoding, simply because glib's + * g_strescape() does the same */ +if ((*str ' ') || (*str = 127)) { +*(s++) = '\\'; +*(s++) = octchar((unsigned char) *str 6); +*(s++) = octchar((unsigned char) *str 3); +*(s++) = octchar((unsigned char) *str); +} else +*(s++) = *str; +break; +} +str += 1; +} +} else { +s = mempcpy(s, UTF8_REPLACEMENT_CHARACTER, strlen(UTF8_REPLACEMENT_CHARACTER)); +str += 1; +} +} + +*s = '\0'; + +return p; +} + char *ascii_is_valid(const char *str) { const char *p; diff --git a/src/shared/utf8.h b/src/shared/utf8.h index c087995..1fe1a35 100644 --- a/src/shared/utf8.h +++ b/src/shared/utf8.h @@ -30,6 +30,7 @@ const char *utf8_is_valid(const char *s) _pure_; char *ascii_is_valid(const char *s) _pure_; char *utf8_escape_invalid(const char *s); +char *utf8_escape_non_printable(const char *str); bool utf8_is_printable_newline(const char* str, size_t length, bool newline) _pure_; _pure_ static inline bool utf8_is_printable(const char* str, size_t length) { diff --git a/src/test/test-utf8.c b/src/test/test-utf8.c index b7d988f..fb27fe5 100644 --- a/src/test/test-utf8.c +++ b/src/test/test-utf8.c @@ -66,12 +66,42 @@ static void
[systemd-devel] [PATCH v2 2/2] bootchart: escape non printable process name
--- src/bootchart/svg.c | 10 +++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/bootchart/svg.c b/src/bootchart/svg.c index faf377e..e5569e1 100644 --- a/src/bootchart/svg.c +++ b/src/bootchart/svg.c @@ -39,6 +39,7 @@ #include svg.h #include bootchart.h #include list.h +#include utf8.h #define time_to_graph(t) ((t) * arg_scale_x) #define ps_to_graph(n) ((n) * arg_scale_y) @@ -1006,12 +1007,15 @@ static void svg_ps_bars(void) { /* pass 2 - ps boxes */ ps = ps_first; while ((ps = get_next_ps(ps))) { -_cleanup_free_ char *enc_name = NULL; +_cleanup_free_ char *enc_name = NULL, *escaped = NULL; double endtime; double starttime; int t; -enc_name = xml_comment_encode(ps-name); +if (!utf8_is_printable(ps-name, strlen(ps-name))) +escaped = utf8_escape_non_printable(ps-name); + +enc_name = xml_comment_encode(escaped ? escaped : ps-name); if (!enc_name) continue; @@ -1100,7 +1104,7 @@ static void svg_ps_bars(void) { svg( text x=\%.03f\ y=\%.03f\![CDATA[%s]] [%i]tspan class=\run\%.03fs/tspan %s/text\n, time_to_graph(w - graph_start) + 5.0, ps_to_graph(j) + 14.0, -ps-name, +escaped ? escaped : ps-name, ps-pid, (ps-last-runtime - ps-first-runtime) / 10.0, arg_show_cgroup ? ps-cgroup : ); -- 1.9.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH v2 4/4] run: introduce timer support option
Supported timer options --on-active=, --on-boot=, --on-startup=, --on-unit-active=, --on-unit-inactive=, --on-calendar=. Each options corresponding with OnActiveSec=, OnBootSec=, OnStartupSec=, OnUnitActiveSec=, OnUnitInactiveSec= of timer respectively. --- man/systemd-run.xml | 42 +++ src/libsystemd/sd-bus/bus-util.c | 14 +- src/run/run.c| 634 +++ 3 files changed, 571 insertions(+), 119 deletions(-) diff --git a/man/systemd-run.xml b/man/systemd-run.xml index 0c9d13d..d359941 100644 --- a/man/systemd-run.xml +++ b/man/systemd-run.xml @@ -210,6 +210,37 @@ along with systemd; If not, see http://www.gnu.org/licenses/. xi:include href=user-system-options.xml xpointer=host / xi:include href=user-system-options.xml xpointer=machine / + varlistentry +termoption--on-active=/option/term +termoption--on-boot=/option/term +termoption--on-startup=/option/term +termoption--on-unit-active=/option/term +termoption--on-unit-inactive=/option/term + +listitemparaDefines monotonic timers relative to different +starting points. Also see varnameOnActiveSec=/varname, +varnameOnBootSec=/varname, +varnameOnStartupSec=/varname, +varnameOnUnitActiveSec=/varname and +varnameOnUnitInactiveSec=/varname in + citerefentryrefentrytitlesystemd.timer/refentrytitlemanvolnum5/manvolnum/citerefentry. This +option has no effect in conjunction with +option--scope/option./para +/listitem + /varlistentry + + varlistentry +termoption--on-calendar=/option/term + +listitemparaDefines realtime (i.e. wallclock) timers with +calendar event expressions. Also see +varnameOnCalendar=/varname in + citerefentryrefentrytitlesystemd.timer/refentrytitlemanvolnum5/manvolnum/citerefentry. This +option has no effect in conjunction with +option--scope/option./para +/listitem + /varlistentry + xi:include href=standard-options.xml xpointer=help / xi:include href=standard-options.xml xpointer=version / /variablelist @@ -250,6 +281,16 @@ Sep 08 07:37:21 bupkis env[19948]: BOOT_IMAGE=/vmlinuz-3.11.0-0.rc5.git6.2.fc20. property./para programlisting# systemd-run -p BlockIOWeight=10 updatedb/programlisting + +paraThe following command will touch a file after 10 seconds./para + +programlisting# date; systemd-run --on-active=10 touch /tmp/hello +Mon Oct 27 20:02:57 KST 2014 +Running as unit run-66.timer. +# journalctl -u run-115.service +-- Logs begin at Mon 2014-10-27 19:44:57 KST, end at Mon 2014-10-27 20:03:15 KST. -- +Oct 27 20:03:15 container systemd[1]: Starting /bin/touch /tmp/hello... +Oct 27 20:03:15 container systemd[1]: Started /bin/touch /tmp/hello./programlisting /refsect1 refsect1 @@ -263,6 +304,7 @@ Sep 08 07:37:21 bupkis env[19948]: BOOT_IMAGE=/vmlinuz-3.11.0-0.rc5.git6.2.fc20. citerefentryrefentrytitlesystemd.slice/refentrytitlemanvolnum5/manvolnum/citerefentry, citerefentryrefentrytitlesystemd.exec/refentrytitlemanvolnum5/manvolnum/citerefentry, citerefentryrefentrytitlesystemd.resource-control/refentrytitlemanvolnum5/manvolnum/citerefentry, + citerefentryrefentrytitlesystemd.timer/refentrytitlemanvolnum5/manvolnum/citerefentry, citerefentryrefentrytitlemachinectl/refentrytitlemanvolnum1/manvolnum/citerefentry /para /refsect1 diff --git a/src/libsystemd/sd-bus/bus-util.c b/src/libsystemd/sd-bus/bus-util.c index 43acf5b..13fb9e6 100644 --- a/src/libsystemd/sd-bus/bus-util.c +++ b/src/libsystemd/sd-bus/bus-util.c @@ -1361,7 +1361,8 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen if (STR_IN_SET(field, CPUAccounting, MemoryAccounting, BlockIOAccounting, - SendSIGHUP, SendSIGKILL)) { + SendSIGHUP, SendSIGKILL, + WakeSystem)) { r = parse_boolean(eq); if (r 0) { @@ -1522,6 +1523,17 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen r = sd_bus_message_append(m, v, i, sig); +} else if (streq(field, AccuracySec)) { +usec_t u; + +r = parse_sec(eq, u); +if (r 0) { +log_error(Failed to parse %s value %s, field, eq); +return -EINVAL; +} + +r = sd_bus_message_append(m, v, t, u); + } else { log_error(Unknown assignment %s., assignment); return -EINVAL; diff --git a/src/run/run.c b/src/run/run.c index e3b6293..0c92a1c 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -30,6 +30,7 @@ #include env-util.h #include path-util.h #include bus-error.h +#include calendarspec.h static
[systemd-devel] [PATCH v2 3/4] unit: add UnitMask enum and get unit scope(mask) api from property
--- Makefile.am | 7 ++ src/shared/.gitignore| 1 + src/shared/unit-name.c | 22 src/shared/unit-name.h | 26 + src/shared/unit-property-scope.gperf | 202 +++ 5 files changed, 258 insertions(+) create mode 100644 src/shared/unit-property-scope.gperf diff --git a/Makefile.am b/Makefile.am index c80d25d..737d6d7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -816,6 +816,7 @@ libsystemd_shared_la_SOURCES = \ src/shared/cgroup-show.h \ src/shared/unit-name.c \ src/shared/unit-name.h \ + src/shared/unit-property-scope.c \ src/shared/utmp-wtmp.h \ src/shared/watchdog.c \ src/shared/watchdog.h \ @@ -905,6 +906,12 @@ libsystemd_shared_la_CFLAGS = \ $(SECCOMP_CFLAGS) \ -pthread +EXTRA_DIST += \ + src/shared/unit-property-scope.gperf + +CLEANFILES += \ + src/shared/unit-property-scope.c + # -- noinst_LTLIBRARIES += \ libsystemd-units.la diff --git a/src/shared/.gitignore b/src/shared/.gitignore index 61709e8..e7faa23 100644 --- a/src/shared/.gitignore +++ b/src/shared/.gitignore @@ -10,3 +10,4 @@ /arphrd-from-name.h /arphrd-list.txt /arphrd-to-name.h +/unit-property-scope.c diff --git a/src/shared/unit-name.c b/src/shared/unit-name.c index 2ef8545..e4669dd 100644 --- a/src/shared/unit-name.c +++ b/src/shared/unit-name.c @@ -621,3 +621,25 @@ static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = { }; DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency); + +static UnitMask unit_get_mask_from_property(const char *property) { +const unit_property_scope_mapping *m; + +assert(property); + +m = unit_property_scope_mapping_lookup(property, strlen(property)); +if (m) +return m-scope; + +return _UNIT_MASK_MAX; + +} + +bool unit_can_have_property(UnitType t, const char *property) { +UnitMask m; + +assert(property); + +m = unit_get_mask_from_property(property); +return !!((1ULL t) m); +} diff --git a/src/shared/unit-name.h b/src/shared/unit-name.h index daeb56a..e1d4e27 100644 --- a/src/shared/unit-name.h +++ b/src/shared/unit-name.h @@ -28,6 +28,7 @@ #define UNIT_NAME_MAX 256 typedef enum UnitType UnitType; +typedef enum UnitMask UnitMask; typedef enum UnitLoadState UnitLoadState; typedef enum UnitDependency UnitDependency; @@ -49,6 +50,23 @@ enum UnitType { _UNIT_TYPE_INVALID = -1 }; +enum UnitMask { +UNIT_MASK_SERVICE = 1ULL UNIT_SERVICE, +UNIT_MASK_SOCKET= 1ULL UNIT_SOCKET, +UNIT_MASK_BUSNAME = 1ULL UNIT_BUSNAME, +UNIT_MASK_TARGET= 1ULL UNIT_TARGET, +UNIT_MASK_SNAPSHOT = 1ULL UNIT_SNAPSHOT, +UNIT_MASK_DEVICE= 1ULL UNIT_DEVICE, +UNIT_MASK_MOUNT = 1ULL UNIT_MOUNT, +UNIT_MASK_AUTOMOUNT = 1ULL UNIT_AUTOMOUNT, +UNIT_MASK_SWAP = 1ULL UNIT_SWAP, +UNIT_MASK_TIMER = 1ULL UNIT_TIMER, +UNIT_MASK_PATH = 1ULL UNIT_PATH, +UNIT_MASK_SLICE = 1ULL UNIT_SLICE, +UNIT_MASK_SCOPE = 1ULL UNIT_SCOPE, +_UNIT_MASK_MAX = 1ULL _UNIT_TYPE_MAX, +}; + enum UnitLoadState { UNIT_STUB = 0, UNIT_LOADED, @@ -163,3 +181,11 @@ int build_subslice(const char *slice, const char*name, char **subslice); const char *unit_dependency_to_string(UnitDependency i) _const_; UnitDependency unit_dependency_from_string(const char *s) _pure_; + +struct unit_property_scope_mapping { +const char* property; +UnitMask scope; +}; +typedef struct unit_property_scope_mapping unit_property_scope_mapping; +const unit_property_scope_mapping* unit_property_scope_mapping_lookup (register const char *str, register unsigned int len); +bool unit_can_have_property(UnitType t, const char *property); diff --git a/src/shared/unit-property-scope.gperf b/src/shared/unit-property-scope.gperf new file mode 100644 index 000..bbcfcba --- /dev/null +++ b/src/shared/unit-property-scope.gperf @@ -0,0 +1,202 @@ +%{ +#include unit-name.h +#include bus-util.h +%} +unit_property_scope_mapping; +%null_strings +%language=ANSI-C +%define slot-name property +%define hash-function-name bus_property_scope_mapping_hash +%define lookup-function-name unit_property_scope_mapping_lookup +%readonly-tables +%omit-struct-type +%struct-type +%includes +%% +Description, UNIT_MASK_SERVICE|UNIT_MASK_SOCKET|UNIT_MASK_DEVICE|UNIT_MASK_MOUNT|UNIT_MASK_AUTOMOUNT|UNIT_MASK_SWAP|UNIT_MASK_TARGET|UNIT_MASK_PATH|UNIT_MASK_TIMER|UNIT_MASK_SNAPSHOT|UNIT_MASK_SLICE|UNIT_MASK_SCOPE +Documentation,
[systemd-devel] [PATCH v2 2/4] timer: timer can be a transient unit
--- src/core/dbus-timer.c | 159 ++ src/core/dbus-timer.h | 3 + src/core/timer.c | 4 ++ 3 files changed, 166 insertions(+) diff --git a/src/core/dbus-timer.c b/src/core/dbus-timer.c index f1f8c54..e916f5a 100644 --- a/src/core/dbus-timer.c +++ b/src/core/dbus-timer.c @@ -24,6 +24,8 @@ #include dbus-unit.h #include dbus-timer.h #include bus-util.h +#include errno-list.h +#include strv.h static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, timer_result, TimerResult); @@ -183,3 +185,160 @@ const sd_bus_vtable bus_timer_vtable[] = { SD_BUS_PROPERTY(WakeSystem, b, bus_property_get_bool, offsetof(Timer, wake_system), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_VTABLE_END }; + +static int bus_timer_set_transient_property( +Timer *t, +const char *name, +sd_bus_message *message, +UnitSetPropertiesMode mode, +sd_bus_error *error) { + +const char *str; +int r; + +assert(t); +assert(name); +assert(message); + +if (STR_IN_SET(name, + OnActiveSec, + OnBootSec, + OnStartupSec, + OnUnitActiveSec, + OnUnitInactiveSec)) { + +TimerValue *v; +TimerBase b = _TIMER_BASE_INVALID; +usec_t u = 0; + +b = timer_base_from_string(name); +if (b 0) +return 0; + +r = sd_bus_message_read(message, t, u); +if (r 0) +return r; + +if (mode != UNIT_CHECK) { +unit_write_drop_in_private_format(UNIT(t), + mode, + name, + %s=%lu\n, + name, + u); + +v = new0(TimerValue, 1); +if (!v) +return -ENOMEM; + +v-base = b; +v-value = u; + +LIST_PREPEND(value, t-values, v); +} + +return 1; + +} else if (streq(name, OnCalendar)) { + +TimerValue *v; +CalendarSpec *c = NULL; + +r = sd_bus_message_read(message, s, str); +if (r 0) +return r; + +if (mode != UNIT_CHECK) { +r = calendar_spec_from_string(str, c); +if (r 0) +return r; + +unit_write_drop_in_private_format(UNIT(t), + mode, + name, + %s=%s\n, + name, + str); + +v = new0(TimerValue, 1); +if (!v) { +if (c) +calendar_spec_free(c); +return -ENOMEM; +} + +v-base = TIMER_CALENDAR; +v-calendar_spec = c; + +LIST_PREPEND(value, t-values, v); +} + +return 1; + +} else if (streq(name, AccuracySec)) { + +usec_t u = 0; + +r = sd_bus_message_read(message, t, u); +if (r 0) +return r; + +if (mode != UNIT_CHECK) { +t-accuracy_usec = u; +unit_write_drop_in_private_format(UNIT(t), + mode, + name, + %s=%lu\n, + name, + u); +} + +return 1; + +} else if (streq(name, WakeSystem)) { + +int b; + +r = sd_bus_message_read(message, b, b); +if (r 0) +return r; + +if (mode != UNIT_CHECK) { +t-wake_system = b; +unit_write_drop_in_private_format(UNIT(t), + mode, + name, +
[systemd-devel] [PATCH v2 1/4] bus: StartTransientUnit can have aux unit
--- src/core/dbus-manager.c | 123 +--- 1 file changed, 105 insertions(+), 18 deletions(-) diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index c54abd3..bba4b27 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -615,6 +615,93 @@ static int method_set_unit_properties(sd_bus *bus, sd_bus_message *message, void return bus_unit_method_set_properties(bus, message, u, error); } +static int transient_unit_from_message( +Manager *m, +sd_bus_message *message, +const char *name, +Unit **unit, +sd_bus_error *error) { + +Unit *u; +int r; + +assert(m); +assert(message); +assert(name); + +r = manager_load_unit(m, name, NULL, error, u); +if (r 0) +return r; + +if (u-load_state != UNIT_NOT_FOUND || +set_size(u-dependencies[UNIT_REFERENCED_BY]) 0) +return sd_bus_error_setf(error, + BUS_ERROR_UNIT_EXISTS, + Unit %s already exists., + name); + +/* OK, the unit failed to load and is unreferenced, now let's + * fill in the transient data instead */ +r = unit_make_transient(u); +if (r 0) +return r; + +/* Set our properties */ +r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error); +if (r 0) +return r; + +*unit = u; + +return 0; +} + +static int try_aux_units_in_message( +Manager *m, +sd_bus_message *message, +sd_bus_error *error) { + +Unit *u; +char *name = NULL; +int r; + +assert(m); +assert(message); + +r = sd_bus_message_enter_container(message, 'a', (sa(sv))); +if (r 0) +return r; + +while ((r = sd_bus_message_enter_container(message, 'r', sa(sv))) 0) { +if (r = 0) +return r; + +r = sd_bus_message_read(message, s, name); +if (r 0) +return r; + +r = transient_unit_from_message(m, message, name, u, error); +if (r 0 r != -EEXIST) +return r; + +r = sd_bus_message_exit_container(message); +if (r 0) +return r; + +r = unit_load(u); +if (r 0) +return r; +} +if (r 0) +return r; + +r = sd_bus_message_exit_container(message); +if (r 0) +return r; + +return 0; +} + static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { const char *name, *smode; Manager *m = userdata; @@ -631,7 +718,9 @@ static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, voi if (r 0) return r; if (r == 0) -return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ +/* No authorization for now, but the async polkit + * stuff will call us again when it has it */ +return 1; r = sd_bus_message_read(message, ss, name, smode); if (r 0) @@ -639,34 +728,32 @@ static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, voi t = unit_name_to_type(name); if (t 0) -return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, Invalid unit type.); +return sd_bus_error_setf(error, + SD_BUS_ERROR_INVALID_ARGS, + Invalid unit type.); if (!unit_vtable[t]-can_transient) -return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, Unit type %s does not support transient units., unit_type_to_string(t)); - -mode = job_mode_from_string(smode); -if (mode 0) -return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, Job mode %s is invalid., smode); +return sd_bus_error_setf(error, + SD_BUS_ERROR_INVALID_ARGS, + Unit type %s does not support transient units., + unit_type_to_string(t)); r = mac_selinux_access_check(message, start, error); if (r 0) return r; -r = manager_load_unit(m, name, NULL, error, u); -if (r 0) -return r; - -if (u-load_state != UNIT_NOT_FOUND || set_size(u-dependencies[UNIT_REFERENCED_BY]) 0) -
[systemd-devel] [PATCH] bus: use STR_IN_SET
--- src/core/dbus-unit.c | 24 ++-- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index 9b13c6e..2d1862c 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -859,20 +859,16 @@ static int bus_unit_set_transient_property( } return 1; - -} else if (streq(name, Requires) || - streq(name, RequiresOverridable) || - streq(name, Requisite) || - streq(name, RequisiteOverridable) || - streq(name, Wants) || - streq(name, BindsTo) || - streq(name, Conflicts) || - streq(name, Before) || - streq(name, After) || - streq(name, OnFailure) || - streq(name, PropagatesReloadTo) || - streq(name, ReloadPropagatedFrom) || - streq(name, PartOf)) { +} else if (STR_IN_SET(name, + Requires, RequiresOverridable, + Requisite, RequisiteOverridable, + Wants, + BindsTo, + Conflicts, + Before, After, + OnFailure, + PropagatesReloadTo, ReloadPropagatedFrom, + PartOf)) { UnitDependency d; const char *other; -- 1.9.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [PATCH 3/3] run: introduce timer support option
On 10/28/2014 07:22 PM, Lennart Poettering wrote: On Tue, 28.10.14 12:09, WaLyong Cho (walyong@samsung.com) wrote: The AccuracySec= and WakeSystem= stuff I think we don't need to cover with a command line argument of its own, we can cover that with --property=. Rework is almost done. Now I'm testing. But the AccuracySec= and WakeSystem= options are hard to deal with --property= option. Currently the --property= option of systemd-run is designed for service or scope unit. If that option is specified then given string is parsed again by bus_append_unit_property_assignment(). We can AccuracySec=/WakeSystem= option to there. But we have to split given properties(by --property option) according to which unit can have that properties. Hmm, the implied rule here is that we do not intrdouce properties with the same name on different unit types that do not shrae the same signature. That way it really doesn't matter to specify which properties can be parsed for a specific unit type on the client side, since the server side will already know. Or in other words: go ahead, add this to bus_append_unit_property_assignment(), and the server side will deny what it doesn't like. Honestly, I'd tried. But that was denied by server side. The properties of received transient unit are set by bus_unit_set_properties. Currently, bus_unit_set_properties return fail for unknown property. See this example, systemd-run --on-unit-active=30 --property=AccuracySec=100ms touch /tmp/hello On the client side, systemd-run ship the AccuracySec=100ms option to both timer and service(aux unit) property. Because bus_append_unit_property_assignment don't know that is working on which kind of unit. Anyway the message is successfully made and sent to systemd(server side). There is no problem on parse timer unit properties. But when parse aux unit(maybe run-xxx.service), bus_unit_set_properties try to parse AccuracySec= but it can not. And return fail with Cannot set property AccuracySec, or unknown property. I think we have to pass unit type to bus_append_unit_property_assignment and only be assigned what be supported by its unit type. Hope that makes sense, Lennart ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [PATCH 3/3] run: introduce timer support option
On 10/23/2014 12:56 AM, Lennart Poettering wrote: On Tue, 07.10.14 14:20, WaLyong Cho (walyong@samsung.com) wrote: If systemd-run is called with timer option, then systemd-run call NewTransientUnit with service unit. And also call StartTransientUnit with timer unit which has same name with the service. So actually, two method call is coming and two transient unit is generated. One is service and the other is timer. Supported timer options are --after=, --after-boot=, --after-startup=, --after-active=, --after-inactive=, --calendar=, --accuracy= and --wake-system. Each option corresponding with OnActiveSec=, OnBootSec=, OnStartupSec=, OnUnitActiveSec=, OnUnitInactiveSec=, AccuracySec= and AccuracySec= of timer respectively. Hmm, I'd really like to stay close to the underlying props here in naming, and call the options --on-boot=, --on-inactive= and so on (the -sec suffix we can probably drop). The AccuracySec= and WakeSystem= stuff I think we don't need to cover with a command line argument of its own, we can cover that with --property=. Rework is almost done. Now I'm testing. But the AccuracySec= and WakeSystem= options are hard to deal with --property= option. Currently the --property= option of systemd-run is designed for service or scope unit. If that option is specified then given string is parsed again by bus_append_unit_property_assignment(). We can AccuracySec=/WakeSystem= option to there. But we have to split given properties(by --property option) according to which unit can have that properties. So I'd like to keep those two option as separated systemd-run options. If you agree, I will send a patch soon. WaLyong +static bool with_timer = false; +static char *arg_after = NULL; +static char *arg_after_boot = NULL; +static char *arg_after_startup = NULL; +static char *arg_after_active = NULL; +static char *arg_after_inactive = NULL; +static char *arg_calendar = NULL; +static char *arg_accuracy = NULL; +static bool arg_wake_system = false; I'd just do one arg_on_timer usec_t variable to store most of the --on-xyz= values in. Plus one arg_on_calendar to hold the calendar expression. This should be much simpler than keeping one variable around for each. +case ARG_AFTER: +r = parse_sec(optarg, u); +if (r 0) { +log_error(Failed to parse timer value: %s, optarg); +return r; +} +arg_after = optarg; +with_timer = true; +break; This stuff really should not store the string, but the parsed value. (I'll leave the rest unreviewed for now, please rework this first to make use of the fourth StartTransientUnit() bus call argument!) Thanks, Lennart ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [RFC] runtime configurable timer
On 10/23/2014 12:28 AM, Lennart Poettering wrote: On Thu, 11.09.14 17:45, WaLyong Cho (walyong@samsung.com) wrote: (I will happy there is already similar method already exist.) systemd already has similar functionality systemd-run but that is only for scope or service unit. I think that is useful run a service without unit file on permanent storage. As a similar method, is it possible to generate or configure timer unit on runtime? Currently not, but this would be certainly useful. Honestly, now, I need a runtime configurable timer interface. If systemd has this then I can reduce one of daemon. Currently pid1's StartTransientUnit() bus call already takes four arguments arguments: 1. a name for the unit to create and start 2. a mode how to start it 3. an array with properties for the unit 4. an array conisting of unit names plus a property array each, which is supposed to contain additional unit definitions which can be referenced by the main unit you are creating. Ok, one more question. In this case, if the timer unit is not loaded and service unit is already loaded then I hope to use that already loaded instead of new transient service unit. Then the COMMAND argument of systemd-run will be optional. Does it make sense? WaLyong Now, while the method takes that fourth argument it is actually just ignored. The plan was (and still is) to beef this up and make it useful for installing both a transient service and a timer unit at once. More specifically: to implement something that would work like at a client would invoke StartTransientUnit(), create the timer unit as primary unit, and then include the service definition for the service to eventually start in the second array. I would love to see this getting fully implemented now, it would be great if systemd-run would get an --on-calendar= switch or so, which makes use of this behaviour. Lennart ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [PATCH 1/2] selinux: make sure selinux is using on mac_selinux_fix()
On 10/24/2014 07:16 PM, Lennart Poettering wrote: On Fri, 24.10.14 13:51, WaLyong Cho (walyong@gmail.com) wrote: --- src/shared/selinux-util.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/shared/selinux-util.c b/src/shared/selinux-util.c index 1eddd17..bb27328 100644 --- a/src/shared/selinux-util.c +++ b/src/shared/selinux-util.c @@ -128,6 +128,9 @@ int mac_selinux_fix(const char *path, bool ignore_enoent, bool ignore_erofs) { assert(path); +if (!mac_selinux_use()) +return 0; + /* if mac_selinux_init() wasn't called before we are a NOOP */ if (!label_hnd) return 0; label_hnd is initialized by mac_selinux_init(), which in turn checks for mac_selinux_use(), hence checking it here againis unnecessary. Ah, sorry, you're right. The second patch just enough. Thanks, WaLyong Lennart ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH] mac: add mac_ prefix to distinguish origin security apis
--- src/core/dbus-job.c | 2 +- src/core/dbus-manager.c | 68 +++ src/core/dbus-snapshot.c | 2 +- src/core/dbus-unit.c | 8 +++--- src/core/dbus.c | 8 +++--- src/core/main.c | 4 +-- src/core/selinux-access.c | 46 +++- src/core/selinux-access.h | 18 ++--- src/core/selinux-setup.c | 2 +- src/core/selinux-setup.h | 2 +- src/core/smack-setup.c| 2 +- src/core/smack-setup.h| 2 +- 12 files changed, 74 insertions(+), 90 deletions(-) diff --git a/src/core/dbus-job.c b/src/core/dbus-job.c index 3f7a28a..09f5739 100644 --- a/src/core/dbus-job.c +++ b/src/core/dbus-job.c @@ -80,7 +80,7 @@ int bus_job_method_cancel(sd_bus *bus, sd_bus_message *message, void *userdata, if (r 0) return r; -r = selinux_unit_access_check(j-unit, message, stop, error); +r = mac_selinux_unit_access_check(j-unit, message, stop, error); if (r 0) return r; diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 57db1c9..c54abd3 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -363,7 +363,7 @@ static int method_get_unit(sd_bus *bus, sd_bus_message *message, void *userdata, if (!u) return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, Unit %s not loaded., name); -r = selinux_unit_access_check(u, message, status, error); +r = mac_selinux_unit_access_check(u, message, status, error); if (r 0) return r; @@ -409,7 +409,7 @@ static int method_get_unit_by_pid(sd_bus *bus, sd_bus_message *message, void *us if (!u) return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, PID %u does not belong to any loaded unit., pid); -r = selinux_unit_access_check(u, message, status, error); +r = mac_selinux_unit_access_check(u, message, status, error); if (r 0) return r; @@ -441,7 +441,7 @@ static int method_load_unit(sd_bus *bus, sd_bus_message *message, void *userdata if (r 0) return r; -r = selinux_unit_access_check(u, message, status, error); +r = mac_selinux_unit_access_check(u, message, status, error); if (r 0) return r; @@ -648,7 +648,7 @@ static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, voi if (mode 0) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, Job mode %s is invalid., smode); -r = selinux_access_check(message, start, error); +r = mac_selinux_access_check(message, start, error); if (r 0) return r; @@ -702,7 +702,7 @@ static int method_get_job(sd_bus *bus, sd_bus_message *message, void *userdata, if (!j) return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, Job %u does not exist., (unsigned) id); -r = selinux_unit_access_check(j-unit, message, status, error); +r = mac_selinux_unit_access_check(j-unit, message, status, error); if (r 0) return r; @@ -742,7 +742,7 @@ static int method_clear_jobs(sd_bus *bus, sd_bus_message *message, void *userdat assert(message); assert(m); -r = selinux_access_check(message, reboot, error); +r = mac_selinux_access_check(message, reboot, error); if (r 0) return r; @@ -759,7 +759,7 @@ static int method_reset_failed(sd_bus *bus, sd_bus_message *message, void *userd assert(message); assert(m); -r = selinux_access_check(message, reload, error); +r = mac_selinux_access_check(message, reload, error); if (r 0) return r; @@ -782,7 +782,7 @@ static int list_units_filtered(sd_bus *bus, sd_bus_message *message, void *userd /* Anyone can call this method */ -r = selinux_access_check(message, status, error); +r = mac_selinux_access_check(message, status, error); if (r 0) return r; @@ -870,7 +870,7 @@ static int method_list_jobs(sd_bus *bus, sd_bus_message *message, void *userdata /* Anyone can call this method */ -r = selinux_access_check(message, status, error); +r = mac_selinux_access_check(message, status, error); if (r 0) return r; @@ -922,7 +922,7 @@ static int method_subscribe(sd_bus *bus, sd_bus_message *message, void *userdata /* Anyone can call this method */ -r = selinux_access_check(message, status, error); +r = mac_selinux_access_check(message, status, error); if (r 0) return r; @@ -957,7 +957,7 @@ static int method_unsubscribe(sd_bus *bus, sd_bus_message *message, void *userda /* Anyone can call this method */ -r =
Re: [systemd-devel] [PATCH 2/3] timer: timer can be a transient unit
On 10/23/2014 12:42 AM, Lennart Poettering wrote: On Tue, 07.10.14 14:20, WaLyong Cho (walyong@samsung.com) wrote: +assert(message); + +if (streq(name, OnActiveSec) || +streq(name, OnBootSec) || +streq(name, OnStartupSec) || +streq(name, OnUnitActiveSec) || +streq(name, OnUnitInactiveSec)) { I think it would be cool to use STR_IN_SET() here. Ok, I will do on next patch. + +TimerValue *v; +TimerBase b = _TIMER_BASE_INVALID; +usec_t u = 0; +CalendarSpec *c = NULL; + +b = timer_base_from_string(name); +if (b 0) +return 0; + +r = sd_bus_message_read(message, s, str); +if (r 0) +return r; + +if (mode != UNIT_CHECK) { +if (b == TIMER_CALENDAR) { Hmm, there's something wrong here, b can never be TIMER_CALENDAR as we never enter this if block for name == OnCalendar. Yes, right. I will add OnCalendar to above condition check. + +} else if (streq(name, AccuracySec)) { + +usec_t u = 0; + +r = sd_bus_message_read(message, s, str); +if (r 0) +return r; No. The accuracy should be of type t, and be called AccuracyUSec. There's a slight asymmetry between dbus interfaces and the config files here, as the bus interfaces always expose usec as uint64_t, while the config files default to sec as unit... Yes, right. I think we talked already about this. If systemd-run send parsed value then this also should be not string. +/* If trigger unit is transient, make sure be gabage + * collected. That maybe have no_gc to wait until this timer + * is started. */ +if (UNIT_TRIGGER(u)-transient) +UNIT_TRIGGER(u)-no_gc = false; + No, this should be unnecessary? timer units should just follow the normal GC logic, and get GC'ed as soon as they are not running or referenced anymore. If we only use StartTransientUnit then NOT necessary. This was added for keeping the generated transient service by NewTransientUnit what only exist on my previous patch. Some more detail, on previous my patch, there are two method calls. At the first, NewTransientUnit is sent for transient service. And the second, StartTransientUnit is sent for transient timer. The transient service was cleared by GC because there is no jobs and no dependencies on there. The transient service has dependency after the transient timer is loaded. Now we will only use StartTransientUnit so maybe this kind of hack will not be needed. Thanks, WaLyong Lennart ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [PATCH 3/3] run: introduce timer support option
On 10/23/2014 12:56 AM, Lennart Poettering wrote: On Tue, 07.10.14 14:20, WaLyong Cho (walyong@samsung.com) wrote: If systemd-run is called with timer option, then systemd-run call NewTransientUnit with service unit. And also call StartTransientUnit with timer unit which has same name with the service. So actually, two method call is coming and two transient unit is generated. One is service and the other is timer. Supported timer options are --after=, --after-boot=, --after-startup=, --after-active=, --after-inactive=, --calendar=, --accuracy= and --wake-system. Each option corresponding with OnActiveSec=, OnBootSec=, OnStartupSec=, OnUnitActiveSec=, OnUnitInactiveSec=, AccuracySec= and AccuracySec= of timer respectively. Hmm, I'd really like to stay close to the underlying props here in naming, and call the options --on-boot=, --on-inactive= and so on (the -sec suffix we can probably drop). I'd really tought and worried about naming of the options. At the first time, I'd made similar named option with timer unit. But I tought the command line options should be more meaningful or easy to understand. So I changed like this. But if you say so, I don't want to against to your opinion. I will change those. The AccuracySec= and WakeSystem= stuff I think we don't need to cover with a command line argument of its own, we can cover that with --property=. Ah, good, I didn't know that. I will do like that. +static bool with_timer = false; +static char *arg_after = NULL; +static char *arg_after_boot = NULL; +static char *arg_after_startup = NULL; +static char *arg_after_active = NULL; +static char *arg_after_inactive = NULL; +static char *arg_calendar = NULL; +static char *arg_accuracy = NULL; +static bool arg_wake_system = false; I'd just do one arg_on_timer usec_t variable to store most of the --on-xyz= values in. Plus one arg_on_calendar to hold the calendar expression. This should be much simpler than keeping one variable around for each. +case ARG_AFTER: +r = parse_sec(optarg, u); +if (r 0) { +log_error(Failed to parse timer value: %s, optarg); +return r; +} +arg_after = optarg; +with_timer = true; +break; This stuff really should not store the string, but the parsed value. Yeah, a couple of parse_sec doesn't make sense. How about calendar_spec_from_string? calendar_spec_from_string also be called twice on run and dbus-timer. I'm not sure the parsed calendar spec is able to be sent on current StartTransientUnit() interface. But even if possible, just string is obiously easy to send and receive. How do you think? (I'll leave the rest unreviewed for now, please rework this first to make use of the fourth StartTransientUnit() bus call argument!) If you reply on above question, then I will send patch again soon. Thanks, WaLyong Thanks, Lennart ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [PATCH 2/3] mac: rename apis with mac_{selinux/smack}_ prefix
On 10/23/2014 06:12 AM, Lennart Poettering wrote: On Thu, 16.10.14 16:59, WaLyong Cho (walyong@samsung.com) wrote: -if (smack_label_ip_in_fd(fd, s-smack_ip_in) 0) -log_error_unit(UNIT(s)-id, smack_label_ip_in_fd: %m); +if (mac_smack_ip_in_fd(fd, s-smack_ip_in) 0) +log_error_unit(UNIT(s)-id, -mac_smack_ip_in_fd: %m); I think this call should still contern a verb of some kind, do indicate what it does. mac_smack_label_ip_in_fd() or even mac_smack_relabel_ip_in_fd() or so? --- a/src/resolve/resolved-dns-domain.c +++ b/src/resolve/resolved-dns-domain.c @@ -169,7 +169,7 @@ int dns_label_escape(const char *p, size_t l, char **ret) { return r; } -int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max) { +int dns_mac_selinux_apply_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max) { THis looks like a copy/past error. This is not a security label here, but just a part of a DNS domain OMG, it caused by grep/sed script. I will modify that. Sorry. WaLyong Otherwise looks good! Could you please fix and rebase the series? I promise I will merge this quickly now, sorry reviewing this so slowly! It must have been awful constantly rebasing this without getting this merged! Sorry for that! Lennart ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [PATCH 3/3] udev: do NOT re-label smack
On 10/23/2014 06:13 AM, Lennart Poettering wrote: On Thu, 16.10.14 16:59, WaLyong Cho (walyong@samsung.com) wrote: If selinux is disabled and smack is only enabled, smack label is relable-ed by label_fix. To avoid, make only be labeled for selinux. --- src/udev/udev-node.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c index 9796672..6dd4e74 100644 --- a/src/udev/udev-node.c +++ b/src/udev/udev-node.c @@ -317,8 +317,8 @@ static int node_permissions_apply(struct udev_device *dev, bool apply, } /* set the defaults */ -if (!selinux) -label_fix(devnode, true, false); +if (!selinux use_selinux()) +mac_selinux_fix(devnode, true, false); Hmm, but doesn't mac_selinux_fix() check for use_selinux() internally anyway? Checking this outside sounds redundant, no? I will check this later after migration patch is merged. I will send a separated patch for this. Thanks, WaLyong Lennart ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH 1/2] label: rearrange mandatory access control(MAC) apis
From: WaLyong Cho walyong@samsung.com move label apis to selinux-util.ch or smack-util.ch appropriately. --- src/shared/label.c| 554 -- src/shared/label.h| 31 +-- src/shared/mkdir-label.c | 26 +++ src/shared/mkdir.h| 2 +- src/shared/selinux-util.c | 481 +++- src/shared/selinux-util.h | 27 +++ src/shared/smack-util.c | 45 +++- src/shared/smack-util.h | 1 + 8 files changed, 575 insertions(+), 592 deletions(-) diff --git a/src/shared/label.c b/src/shared/label.c index 69d4616..b48a4ff 100644 --- a/src/shared/label.c +++ b/src/shared/label.c @@ -19,170 +19,8 @@ along with systemd; If not, see http://www.gnu.org/licenses/. ***/ -#include errno.h -#include unistd.h -#include malloc.h -#include sys/socket.h -#include sys/un.h -#include sys/types.h -#include sys/stat.h -#include fcntl.h -#include sys/xattr.h -#ifdef HAVE_SELINUX -#include selinux/selinux.h -#include selinux/label.h -#include selinux/context.h -#endif - #include label.h -#include strv.h #include util.h -#include path-util.h -#include selinux-util.h -#include smack-util.h - -#ifdef HAVE_SELINUX -DEFINE_TRIVIAL_CLEANUP_FUNC(security_context_t, freecon); -DEFINE_TRIVIAL_CLEANUP_FUNC(context_t, context_free); - -#define _cleanup_security_context_free_ _cleanup_(freeconp) -#define _cleanup_context_free_ _cleanup_(context_freep) - -static struct selabel_handle *label_hnd = NULL; -#endif - -static int smack_relabel_in_dev(const char *path) { -int r = 0; - -#ifdef HAVE_SMACK -struct stat sb; -const char *label; - -/* - * Path must be in /dev and must exist - */ -if (!path_startswith(path, /dev)) -return 0; - -r = lstat(path, sb); -if (r 0) -return -errno; - -/* - * Label directories and character devices *. - * Label symlinks _. - * Don't change anything else. - */ -if (S_ISDIR(sb.st_mode)) -label = SMACK_STAR_LABEL; -else if (S_ISLNK(sb.st_mode)) -label = SMACK_FLOOR_LABEL; -else if (S_ISCHR(sb.st_mode)) -label = SMACK_STAR_LABEL; -else -return 0; - -r = setxattr(path, security.SMACK64, label, strlen(label), 0); -if (r 0) { -log_error(Smack relabeling \%s\ %m, path); -return -errno; -} -#endif - -return r; -} - -int label_init(const char *prefix) { -int r = 0; - -#ifdef HAVE_SELINUX -usec_t before_timestamp, after_timestamp; -struct mallinfo before_mallinfo, after_mallinfo; - -if (!use_selinux()) -return 0; - -if (label_hnd) -return 0; - -before_mallinfo = mallinfo(); -before_timestamp = now(CLOCK_MONOTONIC); - -if (prefix) { -struct selinux_opt options[] = { -{ .type = SELABEL_OPT_SUBSET, .value = prefix }, -}; - -label_hnd = selabel_open(SELABEL_CTX_FILE, options, ELEMENTSOF(options)); -} else -label_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0); - -if (!label_hnd) { -log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG, - Failed to initialize SELinux context: %m); -r = security_getenforce() == 1 ? -errno : 0; -} else { -char timespan[FORMAT_TIMESPAN_MAX]; -int l; - -after_timestamp = now(CLOCK_MONOTONIC); -after_mallinfo = mallinfo(); - -l = after_mallinfo.uordblks before_mallinfo.uordblks ? after_mallinfo.uordblks - before_mallinfo.uordblks : 0; - -log_debug(Successfully loaded SELinux database in %s, size on heap is %iK., - format_timespan(timespan, sizeof(timespan), after_timestamp - before_timestamp, 0), - (l+1023)/1024); -} -#endif - -return r; -} - -static int label_fix_selinux(const char *path, bool ignore_enoent, bool ignore_erofs) { -int r = 0; - -#ifdef HAVE_SELINUX -struct stat st; -security_context_t fcon; - -if (!label_hnd) -return 0; - -r = lstat(path, st); -if (r == 0) { -r = selabel_lookup_raw(label_hnd, fcon, path, st.st_mode); - -/* If there's no label to set, then exit without warning */ -if (r 0 errno == ENOENT) -return 0; - -if (r == 0) { -r = lsetfilecon(path, fcon); -freecon(fcon); - -/* If the FS doesn't support labels, then exit without warning */ -if (r 0 errno == ENOTSUP
[systemd-devel] [PATCH 2/2] mac: rename apis with mac_{selinux/smack}_ prefix
From: WaLyong Cho walyong@samsung.com --- src/core/execute.c| 2 +- src/core/main.c | 4 ++-- src/core/namespace.c | 4 ++-- src/core/selinux-setup.c | 4 ++-- src/core/socket.c | 26 +- src/hostname/hostnamed.c | 2 +- src/locale/localed.c | 2 +- src/login/logind-dbus.c | 2 +- src/resolve/resolved.c| 2 +- src/shared/dev-setup.c| 4 ++-- src/shared/fileio-label.c | 12 ++-- src/shared/label.c| 4 ++-- src/shared/mkdir-label.c | 4 ++-- src/shared/selinux-util.c | 28 ++-- src/shared/selinux-util.h | 34 +- src/shared/smack-util.c | 10 +- src/shared/smack-util.h | 10 +- src/shared/socket-label.c | 6 +++--- src/sysusers/sysusers.c | 2 +- src/test/test-udev.c | 4 ++-- src/timedate/timedated.c | 2 +- src/tmpfiles/tmpfiles.c | 32 src/udev/udev-node.c | 14 +++--- src/udev/udevadm.c| 4 ++-- src/udev/udevd.c | 4 ++-- src/update-done/update-done.c | 6 +++--- 26 files changed, 114 insertions(+), 114 deletions(-) diff --git a/src/core/execute.c b/src/core/execute.c index f535b47..caff2c6 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -1681,7 +1681,7 @@ static int exec_child(ExecCommand *command, if (params-selinux_context_net socket_fd = 0) { _cleanup_free_ char *label = NULL; -err = label_get_child_mls_label(socket_fd, command-path, label); +err = mac_selinux_get_child_mls_label(socket_fd, command-path, label); if (err 0) { *error = EXIT_SELINUX_CONTEXT; return err; diff --git a/src/core/main.c b/src/core/main.c index 0388f46..95597de 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1308,7 +1308,7 @@ int main(int argc, char *argv[]) { dual_timestamp_get(security_finish_timestamp); } -if (label_init(NULL) 0) +if (mac_selinux_init(NULL) 0) goto finish; if (!skip_setup) { @@ -1830,7 +1830,7 @@ finish: free(arg_start_timeout_reboot_arg); arg_start_timeout_reboot_arg = NULL; -label_finish(); +mac_selinux_finish(); if (reexecute) { const char **args; diff --git a/src/core/namespace.c b/src/core/namespace.c index ab03aeb..6dd7a4f 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -225,9 +225,9 @@ static int mount_dev(BindMount *m) { goto fail; } -label_context_set(d, st.st_mode); +mac_selinux_context_set(d, st.st_mode); r = mknod(dn, st.st_mode, st.st_rdev); -label_context_clear(); +mac_selinux_context_clear(); if (r 0) { r = -errno; diff --git a/src/core/selinux-setup.c b/src/core/selinux-setup.c index b419a27..8be97fc 100644 --- a/src/core/selinux-setup.c +++ b/src/core/selinux-setup.c @@ -87,7 +87,7 @@ int selinux_setup(bool *loaded_policy) { retest_selinux(); /* Transition to the new context */ -r = label_get_create_label_from_exe(SYSTEMD_BINARY_PATH, label); +r = mac_selinux_get_create_label_from_exe(SYSTEMD_BINARY_PATH, label); if (r 0 || label == NULL) { log_open(); log_error(Failed to compute init label, ignoring.); @@ -98,7 +98,7 @@ int selinux_setup(bool *loaded_policy) { if (r 0) log_error(Failed to transition into init label '%s', ignoring., label); -label_free(label); +mac_selinux_free(label); } after_load = now(CLOCK_MONOTONIC); diff --git a/src/core/socket.c b/src/core/socket.c index 00d5fd1..fce1695 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -921,12 +921,12 @@ static void socket_apply_socket_options(Socket *s, int fd) { } if (s-smack_ip_in) -if (smack_label_ip_in_fd(fd, s-smack_ip_in) 0) -log_error_unit(UNIT(s)-id, smack_label_ip_in_fd: %m); +if (mac_smack_set_ip_in_fd(fd, s-smack_ip_in) 0) +log_error_unit(UNIT(s)-id, mac_smack_set_ip_in_fd: %m); if (s-smack_ip_out) -if (smack_label_ip_out_fd(fd, s-smack_ip_out) 0) -log_error_unit(UNIT(s)-id, smack_label_ip_out_fd: %m
[systemd-devel] [RFC] tmpfiles.d with mac_label
As we know we can make a direcory or link or file or some others by using tmpfiles.d. But we can not apply mac_label on there when after that is genreated. How about add mac_label field on tmpfiles.d? Actually, now we can not assign a mac_label to newly generated directory. So we make a script which include mkdir/chsmack. (I'm not sure chsmack is official tool for get/set SMACK label. Anyway.) If tmpfiles.d have a field for mac_label then we don't need such a terrible scripts. ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [RFC] tmpfiles.d with mac_label
On 10/23/2014 05:34 PM, WaLyong Cho wrote: As we know we can make a direcory or link or file or some others by using tmpfiles.d. But we can not apply mac_label on there when after that is genreated. How about add mac_label field on tmpfiles.d? Actually, now we can not assign a mac_label to newly generated directory. So we make a script which include mkdir/chsmack. (I'm not sure chsmack is official tool for get/set SMACK label. Anyway.) If tmpfiles.d have a field for mac_label then we don't need such a terrible scripts. If you agree, SECLABEL{module} format will appropriate for that like udev rules. ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [PATCH 2/2] mac: rename apis with mac_{selinux/smack}_ prefix
On 10/24/2014 07:56 AM, Lennart Poettering wrote: On Thu, 23.10.14 17:23, WaLyong Cho (walyong@gmail.com) wrote: Heya! I merged both patches now! Thanks! After merging I reworked quite a bit more code to make the selinux and smack bits work more similar to each. I cannot test this though, as I don't run SMACK. I really hope I didn't break anything, could you test and verify? As I know, Tizen is most active test bed of SMACK. But I'm not sure they are using most recent systemd version. In my case, I'm working for mobile division and We are using systemd version 210 now. So, to test this we have to upgrade systemd to newest version. That's not easy now. But whenever will be. :) At that time, I will test that. Thanks, WaLyong It would be good if you could go through the various commits since I merged your patch. There were some changes that might be particularly relevant. Most specifically, I changed the code that applies the SMACK label to a path to use lsetxattr() instead of setxattr(). The code to remove a SMACK label was already use lremovexattr(), so I figured we should be symmetric here, and it appeared safer to me. AFAICS this changed didn't break anything, but again, I didn't test it. Thanks, Lennart ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [PATCH 3/3] udev: do NOT re-label smack
On 10/23/2014 06:13 AM, Lennart Poettering wrote: On Thu, 16.10.14 16:59, WaLyong Cho (walyong@samsung.com) wrote: If selinux is disabled and smack is only enabled, smack label is relable-ed by label_fix. To avoid, make only be labeled for selinux. --- src/udev/udev-node.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c index 9796672..6dd4e74 100644 --- a/src/udev/udev-node.c +++ b/src/udev/udev-node.c @@ -317,8 +317,8 @@ static int node_permissions_apply(struct udev_device *dev, bool apply, } /* set the defaults */ -if (!selinux) -label_fix(devnode, true, false); +if (!selinux use_selinux()) +mac_selinux_fix(devnode, true, false); Hmm, but doesn't mac_selinux_fix() check for use_selinux() internally anyway? Checking this outside sounds redundant, no? No, mac_selinux_fix() has no mac_selinux_use(). I will add mac_selinux_use() to mac_selinux_fix(). WaLyong Lennart ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH 2/2] udev: do NOT re-label smack
From: WaLyong Cho walyong@samsung.com If selinux is disabled and smack is only enabled, smack label is relable-ed by label_fix. To avoid, make only be labeled for selinux. --- src/udev/udev-node.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c index 4ac6f71..030e459 100644 --- a/src/udev/udev-node.c +++ b/src/udev/udev-node.c @@ -323,7 +323,7 @@ static int node_permissions_apply(struct udev_device *dev, bool apply, /* set the defaults */ if (!selinux) -label_fix(devnode, true, false); +mac_selinux_fix(devnode, true, false); if (!smack) mac_smack_apply(devnode, NULL); } -- 2.1.2 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH 1/2] selinux: make sure selinux is using on mac_selinux_fix()
--- src/shared/selinux-util.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/shared/selinux-util.c b/src/shared/selinux-util.c index 1eddd17..bb27328 100644 --- a/src/shared/selinux-util.c +++ b/src/shared/selinux-util.c @@ -128,6 +128,9 @@ int mac_selinux_fix(const char *path, bool ignore_enoent, bool ignore_erofs) { assert(path); +if (!mac_selinux_use()) +return 0; + /* if mac_selinux_init() wasn't called before we are a NOOP */ if (!label_hnd) return 0; -- 2.1.2 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH 2/3] mac: rename apis with mac_{selinux/smack}_ prefix
--- src/core/execute.c| 2 +- src/core/main.c | 4 ++-- src/core/namespace.c | 4 ++-- src/core/selinux-setup.c | 4 ++-- src/core/socket.c | 26 +- src/hostname/hostnamed.c | 2 +- src/locale/localed.c | 2 +- src/login/logind-dbus.c | 2 +- src/resolve/resolved-dns-domain.c | 2 +- src/resolve/resolved-dns-domain.h | 2 +- src/resolve/resolved-dns-packet.c | 2 +- src/resolve/resolved.c| 2 +- src/shared/dev-setup.c| 4 ++-- src/shared/fileio-label.c | 12 ++-- src/shared/label.c| 4 ++-- src/shared/mkdir-label.c | 4 ++-- src/shared/selinux-util.c | 28 ++-- src/shared/selinux-util.h | 34 +- src/shared/smack-util.c | 10 +- src/shared/smack-util.h | 10 +- src/shared/socket-label.c | 6 +++--- src/sysusers/sysusers.c | 2 +- src/test/test-udev.c | 4 ++-- src/timedate/timedated.c | 2 +- src/tmpfiles/tmpfiles.c | 32 src/udev/udev-node.c | 14 +++--- src/udev/udevadm.c| 4 ++-- src/udev/udevd.c | 4 ++-- src/update-done/update-done.c | 6 +++--- 29 files changed, 117 insertions(+), 117 deletions(-) diff --git a/src/core/execute.c b/src/core/execute.c index b165b33..49f1041 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -1678,7 +1678,7 @@ static int exec_child(ExecCommand *command, if (params-selinux_context_net socket_fd = 0) { _cleanup_free_ char *label = NULL; -err = label_get_child_mls_label(socket_fd, command-path, label); +err = mac_selinux_get_child_mls_label(socket_fd, command-path, label); if (err 0) { *error = EXIT_SELINUX_CONTEXT; return err; diff --git a/src/core/main.c b/src/core/main.c index 44373cc..2740dd5 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1308,7 +1308,7 @@ int main(int argc, char *argv[]) { dual_timestamp_get(security_finish_timestamp); } -if (label_init(NULL) 0) +if (mac_selinux_init(NULL) 0) goto finish; if (!skip_setup) { @@ -1830,7 +1830,7 @@ finish: free(arg_start_timeout_reboot_arg); arg_start_timeout_reboot_arg = NULL; -label_finish(); +mac_selinux_finish(); if (reexecute) { const char **args; diff --git a/src/core/namespace.c b/src/core/namespace.c index c221509..d1cfd00 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -225,9 +225,9 @@ static int mount_dev(BindMount *m) { goto fail; } -label_context_set(d, st.st_mode); +mac_selinux_context_set(d, st.st_mode); r = mknod(dn, st.st_mode, st.st_rdev); -label_context_clear(); +mac_selinux_context_clear(); if (r 0) { r = -errno; diff --git a/src/core/selinux-setup.c b/src/core/selinux-setup.c index b419a27..8be97fc 100644 --- a/src/core/selinux-setup.c +++ b/src/core/selinux-setup.c @@ -87,7 +87,7 @@ int selinux_setup(bool *loaded_policy) { retest_selinux(); /* Transition to the new context */ -r = label_get_create_label_from_exe(SYSTEMD_BINARY_PATH, label); +r = mac_selinux_get_create_label_from_exe(SYSTEMD_BINARY_PATH, label); if (r 0 || label == NULL) { log_open(); log_error(Failed to compute init label, ignoring.); @@ -98,7 +98,7 @@ int selinux_setup(bool *loaded_policy) { if (r 0) log_error(Failed to transition into init label '%s', ignoring., label); -label_free(label); +mac_selinux_free(label); } after_load = now(CLOCK_MONOTONIC); diff --git a/src/core/socket.c b/src/core/socket.c index 00d5fd1..12be192 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -921,12 +921,12 @@ static void socket_apply_socket_options(Socket *s, int fd) { } if (s-smack_ip_in) -if (smack_label_ip_in_fd(fd, s-smack_ip_in) 0) -log_error_unit(UNIT(s)-id, smack_label_ip_in_fd: %m); +if (mac_smack_ip_in_fd(fd, s-smack_ip_in) 0) +log_error_unit(UNIT(s)-id, mac_smack_ip_in_fd:
[systemd-devel] [PATCH 3/3] udev: do NOT re-label smack
If selinux is disabled and smack is only enabled, smack label is relable-ed by label_fix. To avoid, make only be labeled for selinux. --- src/udev/udev-node.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c index 9796672..6dd4e74 100644 --- a/src/udev/udev-node.c +++ b/src/udev/udev-node.c @@ -317,8 +317,8 @@ static int node_permissions_apply(struct udev_device *dev, bool apply, } /* set the defaults */ -if (!selinux) -label_fix(devnode, true, false); +if (!selinux use_selinux()) +mac_selinux_fix(devnode, true, false); if (!smack) mac_smack_path(devnode, NULL); } -- 1.9.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH 1/3] label: rearrange mandatory access control(MAC) apis
move label apis to selinux-util.ch or smack-util.ch appropriately. --- src/shared/label.c| 554 -- src/shared/label.h| 31 +-- src/shared/mkdir-label.c | 26 +++ src/shared/mkdir.h| 2 +- src/shared/selinux-util.c | 481 +++- src/shared/selinux-util.h | 27 +++ src/shared/smack-util.c | 45 +++- src/shared/smack-util.h | 1 + 8 files changed, 575 insertions(+), 592 deletions(-) diff --git a/src/shared/label.c b/src/shared/label.c index 69d4616..b48a4ff 100644 --- a/src/shared/label.c +++ b/src/shared/label.c @@ -19,170 +19,8 @@ along with systemd; If not, see http://www.gnu.org/licenses/. ***/ -#include errno.h -#include unistd.h -#include malloc.h -#include sys/socket.h -#include sys/un.h -#include sys/types.h -#include sys/stat.h -#include fcntl.h -#include sys/xattr.h -#ifdef HAVE_SELINUX -#include selinux/selinux.h -#include selinux/label.h -#include selinux/context.h -#endif - #include label.h -#include strv.h #include util.h -#include path-util.h -#include selinux-util.h -#include smack-util.h - -#ifdef HAVE_SELINUX -DEFINE_TRIVIAL_CLEANUP_FUNC(security_context_t, freecon); -DEFINE_TRIVIAL_CLEANUP_FUNC(context_t, context_free); - -#define _cleanup_security_context_free_ _cleanup_(freeconp) -#define _cleanup_context_free_ _cleanup_(context_freep) - -static struct selabel_handle *label_hnd = NULL; -#endif - -static int smack_relabel_in_dev(const char *path) { -int r = 0; - -#ifdef HAVE_SMACK -struct stat sb; -const char *label; - -/* - * Path must be in /dev and must exist - */ -if (!path_startswith(path, /dev)) -return 0; - -r = lstat(path, sb); -if (r 0) -return -errno; - -/* - * Label directories and character devices *. - * Label symlinks _. - * Don't change anything else. - */ -if (S_ISDIR(sb.st_mode)) -label = SMACK_STAR_LABEL; -else if (S_ISLNK(sb.st_mode)) -label = SMACK_FLOOR_LABEL; -else if (S_ISCHR(sb.st_mode)) -label = SMACK_STAR_LABEL; -else -return 0; - -r = setxattr(path, security.SMACK64, label, strlen(label), 0); -if (r 0) { -log_error(Smack relabeling \%s\ %m, path); -return -errno; -} -#endif - -return r; -} - -int label_init(const char *prefix) { -int r = 0; - -#ifdef HAVE_SELINUX -usec_t before_timestamp, after_timestamp; -struct mallinfo before_mallinfo, after_mallinfo; - -if (!use_selinux()) -return 0; - -if (label_hnd) -return 0; - -before_mallinfo = mallinfo(); -before_timestamp = now(CLOCK_MONOTONIC); - -if (prefix) { -struct selinux_opt options[] = { -{ .type = SELABEL_OPT_SUBSET, .value = prefix }, -}; - -label_hnd = selabel_open(SELABEL_CTX_FILE, options, ELEMENTSOF(options)); -} else -label_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0); - -if (!label_hnd) { -log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG, - Failed to initialize SELinux context: %m); -r = security_getenforce() == 1 ? -errno : 0; -} else { -char timespan[FORMAT_TIMESPAN_MAX]; -int l; - -after_timestamp = now(CLOCK_MONOTONIC); -after_mallinfo = mallinfo(); - -l = after_mallinfo.uordblks before_mallinfo.uordblks ? after_mallinfo.uordblks - before_mallinfo.uordblks : 0; - -log_debug(Successfully loaded SELinux database in %s, size on heap is %iK., - format_timespan(timespan, sizeof(timespan), after_timestamp - before_timestamp, 0), - (l+1023)/1024); -} -#endif - -return r; -} - -static int label_fix_selinux(const char *path, bool ignore_enoent, bool ignore_erofs) { -int r = 0; - -#ifdef HAVE_SELINUX -struct stat st; -security_context_t fcon; - -if (!label_hnd) -return 0; - -r = lstat(path, st); -if (r == 0) { -r = selabel_lookup_raw(label_hnd, fcon, path, st.st_mode); - -/* If there's no label to set, then exit without warning */ -if (r 0 errno == ENOENT) -return 0; - -if (r == 0) { -r = lsetfilecon(path, fcon); -freecon(fcon); - -/* If the FS doesn't support labels, then exit without warning */ -if (r 0 errno == ENOTSUP) -return 0; -} -} - -
[systemd-devel] [PATCH] resolve: suppress warning
--- src/resolve/resolved.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/resolve/resolved.c b/src/resolve/resolved.c index ef416e5..d612938 100644 --- a/src/resolve/resolved.c +++ b/src/resolve/resolved.c @@ -26,6 +26,7 @@ #include resolved-manager.h #include resolved-conf.h +#include label.h int main(int argc, char *argv[]) { _cleanup_(manager_freep) Manager *m = NULL; -- 2.1.2 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH 1/3] dbus: introduce new method call NewTransientUnit
It similar with StartTransientUnit but the NewTransientUnit does not start the unit immediately. Newly generated transient unit can be activated by systemctl start. --- src/core/dbus-manager.c| 99 +- src/core/org.freedesktop.systemd1.conf | 4 ++ src/core/service.c | 12 + 3 files changed, 103 insertions(+), 12 deletions(-) diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 533ce43..84c913b 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -615,10 +615,15 @@ static int method_set_unit_properties(sd_bus *bus, sd_bus_message *message, void return bus_unit_method_set_properties(bus, message, u, error); } -static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { +static int new_transient_unit_from_message(sd_bus *bus, + sd_bus_message *message, + void *userdata, + sd_bus_error *error, + Unit **unit, + JobMode *mode, + bool keep) { const char *name, *smode; Manager *m = userdata; -JobMode mode; UnitType t; Unit *u; int r; @@ -631,7 +636,9 @@ static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, voi if (r 0) return r; if (r == 0) -return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ +/* No authorization for now, but the async polkit + * stuff will call us again when it has it */ +return 1; r = sd_bus_message_read(message, ss, name, smode); if (r 0) @@ -639,14 +646,22 @@ static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, voi t = unit_name_to_type(name); if (t 0) -return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, Invalid unit type.); +return sd_bus_error_setf(error, + SD_BUS_ERROR_INVALID_ARGS, + Invalid unit type.); if (!unit_vtable[t]-can_transient) -return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, Unit type %s does not support transient units., unit_type_to_string(t)); - -mode = job_mode_from_string(smode); -if (mode 0) -return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, Job mode %s is invalid., smode); +return sd_bus_error_setf(error, + SD_BUS_ERROR_INVALID_ARGS, + Unit type %s does not support transient units., + unit_type_to_string(t)); + +*mode = job_mode_from_string(smode); +if (*mode 0) +return sd_bus_error_setf(error, + SD_BUS_ERROR_INVALID_ARGS, + Job mode %s is invalid., + smode); r = selinux_access_check(message, start, error); if (r 0) @@ -656,8 +671,12 @@ static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, voi if (r 0) return r; -if (u-load_state != UNIT_NOT_FOUND || set_size(u-dependencies[UNIT_REFERENCED_BY]) 0) -return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, Unit %s already exists., name); +if (u-load_state != UNIT_NOT_FOUND || +set_size(u-dependencies[UNIT_REFERENCED_BY]) 0) +return sd_bus_error_setf(error, + BUS_ERROR_UNIT_EXISTS, + Unit %s already exists., + name); /* OK, the unit failed to load and is unreferenced, now let's * fill in the transient data instead */ @@ -675,10 +694,65 @@ static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, voi if (r 0) return r; +*unit = u; manager_dispatch_load_queue(m); +return 0; +} + +static int method_new_transient_unit(sd_bus *bus, + sd_bus_message *message, + void *userdata, + sd_bus_error *error) { +_cleanup_free_ char *path = NULL; +JobMode mode; +Unit *u = NULL; +int r; + +r = new_transient_unit_from_message(bus, +message, +userdata, +
[systemd-devel] [PATCH 3/3] run: introduce timer support option
If systemd-run is called with timer option, then systemd-run call NewTransientUnit with service unit. And also call StartTransientUnit with timer unit which has same name with the service. So actually, two method call is coming and two transient unit is generated. One is service and the other is timer. Supported timer options are --after=, --after-boot=, --after-startup=, --after-active=, --after-inactive=, --calendar=, --accuracy= and --wake-system. Each option corresponding with OnActiveSec=, OnBootSec=, OnStartupSec=, OnUnitActiveSec=, OnUnitInactiveSec=, AccuracySec= and AccuracySec= of timer respectively. --- man/systemd-run.xml | 70 + src/run/run.c | 294 ++-- 2 files changed, 331 insertions(+), 33 deletions(-) diff --git a/man/systemd-run.xml b/man/systemd-run.xml index 0c9d13d..452721c 100644 --- a/man/systemd-run.xml +++ b/man/systemd-run.xml @@ -210,6 +210,64 @@ along with systemd; If not, see http://www.gnu.org/licenses/. xi:include href=user-system-options.xml xpointer=host / xi:include href=user-system-options.xml xpointer=machine / + varlistentry +termoption--after=/option/term +termoption--after-boot=/option/term +termoption--after-startup=/option/term +termoption--after-active=/option/term +termoption--after-inactive=/option/term + +listitemparaDefines monotonic timers relative to different +starting points. Also see varnameOnActiveSec=/varname, +varnameOnBootSec=/varname, +varnameOnStartupSec=/varname, +varnameOnUnitActiveSec=/varname and +varnameOnUnitInactiveSec=/varname in + citerefentryrefentrytitlesystemd.timer/refentrytitlemanvolnum5/manvolnum/citerefentry. This +option has no effect in conjunction with +option--scope/option./para +/listitem + /varlistentry + + varlistentry +termoption--calendar=/option/term + +listitemparaDefines realtime (i.e. wallclock) timers with +calendar event expressions. Also see +varnameOnCalendar=/varname in + citerefentryrefentrytitlesystemd.timer/refentrytitlemanvolnum5/manvolnum/citerefentry. This +option has no effect in conjunction with +option--scope/option./para +/listitem + /varlistentry + + varlistentry +termoption--accuracy=/option/term + +listitemparaSpecify the accuracy the timer shall elapse +with. Also see varnameAccuracySec=/varname in + citerefentryrefentrytitlesystemd.timer/refentrytitlemanvolnum5/manvolnum/citerefentry. This +option only has effect with option--after=/option, +option--after-boot=/option, option--after-startup=/option, +option--after-active=/option, option--after-inactive=/option +or option--calendar=/option./para +/listitem + /varlistentry + + varlistentry +termoption--wake-system/option/term + +listitemparaElapsing timer will cause the system to resume +from suspend, should it be suspended and if the system supports +this. Also see varnameWakeSystem=/varname in + citerefentryrefentrytitlesystemd.timer/refentrytitlemanvolnum5/manvolnum/citerefentry. This +option only has effect with option--after=/option, +option--after-boot=/option, option--after-startup=/option, +option--after-active=/option, option--after-inactive=/option +or option--calendar=/option./para +/listitem + /varlistentry + xi:include href=standard-options.xml xpointer=help / xi:include href=standard-options.xml xpointer=version / /variablelist @@ -250,6 +308,17 @@ Sep 08 07:37:21 bupkis env[19948]: BOOT_IMAGE=/vmlinuz-3.11.0-0.rc5.git6.2.fc20. property./para programlisting# systemd-run -p BlockIOWeight=10 updatedb/programlisting + +paraThe following command will touch a file after 10 seconds./para + +programlisting# date; systemd-run --after=10 --accuracy=100ms touch /tmp/hello +Tue Oct 7 14:00:37 KST 2014 +Will running as unit run-115.service. +Running as unit run-115.timer. +# journalctl -u run-115.service +-- Logs begin at Sat 2014-10-04 13:54:49 KST, end at Tue 2014-10-07 14:00:47 KST. -- +Oct 07 14:00:47 container systemd[1]: Starting /bin/touch /tmp/hello... +Oct 07 14:00:47 container systemd[1]: Started /bin/touch /tmp/hello./programlisting /refsect1 refsect1 @@ -263,6 +332,7 @@ Sep 08 07:37:21 bupkis env[19948]: BOOT_IMAGE=/vmlinuz-3.11.0-0.rc5.git6.2.fc20. citerefentryrefentrytitlesystemd.slice/refentrytitlemanvolnum5/manvolnum/citerefentry, citerefentryrefentrytitlesystemd.exec/refentrytitlemanvolnum5/manvolnum/citerefentry, citerefentryrefentrytitlesystemd.resource-control/refentrytitlemanvolnum5/manvolnum/citerefentry, +
[systemd-devel] [PATCH 2/3] timer: timer can be a transient unit
--- src/core/dbus-timer.c | 140 ++ src/core/dbus-timer.h | 3 ++ src/core/timer.c | 10 3 files changed, 153 insertions(+) diff --git a/src/core/dbus-timer.c b/src/core/dbus-timer.c index f1f8c54..5f0b80e 100644 --- a/src/core/dbus-timer.c +++ b/src/core/dbus-timer.c @@ -24,6 +24,7 @@ #include dbus-unit.h #include dbus-timer.h #include bus-util.h +#include errno-list.h static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, timer_result, TimerResult); @@ -183,3 +184,142 @@ const sd_bus_vtable bus_timer_vtable[] = { SD_BUS_PROPERTY(WakeSystem, b, bus_property_get_bool, offsetof(Timer, wake_system), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_VTABLE_END }; + +static int bus_timer_set_transient_property( +Timer *t, +const char *name, +sd_bus_message *message, +UnitSetPropertiesMode mode, +sd_bus_error *error) { + +const char *str; +int r; + +assert(t); +assert(name); +assert(message); + +if (streq(name, OnActiveSec) || +streq(name, OnBootSec) || +streq(name, OnStartupSec) || +streq(name, OnUnitActiveSec) || +streq(name, OnUnitInactiveSec)) { + +TimerValue *v; +TimerBase b = _TIMER_BASE_INVALID; +usec_t u = 0; +CalendarSpec *c = NULL; + +b = timer_base_from_string(name); +if (b 0) +return 0; + +r = sd_bus_message_read(message, s, str); +if (r 0) +return r; + +if (mode != UNIT_CHECK) { +if (b == TIMER_CALENDAR) { +r = calendar_spec_from_string(str, c); +if (r 0) +return r; +} else { +r = parse_sec(str, u); +if (r 0) +return r; +} + +unit_write_drop_in_private_format(UNIT(t), + mode, + name, + %s=%s\n, + name, + str); + +v = new0(TimerValue, 1); +if (!v) { +if (c) +calendar_spec_free(c); +return -ENOMEM; +} + +v-base = b; +v-value = u; +v-calendar_spec = c; + +LIST_PREPEND(value, t-values, v); +} + +return 1; + +} else if (streq(name, AccuracySec)) { + +usec_t u = 0; + +r = sd_bus_message_read(message, s, str); +if (r 0) +return r; + +r = parse_sec(str, u); +if (r 0) +return r; + +if (mode != UNIT_CHECK) { +t-accuracy_usec = u; +unit_write_drop_in_private_format(UNIT(t), + mode, + name, + %s=%s\n, + name, + str); +} + +return 1; + +} else if (streq(name, WakeSystem)) { + +int b; + +r = sd_bus_message_read(message, b, b); +if (r 0) +return r; + +if (mode != UNIT_CHECK) { +t-wake_system = b; +unit_write_drop_in_private_format(UNIT(t), + mode, + name, + %s=%s\n, + name, + yes_no(t-wake_system)); +} + +return 1; + +} + +return 0; +} + +int bus_timer_set_property( +Unit *u, +const char *name, +sd_bus_message *message, +UnitSetPropertiesMode mode, +sd_bus_error *error) { + +Timer *t = TIMER(u); +int r; + +
[systemd-devel] [PATCH] label: suppress warning on without selinux
--- src/shared/label.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/shared/label.c b/src/shared/label.c index 02b41f0..b6af38d 100644 --- a/src/shared/label.c +++ b/src/shared/label.c @@ -252,9 +252,10 @@ fail: int label_get_our_label(char **label) { int r = -EOPNOTSUPP; -char *l = NULL; #ifdef HAVE_SELINUX +char *l = NULL; + r = getcon(l); if (r 0) return r; -- 2.1.0 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [RFC] runtime configurable timer
On 09/12/2014 12:54 AM, David Herrmann wrote: Hi On Thu, Sep 11, 2014 at 10:45 AM, WaLyong Cho walyong@samsung.com wrote: (I will happy there is already similar method already exist.) systemd already has similar functionality systemd-run but that is only for scope or service unit. I think that is useful run a service without unit file on permanent storage. As a similar method, is it possible to generate or configure timer unit on runtime? Honestly, now, I need a runtime configurable timer interface. If systemd has this then I can reduce one of daemon. Something like at(1)? That is, executing a command at a later time? Yes, exactly right. Currently, timer units do not support transient units. So to implement something like systemd-at, you'd first have to add support for that, then you can make systemd-run do this. I don't think anyone has worked on this so far. Before start working it, we need some of discussion about how make the transient unit. I think we have two options. One is, as you said, make systemd-at and the other is add option to systemd-run. (e.g. --OnCalendar=, --OnActiveSec= or so) If we choose the former, then we should consider how load the relate unit(service). Because, the timer unit is not working alone. It related with service unit. So, if the transient timer unit related with already existing service then it will not much complicate. But if we want to add both transient timer and transient service then it will more complicate. In latter case, I think, it is more easier. Because, we can get a all of information to make two transient service transient timer. But internally we should call StartTransientUnit method call to start the timer unit and AddTransientUnit(or LoadTransientUnit(?)) to add service unit what will be started by the timer unit. Any other ideas? WaLyong Thanks David ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH 2/2] udev: do NOT re-label smack
If selinux is disabled and smack is only enabled, smack label is relable-ed by label_fix. To avoid, make only be labeled for selinux. --- src/udev/udev-node.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c index f46638f..3c49482 100644 --- a/src/udev/udev-node.c +++ b/src/udev/udev-node.c @@ -313,8 +313,8 @@ static int node_permissions_apply(struct udev_device *dev, bool apply, } /* set the defaults */ -if (!selinux) -label_fix(devnode, true, false); +if (!selinux use_selinux()) +mac_selinux_fix(devnode, true, false); if (!smack) mac_smack_path(devnode, NULL); } -- 1.9.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH 0/2] label: rearrange mandatory access control(MAC) apis
rebased again. It make a conflict by long pending. WaLyong Cho (2): label: rearrange mandatory access control(MAC) apis udev: do NOT re-label smack src/core/main.c | 4 +- src/core/namespace.c | 4 +- src/core/selinux-setup.c | 4 +- src/core/socket.c | 24 +-- src/hostname/hostnamed.c | 2 +- src/locale/localed.c | 2 +- src/login/logind-dbus.c | 2 +- src/shared/dev-setup.c| 4 +- src/shared/fileio-label.c | 12 +- src/shared/label.c| 445 +- src/shared/label.h| 26 +-- src/shared/mkdir-label.c | 26 +++ src/shared/mkdir.h| 2 +- src/shared/selinux-util.c | 365 +- src/shared/selinux-util.h | 14 ++ src/shared/smack-util.c | 53 - src/shared/smack-util.h | 10 +- src/shared/socket-label.c | 6 +- src/sysusers/sysusers.c | 2 +- src/test/test-udev.c | 4 +- src/timedate/timedated.c | 2 +- src/tmpfiles/tmpfiles.c | 32 +-- src/udev/udev-node.c | 18 +- src/udev/udevadm.c| 4 +- src/udev/udevd.c | 4 +- src/update-done/update-done.c | 6 +- 26 files changed, 528 insertions(+), 549 deletions(-) -- 1.9.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [RFC] runtime configurable timer
(I will happy there is already similar method already exist.) systemd already has similar functionality systemd-run but that is only for scope or service unit. I think that is useful run a service without unit file on permanent storage. As a similar method, is it possible to generate or configure timer unit on runtime? Honestly, now, I need a runtime configurable timer interface. If systemd has this then I can reduce one of daemon. Thanks, WaLyong ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel