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 - ohering@suse.de + +- 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: opensuse-commit+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-commit+help@opensuse.org