From a613819a96eeede9f9702d145e0575d459fdfd7a Mon Sep 17 00:00:00 2001 From: Nick Kralevich Date: Fri, 10 Jan 2014 18:52:25 -0800 Subject: [PATCH] restorecon_recursive("/sys") speed boot time Currently, the restorecon_recursive("/sys") call in init.c takes approx 2 seconds on hammerhead. This change reduces the delay to 1.2 seconds. 1) Avoid double stat call when using nftw (time savings of 0.3 seconds) 2) Avoid the repeated calls to is_selinux_enabled() (time savings of 0.5 seconds) Avoid calling lsetfilecon if the file is already properly labeled. This doesn't speed up the restorecon on /sys, but it should help when handling files on /data. Bug: 11640230 Change-Id: Ie212ce4f4acade208c5676d60c1f03f50e2388a4 --- init/util.c | 47 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/init/util.c b/init/util.c index 9aaa77d47..5efd5bebe 100644 --- a/init/util.c +++ b/init/util.c @@ -524,31 +524,50 @@ int make_dir(const char *path, mode_t mode) return rc; } -int restorecon(const char *pathname) +static int restorecon_sb(const char *pathname, const struct stat *sb) { char *secontext = NULL; - struct stat sb; + char *oldsecontext = NULL; int i; + if (selabel_lookup(sehandle, &secontext, pathname, sb->st_mode) < 0) + return -errno; + + if (lgetfilecon(pathname, &oldsecontext) < 0) { + freecon(secontext); + return -errno; + } + + if (strcmp(oldsecontext, secontext) != 0) { + if (lsetfilecon(pathname, secontext) < 0) { + freecon(oldsecontext); + freecon(secontext); + return -errno; + } + } + freecon(oldsecontext); + freecon(secontext); + return 0; +} + +int restorecon(const char *pathname) +{ + struct stat sb; + if (is_selinux_enabled() <= 0 || !sehandle) return 0; if (lstat(pathname, &sb) < 0) return -errno; - if (selabel_lookup(sehandle, &secontext, pathname, sb.st_mode) < 0) - return -errno; - if (lsetfilecon(pathname, secontext) < 0) { - freecon(secontext); - return -errno; - } - freecon(secontext); - return 0; + + return restorecon_sb(pathname, &sb); } static int nftw_restorecon(const char* filename, const struct stat* statptr, - int fileflags, struct FTW* pftw) + int fileflags __attribute__((unused)), + struct FTW* pftw __attribute__((unused))) { - restorecon(filename); + restorecon_sb(filename, statptr); return 0; } @@ -556,5 +575,9 @@ int restorecon_recursive(const char* pathname) { int fd_limit = 20; int flags = FTW_DEPTH | FTW_MOUNT | FTW_PHYS; + + if (is_selinux_enabled() <= 0 || !sehandle) + return 0; + return nftw(pathname, nftw_restorecon, fd_limit, flags); }