install+SELinux: reduce a 12x performance hit to ~1.5x
authorJim Meyering <meyering@redhat.com>
Sat, 10 Nov 2007 16:31:31 +0000 (17:31 +0100)
committerJim Meyering <meyering@redhat.com>
Sat, 10 Nov 2007 17:41:14 +0000 (18:41 +0100)
* src/install.c (setdefaultfilecon): Call matchpathcon_init_prefix,
to mitigate what would otherwise be a large performance hit due to
the use of matchpathcon.
Dan Walsh suggested the use of matchpathcon_init_prefix.
* gl/lib/se-selinux.in.h (matchpathcon_init_prefix): Define.

Signed-off-by: Jim Meyering <meyering@redhat.com>
ChangeLog
gl/lib/se-selinux.in.h
src/install.c

index 996e1dd61ee94f886b6d6e6acaba8252a4b600bd..529c7701103bb6b1687a14387ee45f20de91887d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2007-11-09  Jim Meyering  <meyering@redhat.com>
+
+       install+SELinux: reduce a 12x performance hit to ~1.5x
+       * src/install.c (setdefaultfilecon): Call matchpathcon_init_prefix,
+       to mitigate what would otherwise be a large performance hit due to
+       the use of matchpathcon.
+       Dan Walsh suggested the use of matchpathcon_init_prefix.
+       * gl/lib/se-selinux.in.h (matchpathcon_init_prefix): Define.
+
 2007-11-08  Jim Meyering  <meyering@redhat.com>
 
        Adapt to gnulib's s/jm_/gl_/ cache variable renaming.
index 7bfe4c5ff7aba9343158319fed3b1f9025525680..7be1e702a7c874d97b7eb0cf5ff6996bad10e80a 100644 (file)
@@ -51,4 +51,7 @@ static inline int security_compute_create (security_context_t scon,
                                           security_class_t tclass,
                                           security_context_t *newcon)
   { errno = ENOTSUP; return -1; }
+static inline int matchpathcon_init_prefix (char const *path,
+                                           char const *prefix)
+  { errno = ENOTSUP; return -1; }
 #endif
index 34f61ffba38413212b2e1572531a7d90ece2dde8..216715f5ce30947bf7709fc974f52f1109af98b0 100644 (file)
@@ -213,6 +213,38 @@ setdefaultfilecon (char const *file)
   if (lstat (file, &st) != 0)
     return;
 
+  if (IS_ABSOLUTE_FILE_NAME (file))
+    {
+      /* Calling matchpathcon_init_prefix (NULL, "/first_component/")
+        is an optimization to minimize the expense of the following
+        matchpathcon call.  */
+      char const *p0;
+      char const *p = file + 1;
+      while (ISSLASH (*p))
+       ++p;
+
+      /* Record final leading slash, for when FILE starts with two or more.  */
+      p0 = p - 1;
+
+      if (*p)
+       {
+         char *prefix;
+         do
+           {
+             ++p;
+           }
+         while (*p && !ISSLASH (*p));
+
+         prefix = malloc (p - p0 + 2);
+         if (prefix)
+           {
+             stpcpy (stpncpy (prefix, p0, p - p0), "/");
+             matchpathcon_init_prefix (NULL, prefix);
+             free (prefix);
+           }
+       }
+    }
+
   /* If there's an error determining the context, or it has none,
      return to allow default context */
   if ((matchpathcon (file, st.st_mode, &scontext) != 0) ||