From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752496AbeFEUj2 (ORCPT ); Tue, 5 Jun 2018 16:39:28 -0400 Received: from a2nlsmtp01-02.prod.iad2.secureserver.net ([198.71.225.36]:49480 "EHLO a2nlsmtp01-02.prod.iad2.secureserver.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751999AbeFEUjB (ORCPT ); Tue, 5 Jun 2018 16:39:01 -0400 x-originating-ip: 107.180.71.197 From: kys@linuxonhyperv.com To: gregkh@linuxfoundation.org, linux-kernel@vger.kernel.org, devel@linuxdriverproject.org, olaf@aepfle.de, apw@canonical.com, jasowang@redhat.com, sthemmin@microsoft.com, Michael.H.Kelley@microsoft.com, vkuznets@redhat.com Cc: "K . Y . Srinivasan" Subject: [PATCH 8/8] Tools: hv: vss: fix loop device detection Date: Tue, 5 Jun 2018 13:37:56 -0700 Message-Id: <20180605203756.29809-8-kys@linuxonhyperv.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180605203756.29809-1-kys@linuxonhyperv.com> References: <20180605203536.29751-1-kys@linuxonhyperv.com> <20180605203756.29809-1-kys@linuxonhyperv.com> Reply-To: kys@microsoft.com X-CMAE-Envelope: MS4wfBmPPXvR3AC73sWWSmoXjypNo3+5mZlASFGBmTxJXdkYZ46NrqUmluAu0+sbeDEibEfhlF7ezv7JJVuWqRU5QMs1li0vZBLLo8Kj5YZljCjiUM1yiTi0 +Ldd/VwBSuEyx3T0Rf3eUubo6qvqZDUmmCB8IxMyy7JNpQW9LjpKE6S1UWDVIvAIhR96+waG8cGTdEH1rAX3xl3Bz+BrbVR0blVX4cPpB55BBwYWrlXqd2FO OzXs+RdXGLdOOPNGu4k9YR2rVhSv5Q7i0d43qOEYhtluGVkvRPs4/T3p6cf7EalL8ytQQFbRQhZe1M7aNFZrpll3iw90UmcqkKK7La/4Mkpsbovlj9kS/5VN 43VKfb03UJeZRq7rK6jsJDxPsrWNFamSF9MX1YXATZgM7Ad7QgVfiFrD8Z2FZeOHsD7zeiwVZo93JTM3OYRhosoaAUL9VrlznYafLuL9yTtfP4RkB9NBIQql sXc3/6WeSv0iAalfupgDJWzxbEbWljQIqWpSy/ie1UNcReirnjaUPsciMteQCol7dPxjB/M0STOWmJy9 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Vitaly Kuznetsov Commit ea81fdf0981d ("Tools: hv: vss: Skip freezing filesystems backed by loop") added skip for filesystems backed by loop device. However, it seems the detection of such cases is incomplete. It was found that with 'devicemapper' storage driver docker creates the following chain: NAME MAJ:MIN loop0 7:0 ..docker-8:4-8473394-pool 253:0 ..docker-8:4-8473394-eac... 253:1 so when we're looking at the mounted device we see major '253' and not '7'. Solve the issue by walking /sys/dev/block/*/slaves chain and checking if there's a loop device somewhere. Other than that, don't skip mountpoints silently when stat() fails. In case e.g. SELinux is failing stat we don't want to skip freezing everything without letting user know about the failure. Fixes: ea81fdf0981d ("Tools: hv: vss: Skip freezing filesystems backed by loop") Signed-off-by: Vitaly Kuznetsov Signed-off-by: K. Y. Srinivasan --- tools/hv/hv_vss_daemon.c | 65 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 4 deletions(-) diff --git a/tools/hv/hv_vss_daemon.c b/tools/hv/hv_vss_daemon.c index 34031a297f02..b13300172762 100644 --- a/tools/hv/hv_vss_daemon.c +++ b/tools/hv/hv_vss_daemon.c @@ -36,6 +36,8 @@ #include #include #include +#include +#include /* Don't use syslog() in the function since that can cause write to disk */ static int vss_do_freeze(char *dir, unsigned int cmd) @@ -68,6 +70,55 @@ static int vss_do_freeze(char *dir, unsigned int cmd) return !!ret; } +static bool is_dev_loop(const char *blkname) +{ + char *buffer; + DIR *dir; + struct dirent *entry; + bool ret = false; + + buffer = malloc(PATH_MAX); + if (!buffer) { + syslog(LOG_ERR, "Can't allocate memory!"); + exit(1); + } + + snprintf(buffer, PATH_MAX, "%s/loop", blkname); + if (!access(buffer, R_OK | X_OK)) { + ret = true; + goto free_buffer; + } else if (errno != ENOENT) { + syslog(LOG_ERR, "Can't access: %s; error:%d %s!", + buffer, errno, strerror(errno)); + } + + snprintf(buffer, PATH_MAX, "%s/slaves", blkname); + dir = opendir(buffer); + if (!dir) { + if (errno != ENOENT) + syslog(LOG_ERR, "Can't opendir: %s; error:%d %s!", + buffer, errno, strerror(errno)); + goto free_buffer; + } + + while ((entry = readdir(dir)) != NULL) { + if (strcmp(entry->d_name, ".") == 0 || + strcmp(entry->d_name, "..") == 0) + continue; + + snprintf(buffer, PATH_MAX, "%s/slaves/%s", blkname, + entry->d_name); + if (is_dev_loop(buffer)) { + ret = true; + break; + } + } + closedir(dir); +free_buffer: + free(buffer); + return ret; +} + static int vss_operate(int operation) { char match[] = "/dev/"; @@ -75,6 +126,7 @@ static int vss_operate(int operation) struct mntent *ent; struct stat sb; char errdir[1024] = {0}; + char blkdir[23]; /* /sys/dev/block/XXX:XXX */ unsigned int cmd; int error = 0, root_seen = 0, save_errno = 0; @@ -96,10 +148,15 @@ static int vss_operate(int operation) while ((ent = getmntent(mounts))) { if (strncmp(ent->mnt_fsname, match, strlen(match))) continue; - if (stat(ent->mnt_fsname, &sb) == -1) - continue; - if (S_ISBLK(sb.st_mode) && major(sb.st_rdev) == LOOP_MAJOR) - continue; + if (stat(ent->mnt_fsname, &sb)) { + syslog(LOG_ERR, "Can't stat: %s; error:%d %s!", + ent->mnt_fsname, errno, strerror(errno)); + } else { + sprintf(blkdir, "/sys/dev/block/%d:%d", + major(sb.st_rdev), minor(sb.st_rdev)); + if (is_dev_loop(blkdir)) + continue; + } if (hasmntopt(ent, MNTOPT_RO) != NULL) continue; if (strcmp(ent->mnt_type, "vfat") == 0) -- 2.17.1