From 9a3cf18cea4f1b45a07942acee809f67fc8b499d Mon Sep 17 00:00:00 2001 From: "Michael H. Warfield" Date: Fri, 25 Apr 2014 12:06:44 -0400 Subject: [PATCH] Check for symlinks before attempting create. Check for symlinks before attempting create. When attempting to create the compulsory symlinks in /dev, check for the existence of the link using stat first before blindly attempting to create the link. This works around an apparent quirk in the kernel VFS on read-only file systems where the returned error code might be EEXIST or EROFS depending on previous access to the /dev directory and its entries. Reported-by: William Dauchy Signed-off-by: Michael H. Warfield Tested-by: William Dauchy --- src/lxc/conf.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 4052c5f66b..d765f0da5b 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -828,6 +828,7 @@ static int setup_dev_symlinks(const struct lxc_rootfs *rootfs) { char path[MAXPATHLEN]; int ret,i; + struct stat s; for (i = 0; i < sizeof(dev_symlinks) / sizeof(dev_symlinks[0]); i++) { @@ -835,10 +836,24 @@ static int setup_dev_symlinks(const struct lxc_rootfs *rootfs) ret = snprintf(path, sizeof(path), "%s/dev/%s", rootfs->mount, d->name); if (ret < 0 || ret >= MAXPATHLEN) return -1; + + /* + * Stat the path first. If we don't get an error + * accept it as is and don't try to create it + */ + if (!stat(path, &s)) { + continue; + } + ret = symlink(d->oldpath, path); + if (ret && errno != EEXIST) { - SYSERROR("Error creating %s", path); - return -1; + if ( errno == EROFS ) { + WARN("Warning: Read Only file system while creating %s", path); + } else { + SYSERROR("Error creating %s", path); + return -1; + } } } return 0;