Accepting request 822481 from Virtualization

- Remove dependency to network-online.target now that gethostname
  is used in kvp_daemon (bsc#1174443, bsc#1174444)
- Reopen the devices if read() or write() returns errors (9fc3c01a)
- Use either python2 or python3 for lsvmbus (bsc#1093910)
- Remove sysv init scripts

- Enable build on aarch64

OBS-URL: https://build.opensuse.org/request/show/822481
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/hyper-v?expand=0&rev=42
This commit is contained in:
Dominique Leuenberger 2020-07-29 15:14:13 +00:00 committed by Git OBS Bridge
commit 7b0f1a5b9c
8 changed files with 120 additions and 356 deletions

View File

@ -1,3 +1,17 @@
-------------------------------------------------------------------
Wed Jul 22 12:12:12 UTC 2020 - ohering@suse.de
- Remove dependency to network-online.target now that gethostname
is used in kvp_daemon (bsc#1174443, bsc#1174444)
- Reopen the devices if read() or write() returns errors (9fc3c01a)
- Use either python2 or python3 for lsvmbus (bsc#1093910)
- Remove sysv init scripts
-------------------------------------------------------------------
Wed Jul 22 09:12:44 UTC 2020 - Guillaume GARDET <guillaume.gardet@opensuse.org>
- Enable build on aarch64
-------------------------------------------------------------------
Thu Feb 20 16:16:16 UTC 2020 - ohering@suse.de

View File

@ -1,82 +0,0 @@
#!/bin/sh
#
# LSB compatible service control script; see http://www.linuxbase.org/spec/
#
### BEGIN INIT INFO
# Provides: hv_fcopy_daemon
# Required-Start: $null
# Should-Start: $syslog $remote_fs $time
# Required-Stop: $null
# Should-Stop: $syslog $remote_fs $time
# Default-Start: 3 5
# Default-Stop: 0 1 2 6
# Short-Description: hv_fcopy_daemon receives files from the host
# Description: Start hv_fcopy_daemon to allow the host to copy files into this guest
### END INIT INFO
# Check for missing binaries (stale symlinks should not happen)
# Note: Special treatment of stop for LSB conformance
HV_FCOPY_BIN=/usr/sbin/hv_fcopy_daemon
test -x $HV_FCOPY_BIN || { echo "$HV_FCOPY_BIN not installed";
if [ "$1" = "stop" ]; then exit 0;
else exit 5; fi; }
. /etc/rc.status
# Reset status of this service
rc_reset
case "$1" in
start)
echo -n "Starting Hyper-V FCOPY daemon "
env PATH=/usr/lib/hyper-v/bin:$PATH \
startproc $HV_FCOPY_BIN
rc_status -v
;;
stop)
echo -n "Shutting down Hyper-V FCOPY daemon "
killproc -TERM $HV_FCOPY_BIN
rc_status -v
;;
try-restart|condrestart)
if test "$1" = "condrestart"; then
echo "${attn} Use try-restart ${done}(LSB)${attn} rather than condrestart ${warn}(RH)${norm}"
fi
$0 status
if test $? = 0; then
$0 restart
else
rc_reset # Not running is not a failure.
fi
# Remember status and be quiet
rc_status
;;
restart)
## Stop the service and regardless of whether it was
## running or not, start it again.
$0 stop
$0 start
# Remember status and be quiet
rc_status
;;
force-reload)
echo -n "Reload service Hyper-V FCOPY daemon "
$0 try-restart
rc_status
;;
reload)
rc_failed 3
rc_status -v
;;
status)
echo -n "Checking for service Hyper-V FCOPY daemon "
checkproc $HV_FCOPY_BIN
rc_status -v
;;
*)
echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload}"
exit 1
;;
esac
rc_exit

View File

@ -1,101 +0,0 @@
#!/bin/sh
#
# LSB compatible service control script; see http://www.linuxbase.org/spec/
#
### BEGIN INIT INFO
# Provides: hv_kvp_daemon
# Required-Start: $null
# Should-Start: $syslog $remote_fs $time
# Required-Stop: $null
# Should-Stop: $syslog $remote_fs $time
# Default-Start: 3 5
# Default-Stop: 0 1 2 6
# Short-Description: hv_kvp_daemon provides info to the host
# Description: Start hv_kvp_daemon to allow the host to query this guest
### END INIT INFO
# Check for missing binaries (stale symlinks should not happen)
# Note: Special treatment of stop for LSB conformance
HV_KVP_BIN=/usr/sbin/hv_kvp_daemon
test -x $HV_KVP_BIN || { echo "$HV_KVP_BIN not installed";
if [ "$1" = "stop" ]; then exit 0;
else exit 5; fi; }
. /etc/rc.status
# Reset status of this service
rc_reset
case "$1" in
start)
echo -n "Starting Hyper-V KVP daemon "
# The service can not be restarted
# IF the currently running kernel is too old, the new daemon is started
# anyway. Due to a flaw in the old kernel-user protocol the kernel
# will flood /var/log/messages with messages like:
# "hv_utils: KVP: user-mode registering done."
# This is also caused by old hyper-v.rpms which have a restart command
# in their post install script. Catch those old kernels and avoid the
# flood, which will easily fill the root partition during an upgrade.
case "`uname -r`" in
2.*) rc_failed 3 ;;
3.0.13-*) rc_failed 3 ;;
3.0.26-*) rc_failed 3 ;;
3.0.31-*) rc_failed 3 ;;
3.0.34-*) rc_failed 3 ;;
3.0.38-*) rc_failed 3 ;;
3.0.42-*) rc_failed 3 ;;
*)
env PATH=/usr/lib/hyper-v/bin:$PATH \
startproc $HV_KVP_BIN
;;
esac
rc_status -v
;;
stop)
echo -n "Shutting down Hyper-V KVP daemon "
killproc -TERM $HV_KVP_BIN
rc_status -v
;;
try-restart|condrestart)
if test "$1" = "condrestart"; then
echo "${attn} Use try-restart ${done}(LSB)${attn} rather than condrestart ${warn}(RH)${norm}"
fi
$0 status
if test $? = 0; then
$0 restart
else
rc_reset # Not running is not a failure.
fi
# Remember status and be quiet
rc_status
;;
restart)
## Stop the service and regardless of whether it was
## running or not, start it again.
$0 stop
$0 start
# Remember status and be quiet
rc_status
;;
force-reload)
echo -n "Reload service Hyper-V KVP daemon "
$0 try-restart
rc_status
;;
reload)
rc_failed 3
rc_status -v
;;
status)
echo -n "Checking for service Hyper-V KVP daemon "
checkproc $HV_KVP_BIN
rc_status -v
;;
*)
echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload}"
exit 1
;;
esac
rc_exit

View File

@ -1,82 +0,0 @@
#!/bin/sh
#
# LSB compatible service control script; see http://www.linuxbase.org/spec/
#
### BEGIN INIT INFO
# Provides: hv_vss_daemon
# Required-Start: $null
# Should-Start: $syslog $remote_fs $time
# Required-Stop: $null
# Should-Stop: $syslog $remote_fs $time
# Default-Start: 3 5
# Default-Stop: 0 1 2 6
# Short-Description: hv_vss_daemon assists with host initiated backup
# Description: Start hv_vss_daemon to allow the host to snapshot this guest
### END INIT INFO
# Check for missing binaries (stale symlinks should not happen)
# Note: Special treatment of stop for LSB conformance
HV_VSS_BIN=/usr/sbin/hv_vss_daemon
test -x $HV_VSS_BIN || { echo "$HV_VSS_BIN not installed";
if [ "$1" = "stop" ]; then exit 0;
else exit 5; fi; }
. /etc/rc.status
# Reset status of this service
rc_reset
case "$1" in
start)
echo -n "Starting Hyper-V VSS daemon "
env PATH=/usr/lib/hyper-v/bin:$PATH \
startproc $HV_VSS_BIN
rc_status -v
;;
stop)
echo -n "Shutting down Hyper-V VSS daemon "
killproc -TERM $HV_VSS_BIN
rc_status -v
;;
try-restart|condrestart)
if test "$1" = "condrestart"; then
echo "${attn} Use try-restart ${done}(LSB)${attn} rather than condrestart ${warn}(RH)${norm}"
fi
$0 status
if test $? = 0; then
$0 restart
else
rc_reset # Not running is not a failure.
fi
# Remember status and be quiet
rc_status
;;
restart)
## Stop the service and regardless of whether it was
## running or not, start it again.
$0 stop
$0 start
# Remember status and be quiet
rc_status
;;
force-reload)
echo -n "Reload service Hyper-V VSS daemon "
$0 try-restart
rc_status
;;
reload)
rc_failed 3
rc_status -v
;;
status)
echo -n "Checking for service Hyper-V VSS daemon "
checkproc $HV_VSS_BIN
rc_status -v
;;
*)
echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload}"
exit 1
;;
esac
rc_exit

View File

@ -22,20 +22,9 @@
%define helper_dir /usr/lib/%{name}
Name: hyper-v
ExclusiveArch: %ix86 x86_64
# systemd for post 13.1 releases
%if 0%{?suse_version} > 1310
%define use_systemd 1
%else
%define use_systemd 0
%endif
%if %{use_systemd}
ExclusiveArch: %ix86 x86_64 aarch64
%{?systemd_requires}
BuildRequires: pkgconfig(systemd)
%else
PreReq: %insserv_prereq
Requires(pre): coreutils
%endif
# Due to usage of char device instead of netlink
Conflicts: kernel < 4.2
Summary: Microsoft Hyper-V tools
@ -45,18 +34,15 @@ Supplements: modalias(dmi:*svnMicrosoftCorporation*pnVirtualMachine*rnVirtual
Supplements: modalias(pci:v00001414d00005353sv*sd*bc*sc*i*)
Url: http://www.kernel.org
# Arbitrary version number
Version: 7
Version: 8
Release: 0
Source0: hyper-v.lsvmbus.py
Source5: hyper-v.kvptest.ps1.txt
Source7: hyper-v.compare-with-upstream.sh
Source9: hyper-v.include.linux.hyperv.h
Source10: hyper-v.tools.hv.hv_kvp_daemon.c
Source11: hyper-v.init.sh
Source12: hyper-v.tools.hv.hv_vss_daemon.c
Source13: hyper-v.init.vss.sh
Source14: hyper-v.tools.hv.hv_fcopy_daemon.c
Source15: hyper-v.init.fcopy.sh
Source20: hyper-v.tools.hv.hv_get_dhcp_info.sh
Source21: hyper-v.tools.hv.hv_get_dns_info.sh
Source22: hyper-v.tools.hv.hv_set_ifconfig.sh
@ -72,7 +58,7 @@ cp -avL %{S:5} kvptest.ps1.txt
cp -vL %{S:9} %{hv_kvp_daemon}.h
cp -vL %{S:10} .
cp -vL %{S:12} %{hv_vss_daemon}.c
cp -vL %{S:14} %{hv_fcopy_daemon}.c
cp -vL %{S:14} %{hv_fcopy_daemon}.c
%patch0 -p1
mv `basename %{S:10}` %{hv_kvp_daemon}.c
@ -115,23 +101,28 @@ gcc \
-o %{hv_fcopy_daemon}
%install
%if %{use_systemd}
# It is not a callable app anyway, so move it out of the way
bindir=%{helper_dir}/bin
%else
bindir=%{_sbindir}
%endif
mkdir -p $RPM_BUILD_ROOT${bindir}
mkdir -p $RPM_BUILD_ROOT%{_sbindir}
mkdir -p $RPM_BUILD_ROOT%{helper_dir}/bin
install -m755 %{hv_kvp_daemon} $RPM_BUILD_ROOT${bindir}
install -m755 %{hv_vss_daemon} $RPM_BUILD_ROOT${bindir}
install -m755 %{hv_fcopy_daemon} $RPM_BUILD_ROOT${bindir}
install -D -m755 %{S:0} $RPM_BUILD_ROOT%{_sbindir}/lsvmbus
sed '
1 {
%if 0%{?suse_version} > 1315
s@^.*@#!%{_bindir}/python3@
%else
s@^.*@#!%{_bindir}/python2@
%endif
}
' %{S:0} > $RPM_BUILD_ROOT%{_sbindir}/lsvmbus
chmod 0755 $RPM_BUILD_ROOT%{_sbindir}/lsvmbus
cp -avL %{S:20} $RPM_BUILD_ROOT%{helper_dir}/bin/hv_get_dhcp_info
cp -avL %{S:21} $RPM_BUILD_ROOT%{helper_dir}/bin/hv_get_dns_info
cp -avL %{S:22} $RPM_BUILD_ROOT%{helper_dir}/bin/hv_set_ifconfig
chmod 755 $RPM_BUILD_ROOT%{helper_dir}/bin/*
%if %{use_systemd}
d=$RPM_BUILD_ROOT%{_unitdir}
mkdir -vp ${d}
#
@ -139,9 +130,7 @@ tee ${d}/%{hv_kvp_daemon}.service <<EOF
# started via %{_udevrulesdir}/%{hv_kvp_daemon}.rules
[Unit]
Description=Hyper-V KVP Daemon
# During startup the current hostname is cached, so start very late
Requires=network-online.target
After=network-online.target
After=local-fs.target
ConditionVirtualization=microsoft
[Service]
@ -228,25 +217,12 @@ fi
EOF
chmod 755 $RPM_BUILD_ROOT${bindir}/${helper}
#
%else
mkdir -p $RPM_BUILD_ROOT/etc/init.d
install -m755 %{S:11} $RPM_BUILD_ROOT/etc/init.d/%{hv_kvp_daemon}
ln -sfvbn ../../etc/init.d/%{hv_kvp_daemon} $RPM_BUILD_ROOT${bindir}/rc%{hv_kvp_daemon}
install -m755 %{S:13} $RPM_BUILD_ROOT/etc/init.d/%{hv_vss_daemon}
ln -sfvbn ../../etc/init.d/%{hv_vss_daemon} $RPM_BUILD_ROOT${bindir}/rc%{hv_vss_daemon}
install -m755 %{S:15} $RPM_BUILD_ROOT/etc/init.d/%{hv_fcopy_daemon}
ln -sfvbn ../../etc/init.d/%{hv_fcopy_daemon} $RPM_BUILD_ROOT${bindir}/rc%{hv_fcopy_daemon}
%endif
%files
%doc kvptest.ps1.txt
%if %{use_systemd}
%{_unitdir}
%dir /usr/lib/udev
%{_udevrulesdir}
%else
/etc/init.d/*
%endif
%{_sbindir}/*
%{helper_dir}
@ -269,9 +245,7 @@ then
fi
rmdir -v /var/opt/hyperv || :
fi
%if %{use_systemd}
: nothing to do in case of systemd
%endif
%post
board_vendor=
@ -290,33 +264,14 @@ then
fi
if test "${board_vendor}" = "Microsoft Corporation" -a "${product_name}" = "Virtual Machine"
then
%if %{use_systemd}
: nothing to do in case of systemd
%else
echo "Enabling %{hv_kvp_daemon} on '${product_name}' from '${board_vendor}'"
%{insserv_force_if_yast %{hv_kvp_daemon}}
echo "Enabling %{hv_vss_daemon} on '${product_name}' from '${board_vendor}'"
%{insserv_force_if_yast %{hv_vss_daemon}}
echo "Enabling %{hv_fcopy_daemon} on '${product_name}' from '${board_vendor}'"
%{insserv_force_if_yast %{hv_fcopy_daemon}}
%endif
fi
%preun
%if %{use_systemd}
: nothing to do in case of systemd
%else
%stop_on_removal %{hv_kvp_daemon}
%stop_on_removal %{hv_vss_daemon}
%stop_on_removal %{hv_fcopy_daemon}
%endif
%postun
# no restart on update because the daemon can not be restarted
%if %{use_systemd}
: nothing to do in case of systemd
%else
%insserv_cleanup
%endif
%changelog

View File

@ -80,6 +80,8 @@ static int hv_start_fcopy(struct hv_start_fcopy *smsg)
error = 0;
done:
if (error)
target_fname[0] = '\0';
return error;
}
@ -108,15 +110,29 @@ static int hv_copy_data(struct hv_do_fcopy *cpmsg)
return ret;
}
/*
* Reset target_fname to "" in the two below functions for hibernation: if
* the fcopy operation is aborted by hibernation, the daemon should remove the
* partially-copied file; to achieve this, the hv_utils driver always fakes a
* CANCEL_FCOPY message upon suspend, and later when the VM resumes back,
* the daemon calls hv_copy_cancel() to remove the file; if a file is copied
* successfully before suspend, hv_copy_finished() must reset target_fname to
* avoid that the file can be incorrectly removed upon resume, since the faked
* CANCEL_FCOPY message is spurious in this case.
*/
static int hv_copy_finished(void)
{
close(target_fd);
target_fname[0] = '\0';
return 0;
}
static int hv_copy_cancel(void)
{
close(target_fd);
unlink(target_fname);
if (strlen(target_fname) > 0) {
unlink(target_fname);
target_fname[0] = '\0';
}
return 0;
}
@ -131,7 +147,7 @@ void print_usage(char *argv[])
int main(int argc, char *argv[])
{
int fcopy_fd;
int fcopy_fd = -1;
int error;
int daemonize = 1, long_index = 0, opt;
int version = FCOPY_CURRENT_VERSION;
@ -141,7 +157,7 @@ int main(int argc, char *argv[])
struct hv_do_fcopy copy;
__u32 kernel_modver;
} buffer = { };
int in_handshake = 1;
int in_handshake;
static struct option long_options[] = {
{"help", no_argument, 0, 'h' },
@ -170,6 +186,12 @@ int main(int argc, char *argv[])
openlog("HV_FCOPY", 0, LOG_USER);
syslog(LOG_INFO, "starting; pid is:%d", getpid());
reopen_fcopy_fd:
if (fcopy_fd != -1)
close(fcopy_fd);
/* Remove any possible partially-copied file on error */
hv_copy_cancel();
in_handshake = 1;
fcopy_fd = open("/dev/vmbus/hv_fcopy", O_RDWR);
if (fcopy_fd < 0) {
@ -196,7 +218,7 @@ int main(int argc, char *argv[])
len = pread(fcopy_fd, &buffer, sizeof(buffer), 0);
if (len < 0) {
syslog(LOG_ERR, "pread failed: %s", strerror(errno));
exit(EXIT_FAILURE);
goto reopen_fcopy_fd;
}
if (in_handshake) {
@ -231,9 +253,14 @@ int main(int argc, char *argv[])
}
/*
* pwrite() may return an error due to the faked CANCEL_FCOPY
* message upon hibernation. Ignore the error by resetting the
* dev file, i.e. closing and re-opening it.
*/
if (pwrite(fcopy_fd, &error, sizeof(int), 0) != sizeof(int)) {
syslog(LOG_ERR, "pwrite failed: %s", strerror(errno));
exit(EXIT_FAILURE);
goto reopen_fcopy_fd;
}
}
}

View File

@ -76,7 +76,7 @@ enum {
DNS
};
static int in_hand_shake = 1;
static int in_hand_shake;
static char *os_name = "";
static char *os_major = "";
@ -1361,7 +1361,7 @@ void print_usage(char *argv[])
int main(int argc, char *argv[])
{
int kvp_fd, len;
int kvp_fd = -1, len;
int error;
struct pollfd pfd;
char *p;
@ -1401,14 +1401,6 @@ int main(int argc, char *argv[])
openlog("KVP", 0, LOG_USER);
syslog(LOG_INFO, "KVP starting; pid is:%d", getpid());
kvp_fd = open("/dev/vmbus/hv_kvp", O_RDWR | O_CLOEXEC);
if (kvp_fd < 0) {
syslog(LOG_ERR, "open /dev/vmbus/hv_kvp failed; error: %d %s",
errno, strerror(errno));
exit(EXIT_FAILURE);
}
/*
* Retrieve OS release information.
*/
@ -1424,6 +1416,18 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
reopen_kvp_fd:
if (kvp_fd != -1)
close(kvp_fd);
in_hand_shake = 1;
kvp_fd = open("/dev/vmbus/hv_kvp", O_RDWR | O_CLOEXEC);
if (kvp_fd < 0) {
syslog(LOG_ERR, "open /dev/vmbus/hv_kvp failed; error: %d %s",
errno, strerror(errno));
exit(EXIT_FAILURE);
}
/*
* Register ourselves with the kernel.
*/
@ -1457,9 +1461,7 @@ int main(int argc, char *argv[])
if (len != sizeof(struct hv_kvp_msg)) {
syslog(LOG_ERR, "read failed; error:%d %s",
errno, strerror(errno));
close(kvp_fd);
return EXIT_FAILURE;
goto reopen_kvp_fd;
}
/*
@ -1618,13 +1620,17 @@ int main(int argc, char *argv[])
break;
}
/* Send the value back to the kernel. */
/*
* Send the value back to the kernel. Note: the write() may
* return an error due to hibernation; we can ignore the error
* by resetting the dev file, i.e. closing and re-opening it.
*/
kvp_done:
len = write(kvp_fd, hv_msg, sizeof(struct hv_kvp_msg));
if (len != sizeof(struct hv_kvp_msg)) {
syslog(LOG_ERR, "write failed; error: %d %s", errno,
strerror(errno));
exit(EXIT_FAILURE);
goto reopen_kvp_fd;
}
}

View File

@ -28,6 +28,8 @@
#include <stdbool.h>
#include <dirent.h>
static bool fs_frozen;
/* Don't use syslog() in the function since that can cause write to disk */
static int vss_do_freeze(char *dir, unsigned int cmd)
{
@ -155,18 +157,27 @@ static int vss_operate(int operation)
continue;
}
error |= vss_do_freeze(ent->mnt_dir, cmd);
if (error && operation == VSS_OP_FREEZE)
goto err;
if (operation == VSS_OP_FREEZE) {
if (error)
goto err;
fs_frozen = true;
}
}
endmntent(mounts);
if (root_seen) {
error |= vss_do_freeze("/", cmd);
if (error && operation == VSS_OP_FREEZE)
goto err;
if (operation == VSS_OP_FREEZE) {
if (error)
goto err;
fs_frozen = true;
}
}
if (operation == VSS_OP_THAW && !error)
fs_frozen = false;
goto out;
err:
save_errno = errno;
@ -175,6 +186,7 @@ err:
endmntent(mounts);
}
vss_operate(VSS_OP_THAW);
fs_frozen = false;
/* Call syslog after we thaw all filesystems */
if (ent)
syslog(LOG_ERR, "FREEZE of %s failed; error:%d %s",
@ -196,13 +208,13 @@ void print_usage(char *argv[])
int main(int argc, char *argv[])
{
int vss_fd, len;
int vss_fd = -1, len;
int error;
struct pollfd pfd;
int op;
struct hv_vss_msg vss_msg[1];
int daemonize = 1, long_index = 0, opt;
int in_handshake = 1;
int in_handshake;
__u32 kernel_modver;
static struct option long_options[] = {
@ -232,6 +244,18 @@ int main(int argc, char *argv[])
openlog("Hyper-V VSS", 0, LOG_USER);
syslog(LOG_INFO, "VSS starting; pid is:%d", getpid());
reopen_vss_fd:
if (vss_fd != -1)
close(vss_fd);
if (fs_frozen) {
if (vss_operate(VSS_OP_THAW) || fs_frozen) {
syslog(LOG_ERR, "failed to thaw file system: err=%d",
errno);
exit(EXIT_FAILURE);
}
}
in_handshake = 1;
vss_fd = open("/dev/vmbus/hv_vss", O_RDWR);
if (vss_fd < 0) {
syslog(LOG_ERR, "open /dev/vmbus/hv_vss failed; error: %d %s",
@ -284,8 +308,7 @@ int main(int argc, char *argv[])
if (len != sizeof(struct hv_vss_msg)) {
syslog(LOG_ERR, "read failed; error:%d %s",
errno, strerror(errno));
close(vss_fd);
return EXIT_FAILURE;
goto reopen_vss_fd;
}
op = vss_msg->vss_hdr.operation;
@ -312,14 +335,18 @@ int main(int argc, char *argv[])
default:
syslog(LOG_ERR, "Illegal op:%d\n", op);
}
/*
* The write() may return an error due to the faked VSS_OP_THAW
* message upon hibernation. Ignore the error by resetting the
* dev file, i.e. closing and re-opening it.
*/
vss_msg->error = error;
len = write(vss_fd, vss_msg, sizeof(struct hv_vss_msg));
if (len != sizeof(struct hv_vss_msg)) {
syslog(LOG_ERR, "write failed; error: %d %s", errno,
strerror(errno));
if (op == VSS_OP_FREEZE)
vss_operate(VSS_OP_THAW);
goto reopen_vss_fd;
}
}