Accepting request 254607 from Virtualization

Automatic submission by obs-autosubmit

OBS-URL: https://build.opensuse.org/request/show/254607
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/hyper-v?expand=0&rev=25
This commit is contained in:
Stephan Kulow 2014-10-08 20:13:24 +00:00 committed by Git OBS Bridge
commit 4d4e3bc9af
2 changed files with 46 additions and 8 deletions

View File

@ -1,3 +1,9 @@
-------------------------------------------------------------------
Tue Sep 30 15:41:02 UTC 2014 - ohering@suse.de
- vssdaemon: ignore the EBUSY on multiple freezing the same
partition (bnc#899204)
------------------------------------------------------------------- -------------------------------------------------------------------
Tue Jul 1 17:32:30 CEST 2014 - ohering@suse.de Tue Jul 1 17:32:30 CEST 2014 - ohering@suse.de

View File

@ -45,21 +45,39 @@ static struct sockaddr_nl addr;
#endif #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); int ret, fd = open(dir, O_RDONLY);
if (fd < 0) if (fd < 0)
return 1; return 1;
ret = ioctl(fd, cmd, 0); 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); close(fd);
return !!ret; return !!ret;
} }
static int vss_operate(int operation) static int vss_operate(int operation)
{ {
char *fs_op;
char match[] = "/dev/"; char match[] = "/dev/";
FILE *mounts; FILE *mounts;
struct mntent *ent; struct mntent *ent;
@ -69,11 +87,9 @@ static int vss_operate(int operation)
switch (operation) { switch (operation) {
case VSS_OP_FREEZE: case VSS_OP_FREEZE:
cmd = FIFREEZE; cmd = FIFREEZE;
fs_op = "freeze";
break; break;
case VSS_OP_THAW: case VSS_OP_THAW:
cmd = FITHAW; cmd = FITHAW;
fs_op = "thaw";
break; break;
default: default:
return -1; return -1;
@ -94,14 +110,22 @@ static int vss_operate(int operation)
root_seen = 1; root_seen = 1;
continue; 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); endmntent(mounts);
if (root_seen) { 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; return error;
} }
@ -236,8 +260,16 @@ int main(void)
case VSS_OP_FREEZE: case VSS_OP_FREEZE:
case VSS_OP_THAW: case VSS_OP_THAW:
error = vss_operate(op); 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; 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; break;
default: default:
syslog(LOG_ERR, "Illegal op:%d\n", op); syslog(LOG_ERR, "Illegal op:%d\n", op);