[systemd-commits] 2 commits - man/systemd.path.xml man/systemd.unit.xml src/condition.c src/condition.h src/load-fragment.c src/path.c src/path.h src/util.c src/util.h TODO
Lennart Poettering
lennart at kemper.freedesktop.org
Wed Jul 6 17:07:50 PDT 2011
TODO | 45 ++++++++++++++++-----------------------------
man/systemd.path.xml | 16 +++++++++++-----
man/systemd.unit.xml | 20 +++++++++++++-------
src/condition.c | 6 ++++++
src/condition.h | 1 +
src/load-fragment.c | 12 +++++++-----
src/path.c | 8 +++++++-
src/path.h | 1 +
src/util.c | 25 +++++++++++++++++++++++++
src/util.h | 2 ++
10 files changed, 89 insertions(+), 47 deletions(-)
New commits:
commit 8092a428d40ac682df9e80c36988043854579679
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Jul 7 02:07:39 2011 +0200
path,unit: support globbing in conditions and path units
diff --git a/TODO b/TODO
index 721e827..6ce4240 100644
--- a/TODO
+++ b/TODO
@@ -20,9 +20,9 @@ F15 External:
Features:
-* support presets
+* add loginctl, i.e. a systemctl for logind introspection
-* wildcard support for .path units (think CUPS spool directory!)
+* support presets
* kernel: add /proc/sys file exposing CAP_LAST_CAP?
diff --git a/man/systemd.path.xml b/man/systemd.path.xml
index e816c30..f99931a 100644
--- a/man/systemd.path.xml
+++ b/man/systemd.path.xml
@@ -111,6 +111,7 @@
<variablelist>
<varlistentry>
<term><varname>PathExists=</varname></term>
+ <term><varname>PathExistsGlob=</varname></term>
<term><varname>PathChanged=</varname></term>
<term><varname>DirectoryNotEmpty=</varname></term>
@@ -121,7 +122,11 @@
file or directory. If the file
specified exists the configured unit
is
- activated. <varname>PathChanged=</varname>
+ activated. <varname>PathExistsGlob=</varname>
+ works similar, but checks for the
+ existance of at least one file
+ matching the globbing pattern
+ specified. <varname>PathChanged=</varname>
may be used to watch a file or
directory and activate the configured
unit whenever it changes or is
@@ -140,12 +145,13 @@
<para>If a path is already existing
(in case of
- <varname>PathExists=</varname>) or a
- directory already is not empty (in
+ <varname>PathExists=</varname> and
+ <varname>PathExistsGlob=</varname>) or
+ a directory already is not empty (in
case of
<varname>DirectoryNotEmpty=</varname>)
- at the time the path unit is activated,
- then the configured unit is
+ at the time the path unit is
+ activated, then the configured unit is
immediately activated as
well. Something similar does not apply
to <varname>PathChanged=</varname>.
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
index dd32e55..0ca18bd 100644
--- a/man/systemd.unit.xml
+++ b/man/systemd.unit.xml
@@ -607,6 +607,7 @@
<varlistentry>
<term><varname>ConditionPathExists=</varname></term>
+ <term><varname>ConditionPathExistsGlob=</varname></term>
<term><varname>ConditionPathIsDirectory=</varname></term>
<term><varname>ConditionDirectoryNotEmpty=</varname></term>
<term><varname>ConditionKernelCommandLine=</varname></term>
@@ -632,7 +633,12 @@
is prefixed with an exclamation mark
(!), the test is negated, and the unit
only started if the path does not
- exist. <varname>ConditionPathIsDirectory=</varname>
+ exist. <varname>ConditionPathExistsGlob=</varname>
+ work in a similar way, but checks for
+ the existance of at least one file or
+ directory matching the specified
+ globbing
+ pattern. <varname>ConditionPathIsDirectory=</varname>
is similar to
<varname>ConditionPathExists=</varname>
but verifies whether a certain path
@@ -677,12 +683,12 @@
test may be negated by prepending an
exclamation mark.
<varname>ConditionSecurity=</varname>
- may be used to check whether the given security
- module is enabled on the system.
- Currently the only recognized value is
- <varname>selinux</varname>.
- The test may be negated by prepending an
- exclamation mark. Finally,
+ may be used to check whether the given
+ security module is enabled on the
+ system. Currently the only recognized
+ value is <varname>selinux</varname>.
+ The test may be negated by prepending
+ an exclamation mark. Finally,
<varname>ConditionNull=</varname> may
be used to add a constant condition
check value to the unit. It takes a
diff --git a/src/condition.c b/src/condition.c
index a520e43..76ee037 100644
--- a/src/condition.c
+++ b/src/condition.c
@@ -34,6 +34,8 @@
Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate) {
Condition *c;
+ assert(type < _CONDITION_TYPE_MAX);
+
if (!(c = new0(Condition, 1)))
return NULL;
@@ -148,6 +150,9 @@ bool condition_test(Condition *c) {
case CONDITION_PATH_EXISTS:
return (access(c->parameter, F_OK) >= 0) == !c->negate;
+ case CONDITION_PATH_EXISTS_GLOB:
+ return (glob_exists(c->parameter) > 0) == !c->negate;
+
case CONDITION_PATH_IS_DIRECTORY: {
struct stat st;
@@ -231,6 +236,7 @@ void condition_dump_list(Condition *first, FILE *f, const char *prefix) {
static const char* const condition_type_table[_CONDITION_TYPE_MAX] = {
[CONDITION_PATH_EXISTS] = "ConditionPathExists",
+ [CONDITION_PATH_EXISTS_GLOB] = "ConditionPathExistsGlob",
[CONDITION_PATH_IS_DIRECTORY] = "ConditionPathIsDirectory",
[CONDITION_DIRECTORY_NOT_EMPTY] = "ConditionDirectoryNotEmpty",
[CONDITION_KERNEL_COMMAND_LINE] = "ConditionKernelCommandLine",
diff --git a/src/condition.h b/src/condition.h
index 8402802..ff896a7 100644
--- a/src/condition.h
+++ b/src/condition.h
@@ -28,6 +28,7 @@
typedef enum ConditionType {
CONDITION_PATH_EXISTS,
+ CONDITION_PATH_EXISTS_GLOB,
CONDITION_PATH_IS_DIRECTORY,
CONDITION_DIRECTORY_NOT_EMPTY,
CONDITION_KERNEL_COMMAND_LINE,
diff --git a/src/load-fragment.c b/src/load-fragment.c
index 8f39839..05e60bf 100644
--- a/src/load-fragment.c
+++ b/src/load-fragment.c
@@ -1999,12 +1999,13 @@ static int load_from_path(Unit *u, const char *path) {
{ "IgnoreOnIsolate", config_parse_bool, 0, &u->meta.ignore_on_isolate, "Unit" },
{ "IgnoreOnSnapshot", config_parse_bool, 0, &u->meta.ignore_on_snapshot, "Unit" },
{ "JobTimeoutSec", config_parse_usec, 0, &u->meta.job_timeout, "Unit" },
- { "ConditionPathExists", config_parse_condition_path, CONDITION_PATH_EXISTS, u, "Unit" },
- { "ConditionPathIsDirectory", config_parse_condition_path, CONDITION_PATH_IS_DIRECTORY, u, "Unit" },
- { "ConditionDirectoryNotEmpty", config_parse_condition_path, CONDITION_DIRECTORY_NOT_EMPTY, u, "Unit" },
+ { "ConditionPathExists", config_parse_condition_path, CONDITION_PATH_EXISTS, u, "Unit" },
+ { "ConditionPathExistsGlob", config_parse_condition_path, CONDITION_PATH_EXISTS_GLOB, u, "Unit" },
+ { "ConditionPathIsDirectory", config_parse_condition_path, CONDITION_PATH_IS_DIRECTORY, u, "Unit" },
+ { "ConditionDirectoryNotEmpty", config_parse_condition_path, CONDITION_DIRECTORY_NOT_EMPTY, u, "Unit" },
{ "ConditionKernelCommandLine", config_parse_condition_string, CONDITION_KERNEL_COMMAND_LINE, u, "Unit" },
- { "ConditionVirtualization", config_parse_condition_string, CONDITION_VIRTUALIZATION, u, "Unit" },
- { "ConditionSecurity", config_parse_condition_string, CONDITION_SECURITY, u, "Unit" },
+ { "ConditionVirtualization", config_parse_condition_string, CONDITION_VIRTUALIZATION, u, "Unit" },
+ { "ConditionSecurity", config_parse_condition_string, CONDITION_SECURITY, u, "Unit" },
{ "ConditionNull", config_parse_condition_null, 0, u, "Unit" },
{ "PIDFile", config_parse_path_printf, 0, &u->service.pid_file, "Service" },
@@ -2094,6 +2095,7 @@ static int load_from_path(Unit *u, const char *path) {
{ "Unit", config_parse_timer_unit, 0, &u->timer, "Timer" },
{ "PathExists", config_parse_path_spec, 0, &u->path, "Path" },
+ { "PathExistsGlob", config_parse_path_spec, 0, &u->path, "Path" },
{ "PathChanged", config_parse_path_spec, 0, &u->path, "Path" },
{ "DirectoryNotEmpty", config_parse_path_spec, 0, &u->path, "Path" },
{ "Unit", config_parse_path_unit, 0, &u->path, "Path" },
diff --git a/src/path.c b/src/path.c
index 1c20dcf..200fc2b 100644
--- a/src/path.c
+++ b/src/path.c
@@ -197,6 +197,7 @@ static void path_dump(Unit *u, FILE *f, const char *prefix) {
static int path_watch_one(Path *p, PathSpec *s) {
static const int flags_table[_PATH_TYPE_MAX] = {
[PATH_EXISTS] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB,
+ [PATH_EXISTS_GLOB] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB,
[PATH_CHANGED] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CLOSE_WRITE|IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO,
[PATH_DIRECTORY_NOT_EMPTY] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CREATE|IN_MOVED_TO
};
@@ -367,6 +368,10 @@ static bool path_check_good(Path *p, bool initial) {
good = access(s->path, F_OK) >= 0;
break;
+ case PATH_EXISTS_GLOB:
+ good = glob_exists(s->path) > 0;
+ break;
+
case PATH_DIRECTORY_NOT_EMPTY: {
int k;
@@ -438,7 +443,7 @@ static void path_mkdir(Path *p) {
LIST_FOREACH(spec, s, p->specs) {
int r;
- if (s->type == PATH_EXISTS)
+ if (s->type == PATH_EXISTS || s->type == PATH_EXISTS_GLOB)
continue;
if ((r = mkdir_p(s->path, p->directory_mode)) < 0)
@@ -672,6 +677,7 @@ DEFINE_STRING_TABLE_LOOKUP(path_state, PathState);
static const char* const path_type_table[_PATH_TYPE_MAX] = {
[PATH_EXISTS] = "PathExists",
+ [PATH_EXISTS_GLOB] = "PathExistsGlob",
[PATH_CHANGED] = "PathChanged",
[PATH_DIRECTORY_NOT_EMPTY] = "DirectoryNotEmpty"
};
diff --git a/src/path.h b/src/path.h
index 8ba0ce6..116fc63 100644
--- a/src/path.h
+++ b/src/path.h
@@ -38,6 +38,7 @@ typedef enum PathState {
typedef enum PathType {
PATH_EXISTS,
+ PATH_EXISTS_GLOB,
PATH_DIRECTORY_NOT_EMPTY,
PATH_CHANGED,
_PATH_TYPE_MAX,
diff --git a/src/util.c b/src/util.c
index 344b869..356b4f9 100644
--- a/src/util.c
+++ b/src/util.c
@@ -53,6 +53,7 @@
#include <sys/capability.h>
#include <sys/time.h>
#include <linux/rtc.h>
+#include <glob.h>
#include "macro.h"
#include "util.h"
@@ -5238,6 +5239,30 @@ int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **h
return 0;
}
+int glob_exists(const char *path) {
+ glob_t g;
+ int r, k;
+
+ assert(path);
+
+ zero(g);
+ errno = 0;
+ k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
+
+ if (k == GLOB_NOMATCH)
+ r = 0;
+ else if (k == GLOB_NOSPACE)
+ r = -ENOMEM;
+ else if (k == 0)
+ r = !strv_isempty(g.gl_pathv);
+ else
+ r = errno ? -errno : -EIO;
+
+ globfree(&g);
+
+ return r;
+}
+
static const char *const ioprio_class_table[] = {
[IOPRIO_CLASS_NONE] = "none",
[IOPRIO_CLASS_RT] = "realtime",
diff --git a/src/util.h b/src/util.h
index 411efae..b8bbd23 100644
--- a/src/util.h
+++ b/src/util.h
@@ -447,6 +447,8 @@ int socket_from_display(const char *display, char **path);
int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **home);
+int glob_exists(const char *path);
+
#define NULSTR_FOREACH(i, l) \
for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1)
commit 31a5f880cf7a742e63a81bacef681939ee4e6616
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Jul 7 01:18:10 2011 +0200
update TODO
diff --git a/TODO b/TODO
index a5225d5..721e827 100644
--- a/TODO
+++ b/TODO
@@ -14,16 +14,13 @@ F15 External:
* bluetooth should be possible to disable (PENDING)
-* get writev() /dev/kmsg support into the F15 kernel
- http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=7e5b58bcbcb3d7518389c1d82fb6e926f5a9f72c
-
* make anaconda write timeout=0 for encrypted devices
* fix broken Sockets=syslog-ng.socket packaging
Features:
-* optionally support --if-listed in systemctl enable to enable only services listed in some filed
+* support presets
* wildcard support for .path units (think CUPS spool directory!)
@@ -52,7 +49,7 @@ Features:
* figure out a standard place to configure timezone name, inform myllynen at redhat.com
-* add dbus call to convert snapshot into target
+* add dbus call to convert snapshot into target, and a dbus call to generate target from current state
* detect LXC with $container=lxc
@@ -68,6 +65,19 @@ Features:
* support notifications for services being enabled/disabled
+* show enablement status in systemctl status
+
+* consider services with any kind of link in /etc/systemd/system enabled
+
+* teach systemctl to enable unit files in arbitrary directories
+
+* In systemctl make sure both is-enabled and is-active print a string, or neither.
+
+* Implement:
+ systemctl mask <unit>
+ systemctl unmask <unit>
+ Also support --temp to make this temporary by placing mask links in /run.
+
* add support for /bin/mount -s
* GC unreferenced jobs (such as .device jobs)
@@ -76,33 +86,20 @@ Features:
controllers together in order to guarantee atomic creation/addition
of cgroups
-* don't enter "exited" mode for sysv services with pid file
-
* avoid DefaultStandardOutput=syslog to have any effect on StandardInput=socket services
* cgroup_notify_empty(): recursively check groups up the tree, too
* fix alsa mixer restore to not print error when no config is stored
-* show enablement status in systemctl status
-
-* support SYSTEMD_PAGER taking precedence over PAGER
-
* fix upstart reboot compat call
-* In systemctl make sure both is-enabled and is-active print a string, or neither.
-
-* teach systemctl to enable unit files in arbitrary directories
-
* when failing to start a service due to ratelimiting, try again later, if restart=always is set
* write blog stories about:
- enabling dbus services
- status update
- /etc/sysconfig and /etc/default
- - how to write socket activated services
-
-* maybe add tiny dbus services similar to hostnamed for locale and wallclock/timezone?
* allow port=0 in .socket units
@@ -166,24 +163,14 @@ Features:
* Support --test based on current system state
-* consider services with any kind of link in /etc/systemd/system enabled
-
* show failure error string in "systemctl status"
* make sure timeouts are applied to Type=oneshot services.
-* Implement:
- systemctl mask <unit>
- systemctl unmask <unit>
- Also support --temp to make this temporary by placing mask links in /run.
-
* detect LXC environment
* investigate whether the gnome pty helper should be moved into systemd, to provide cgroup support.
-* Maybe store in unit files whether a service should be enabled by default on package installation
- (belongs into a distro pattern though, not in an upstream package's service file)
-
* perhaps add "systemctl reenable" as combination of "systemctl disable" and "systemctl enable"
* need a way to apply mount options of api vfs from systemd unit files
More information about the systemd-commits
mailing list