|
@@ -36,6 +36,8 @@
|
|
|
#include <linux/hyperv.h>
|
|
|
#include <syslog.h>
|
|
|
#include <getopt.h>
|
|
|
+#include <stdbool.h>
|
|
|
+#include <dirent.h>
|
|
|
|
|
|
/* 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)
|