[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