Hello community,

here is the log from the commit of package hyper-v for openSUSE:Factory checked 
in at 2014-10-08 22:13:24
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/hyper-v (Old)
 and      /work/SRC/openSUSE:Factory/.hyper-v.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "hyper-v"

Changes:
--------
--- /work/SRC/openSUSE:Factory/hyper-v/hyper-v.changes  2014-07-13 
14:05:46.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.hyper-v.new/hyper-v.changes     2014-10-08 
22:13:27.000000000 +0200
@@ -1,0 +2,6 @@
+Tue Sep 30 15:41:02 UTC 2014 - [email protected]
+
+- vssdaemon: ignore the EBUSY on multiple freezing the same
+  partition (bnc#899204)
+
+-------------------------------------------------------------------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ hyper-v.tools.hv.hv_vss_daemon.c ++++++
--- /var/tmp/diff_new_pack.j9JF4P/_old  2014-10-08 22:13:28.000000000 +0200
+++ /var/tmp/diff_new_pack.j9JF4P/_new  2014-10-08 22:13:28.000000000 +0200
@@ -45,21 +45,39 @@
 #endif
 
 
-static int vss_do_freeze(char *dir, unsigned int cmd, char *fs_op)
+/* Don't use syslog() in the function since that can cause write to disk */
+static int vss_do_freeze(char *dir, unsigned int cmd)
 {
        int ret, fd = open(dir, O_RDONLY);
 
        if (fd < 0)
                return 1;
+
        ret = ioctl(fd, cmd, 0);
-       syslog(LOG_INFO, "VSS: %s of %s: %s\n", fs_op, dir, strerror(errno));
+
+       /*
+        * If a partition is mounted more than once, only the first
+        * FREEZE/THAW can succeed and the later ones will get
+        * EBUSY/EINVAL respectively: there could be 2 cases:
+        * 1) a user may mount the same partition to differnt directories
+        *  by mistake or on purpose;
+        * 2) The subvolume of btrfs appears to have the same partition
+        * mounted more than once.
+        */
+       if (ret) {
+               if ((cmd == FIFREEZE && errno == EBUSY) ||
+                   (cmd == FITHAW && errno == EINVAL)) {
+                       close(fd);
+                       return 0;
+               }
+       }
+
        close(fd);
        return !!ret;
 }
 
 static int vss_operate(int operation)
 {
-       char *fs_op;
        char match[] = "/dev/";
        FILE *mounts;
        struct mntent *ent;
@@ -69,11 +87,9 @@
        switch (operation) {
        case VSS_OP_FREEZE:
                cmd = FIFREEZE;
-               fs_op = "freeze";
                break;
        case VSS_OP_THAW:
                cmd = FITHAW;
-               fs_op = "thaw";
                break;
        default:
                return -1;
@@ -94,15 +110,23 @@
                        root_seen = 1;
                        continue;
                }
-               error |= vss_do_freeze(ent->mnt_dir, cmd, fs_op);
+               error |= vss_do_freeze(ent->mnt_dir, cmd);
+               if (error && operation == VSS_OP_FREEZE)
+                       goto err;
        }
        endmntent(mounts);
 
        if (root_seen) {
-               error |= vss_do_freeze("/", cmd, fs_op);
+               error |= vss_do_freeze("/", cmd);
+               if (error && operation == VSS_OP_FREEZE)
+                       goto err;
        }
 
        return error;
+err:
+       endmntent(mounts);
+       vss_operate(VSS_OP_THAW);
+       return error;
 }
 
 static int netlink_send(int fd, struct cn_msg *msg)
@@ -236,8 +260,16 @@
                case VSS_OP_FREEZE:
                case VSS_OP_THAW:
                        error = vss_operate(op);
-                       if (error)
+                       syslog(LOG_INFO, "VSS: op=%s: %s\n",
+                               op == VSS_OP_FREEZE ? "FREEZE" : "THAW",
+                               error ? "failed" : "succeeded");
+
+                       if (error) {
                                error = HV_E_FAIL;
+                               syslog(LOG_ERR, "op=%d failed!", op);
+                               syslog(LOG_ERR, "report it with these files:");
+                               syslog(LOG_ERR, "/etc/fstab and /proc/mounts");
+                       }
                        break;
                default:
                        syslog(LOG_ERR, "Illegal op:%d\n", op);

-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to