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)