- add hv_vss_daemon (fate#314921)
helper to support host initiated backup OBS-URL: https://build.opensuse.org/package/show/Virtualization/hyper-v?expand=0&rev=55
This commit is contained in:
@@ -1,3 +1,9 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Fri Mar 22 17:23:36 CET 2013 - ohering@suse.de
|
||||||
|
|
||||||
|
- add hv_vss_daemon (fate#314921)
|
||||||
|
helper to support host initiated backup
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Fri Mar 22 16:56:57 CET 2013 - ohering@suse.de
|
Fri Mar 22 16:56:57 CET 2013 - ohering@suse.de
|
||||||
|
|
||||||
|
@@ -27,6 +27,63 @@
|
|||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implementation of host controlled snapshot of the guest.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define VSS_OP_REGISTER 128
|
||||||
|
|
||||||
|
enum hv_vss_op {
|
||||||
|
VSS_OP_CREATE = 0,
|
||||||
|
VSS_OP_DELETE,
|
||||||
|
VSS_OP_HOT_BACKUP,
|
||||||
|
VSS_OP_GET_DM_INFO,
|
||||||
|
VSS_OP_BU_COMPLETE,
|
||||||
|
/*
|
||||||
|
* Following operations are only supported with IC version >= 5.0
|
||||||
|
*/
|
||||||
|
VSS_OP_FREEZE, /* Freeze the file systems in the VM */
|
||||||
|
VSS_OP_THAW, /* Unfreeze the file systems */
|
||||||
|
VSS_OP_AUTO_RECOVER,
|
||||||
|
VSS_OP_COUNT /* Number of operations, must be last */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Header for all VSS messages.
|
||||||
|
*/
|
||||||
|
struct hv_vss_hdr {
|
||||||
|
__u8 operation;
|
||||||
|
__u8 reserved[7];
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flag values for the hv_vss_check_feature. Linux supports only
|
||||||
|
* one value.
|
||||||
|
*/
|
||||||
|
#define VSS_HBU_NO_AUTO_RECOVERY 0x00000005
|
||||||
|
|
||||||
|
struct hv_vss_check_feature {
|
||||||
|
__u32 flags;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct hv_vss_check_dm_info {
|
||||||
|
__u32 flags;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct hv_vss_msg {
|
||||||
|
union {
|
||||||
|
struct hv_vss_hdr vss_hdr;
|
||||||
|
int error;
|
||||||
|
};
|
||||||
|
union {
|
||||||
|
struct hv_vss_check_feature vss_cf;
|
||||||
|
struct hv_vss_check_dm_info dm_info;
|
||||||
|
};
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* An implementation of HyperV key value pair (KVP) functionality for Linux.
|
* An implementation of HyperV key value pair (KVP) functionality for Linux.
|
||||||
*
|
*
|
||||||
|
82
hyper-v.init.vss.sh
Normal file
82
hyper-v.init.vss.sh
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
#!/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
|
27
hyper-v.spec
27
hyper-v.spec
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
|
|
||||||
%define hv_kvp_daemon hv_kvp_daemon
|
%define hv_kvp_daemon hv_kvp_daemon
|
||||||
|
%define hv_vss_daemon hv_vss_daemon
|
||||||
|
|
||||||
Name: hyper-v
|
Name: hyper-v
|
||||||
ExclusiveArch: %ix86 x86_64
|
ExclusiveArch: %ix86 x86_64
|
||||||
@@ -34,6 +35,8 @@ Source5: hyper-v.kvptest.ps1.txt
|
|||||||
Source9: hyper-v.include.linux.hyperv.h
|
Source9: hyper-v.include.linux.hyperv.h
|
||||||
Source10: hyper-v.tools.hv.hv_kvp_daemon.c
|
Source10: hyper-v.tools.hv.hv_kvp_daemon.c
|
||||||
Source11: hyper-v.init.sh
|
Source11: hyper-v.init.sh
|
||||||
|
Source12: hyper-v.tools.hv.hv_vss_daemon.c
|
||||||
|
Source13: hyper-v.init.vss.sh
|
||||||
Source20: hyper-v.tools.hv.hv_get_dhcp_info.sh
|
Source20: hyper-v.tools.hv.hv_get_dhcp_info.sh
|
||||||
Source21: hyper-v.tools.hv.hv_get_dns_info.sh
|
Source21: hyper-v.tools.hv.hv_get_dns_info.sh
|
||||||
Source22: hyper-v.tools.hv.hv_set_ifconfig.sh
|
Source22: hyper-v.tools.hv.hv_set_ifconfig.sh
|
||||||
@@ -48,9 +51,11 @@ This package contains the Microsoft Hyper-V tools.
|
|||||||
cp -avL %{S:5} kvptest.ps1.txt
|
cp -avL %{S:5} kvptest.ps1.txt
|
||||||
cp -vL %{S:9} %{hv_kvp_daemon}.h
|
cp -vL %{S:9} %{hv_kvp_daemon}.h
|
||||||
cp -vL %{S:10} %{hv_kvp_daemon}.c
|
cp -vL %{S:10} %{hv_kvp_daemon}.c
|
||||||
|
cp -vL %{S:12} %{hv_vss_daemon}.c
|
||||||
|
|
||||||
%build
|
%build
|
||||||
sed -i~ '/#include <linux.hyperv.h>/d' %{hv_kvp_daemon}.c
|
sed -i~ '/#include <linux.hyperv.h>/d' %{hv_kvp_daemon}.c
|
||||||
|
sed -i~ '/#include <linux.hyperv.h>/d' %{hv_vss_daemon}.c
|
||||||
gcc \
|
gcc \
|
||||||
$RPM_OPT_FLAGS \
|
$RPM_OPT_FLAGS \
|
||||||
-Wno-unused-variable \
|
-Wno-unused-variable \
|
||||||
@@ -62,10 +67,22 @@ gcc \
|
|||||||
-DCN_KVP_IDX=0x9 \
|
-DCN_KVP_IDX=0x9 \
|
||||||
-DCN_KVP_VAL=0x1 \
|
-DCN_KVP_VAL=0x1 \
|
||||||
-o %{hv_kvp_daemon}
|
-o %{hv_kvp_daemon}
|
||||||
|
gcc \
|
||||||
|
$RPM_OPT_FLAGS \
|
||||||
|
-Wno-unused-variable \
|
||||||
|
-Wno-pointer-sign \
|
||||||
|
-D_GNU_SOURCE \
|
||||||
|
-g \
|
||||||
|
%{hv_vss_daemon}.c \
|
||||||
|
-include %{hv_kvp_daemon}.h \
|
||||||
|
-DCN_VSS_IDX=0xa \
|
||||||
|
-DCN_VSS_VAL=0x1 \
|
||||||
|
-o %{hv_vss_daemon}
|
||||||
|
|
||||||
%install
|
%install
|
||||||
mkdir -p $RPM_BUILD_ROOT/usr/sbin
|
mkdir -p $RPM_BUILD_ROOT/usr/sbin
|
||||||
install -m755 %{hv_kvp_daemon} $RPM_BUILD_ROOT/usr/sbin
|
install -m755 %{hv_kvp_daemon} $RPM_BUILD_ROOT/usr/sbin
|
||||||
|
install -m755 %{hv_vss_daemon} $RPM_BUILD_ROOT/usr/sbin
|
||||||
mkdir -p $RPM_BUILD_ROOT/usr/lib/%{name}/bin
|
mkdir -p $RPM_BUILD_ROOT/usr/lib/%{name}/bin
|
||||||
cp -avL %{S:20} $RPM_BUILD_ROOT/usr/lib/%{name}/bin/hv_get_dhcp_info
|
cp -avL %{S:20} $RPM_BUILD_ROOT/usr/lib/%{name}/bin/hv_get_dhcp_info
|
||||||
cp -avL %{S:21} $RPM_BUILD_ROOT/usr/lib/%{name}/bin/hv_get_dns_info
|
cp -avL %{S:21} $RPM_BUILD_ROOT/usr/lib/%{name}/bin/hv_get_dns_info
|
||||||
@@ -74,13 +91,14 @@ chmod 755 $RPM_BUILD_ROOT/usr/lib/%{name}/bin/*
|
|||||||
mkdir -p $RPM_BUILD_ROOT/etc/init.d
|
mkdir -p $RPM_BUILD_ROOT/etc/init.d
|
||||||
install -m755 %{S:11} $RPM_BUILD_ROOT/etc/init.d/%{hv_kvp_daemon}
|
install -m755 %{S:11} $RPM_BUILD_ROOT/etc/init.d/%{hv_kvp_daemon}
|
||||||
ln -sfvbn ../../etc/init.d/%{hv_kvp_daemon} $RPM_BUILD_ROOT/usr/sbin/rc%{hv_kvp_daemon}
|
ln -sfvbn ../../etc/init.d/%{hv_kvp_daemon} $RPM_BUILD_ROOT/usr/sbin/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/usr/sbin/rc%{hv_vss_daemon}
|
||||||
|
|
||||||
%files
|
%files
|
||||||
%defattr (-,root,root)
|
%defattr (-,root,root)
|
||||||
%doc kvptest.ps1.txt
|
%doc kvptest.ps1.txt
|
||||||
/etc/init.d/%{hv_kvp_daemon}
|
/etc/init.d/*
|
||||||
/usr/sbin/rc%{hv_kvp_daemon}
|
/usr/sbin/*
|
||||||
/usr/sbin/%{hv_kvp_daemon}
|
|
||||||
/usr/lib/%{name}
|
/usr/lib/%{name}
|
||||||
|
|
||||||
%pre
|
%pre
|
||||||
@@ -121,10 +139,13 @@ if test "${board_vendor}" = "Microsoft Corporation" -a "${product_name}" = "Virt
|
|||||||
then
|
then
|
||||||
echo "Enabling %{hv_kvp_daemon} on '${product_name}' from '${board_vendor}'"
|
echo "Enabling %{hv_kvp_daemon} on '${product_name}' from '${board_vendor}'"
|
||||||
%{insserv_force_if_yast %{hv_kvp_daemon}}
|
%{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}}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
%preun
|
%preun
|
||||||
%stop_on_removal %{hv_kvp_daemon}
|
%stop_on_removal %{hv_kvp_daemon}
|
||||||
|
%stop_on_removal %{hv_vss_daemon}
|
||||||
|
|
||||||
%postun
|
%postun
|
||||||
# no restart on update because the daemon can not be restarted
|
# no restart on update because the daemon can not be restarted
|
||||||
|
225
hyper-v.tools.hv.hv_vss_daemon.c
Normal file
225
hyper-v.tools.hv.hv_vss_daemon.c
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
/*
|
||||||
|
* An implementation of the host initiated guest snapshot for Hyper-V.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013, Microsoft, Inc.
|
||||||
|
* Author : K. Y. Srinivasan <kys@microsoft.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 as published
|
||||||
|
* by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||||
|
* NON INFRINGEMENT. See the GNU General Public License for more
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/poll.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <linux/connector.h>
|
||||||
|
#include <linux/hyperv.h>
|
||||||
|
#include <linux/netlink.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
|
||||||
|
static char vss_recv_buffer[4096];
|
||||||
|
static char vss_send_buffer[4096];
|
||||||
|
static struct sockaddr_nl addr;
|
||||||
|
|
||||||
|
#ifndef SOL_NETLINK
|
||||||
|
#define SOL_NETLINK 270
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static int vss_operate(int operation)
|
||||||
|
{
|
||||||
|
char *fs_op;
|
||||||
|
char cmd[512];
|
||||||
|
char buf[512];
|
||||||
|
FILE *file;
|
||||||
|
char *p;
|
||||||
|
char *x;
|
||||||
|
int error = -1;
|
||||||
|
|
||||||
|
switch (operation) {
|
||||||
|
case VSS_OP_FREEZE:
|
||||||
|
fs_op = "-f ";
|
||||||
|
break;
|
||||||
|
case VSS_OP_THAW:
|
||||||
|
fs_op = "-u ";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
file = popen("mount | awk '/^\\/dev\\// { print $3}'", "r");
|
||||||
|
if (file == NULL)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
while ((p = fgets(buf, sizeof(buf), file)) != NULL) {
|
||||||
|
x = strchr(p, '\n');
|
||||||
|
*x = '\0';
|
||||||
|
if (!strncmp(p, "/", sizeof("/")))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sprintf(cmd, "%s %s %s", "fsfreeze ", fs_op, p);
|
||||||
|
syslog(LOG_INFO, "VSS cmd is %s\n", cmd);
|
||||||
|
error = system(cmd);
|
||||||
|
}
|
||||||
|
pclose(file);
|
||||||
|
|
||||||
|
sprintf(cmd, "%s %s %s", "fsfreeze ", fs_op, "/");
|
||||||
|
syslog(LOG_INFO, "VSS cmd is %s\n", cmd);
|
||||||
|
error = system(cmd);
|
||||||
|
|
||||||
|
out:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int netlink_send(int fd, struct cn_msg *msg)
|
||||||
|
{
|
||||||
|
struct nlmsghdr *nlh;
|
||||||
|
unsigned int size;
|
||||||
|
struct msghdr message;
|
||||||
|
char buffer[64];
|
||||||
|
struct iovec iov[2];
|
||||||
|
|
||||||
|
size = NLMSG_SPACE(sizeof(struct cn_msg) + msg->len);
|
||||||
|
|
||||||
|
nlh = (struct nlmsghdr *)buffer;
|
||||||
|
nlh->nlmsg_seq = 0;
|
||||||
|
nlh->nlmsg_pid = getpid();
|
||||||
|
nlh->nlmsg_type = NLMSG_DONE;
|
||||||
|
nlh->nlmsg_len = NLMSG_LENGTH(size - sizeof(*nlh));
|
||||||
|
nlh->nlmsg_flags = 0;
|
||||||
|
|
||||||
|
iov[0].iov_base = nlh;
|
||||||
|
iov[0].iov_len = sizeof(*nlh);
|
||||||
|
|
||||||
|
iov[1].iov_base = msg;
|
||||||
|
iov[1].iov_len = size;
|
||||||
|
|
||||||
|
memset(&message, 0, sizeof(message));
|
||||||
|
message.msg_name = &addr;
|
||||||
|
message.msg_namelen = sizeof(addr);
|
||||||
|
message.msg_iov = iov;
|
||||||
|
message.msg_iovlen = 2;
|
||||||
|
|
||||||
|
return sendmsg(fd, &message, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
int fd, len, nl_group;
|
||||||
|
int error;
|
||||||
|
struct cn_msg *message;
|
||||||
|
struct pollfd pfd;
|
||||||
|
struct nlmsghdr *incoming_msg;
|
||||||
|
struct cn_msg *incoming_cn_msg;
|
||||||
|
int op;
|
||||||
|
struct hv_vss_msg *vss_msg;
|
||||||
|
|
||||||
|
if (daemon(1, 0))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
openlog("Hyper-V VSS", 0, LOG_USER);
|
||||||
|
syslog(LOG_INFO, "VSS starting; pid is:%d", getpid());
|
||||||
|
|
||||||
|
fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
|
||||||
|
if (fd < 0) {
|
||||||
|
syslog(LOG_ERR, "netlink socket creation failed; error:%d", fd);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
addr.nl_family = AF_NETLINK;
|
||||||
|
addr.nl_pad = 0;
|
||||||
|
addr.nl_pid = 0;
|
||||||
|
addr.nl_groups = 0;
|
||||||
|
|
||||||
|
|
||||||
|
error = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
|
||||||
|
if (error < 0) {
|
||||||
|
syslog(LOG_ERR, "bind failed; error:%d", error);
|
||||||
|
close(fd);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
nl_group = CN_VSS_IDX;
|
||||||
|
setsockopt(fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &nl_group, sizeof(nl_group));
|
||||||
|
/*
|
||||||
|
* Register ourselves with the kernel.
|
||||||
|
*/
|
||||||
|
message = (struct cn_msg *)vss_send_buffer;
|
||||||
|
message->id.idx = CN_VSS_IDX;
|
||||||
|
message->id.val = CN_VSS_VAL;
|
||||||
|
message->ack = 0;
|
||||||
|
vss_msg = (struct hv_vss_msg *)message->data;
|
||||||
|
vss_msg->vss_hdr.operation = VSS_OP_REGISTER;
|
||||||
|
|
||||||
|
message->len = sizeof(struct hv_vss_msg);
|
||||||
|
|
||||||
|
len = netlink_send(fd, message);
|
||||||
|
if (len < 0) {
|
||||||
|
syslog(LOG_ERR, "netlink_send failed; error:%d", len);
|
||||||
|
close(fd);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
pfd.fd = fd;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
struct sockaddr *addr_p = (struct sockaddr *) &addr;
|
||||||
|
socklen_t addr_l = sizeof(addr);
|
||||||
|
pfd.events = POLLIN;
|
||||||
|
pfd.revents = 0;
|
||||||
|
poll(&pfd, 1, -1);
|
||||||
|
|
||||||
|
len = recvfrom(fd, vss_recv_buffer, sizeof(vss_recv_buffer), 0,
|
||||||
|
addr_p, &addr_l);
|
||||||
|
|
||||||
|
if (len < 0 || addr.nl_pid) {
|
||||||
|
syslog(LOG_ERR, "recvfrom failed; pid:%u error:%d %s",
|
||||||
|
addr.nl_pid, errno, strerror(errno));
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
incoming_msg = (struct nlmsghdr *)vss_recv_buffer;
|
||||||
|
|
||||||
|
if (incoming_msg->nlmsg_type != NLMSG_DONE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
incoming_cn_msg = (struct cn_msg *)NLMSG_DATA(incoming_msg);
|
||||||
|
vss_msg = (struct hv_vss_msg *)incoming_cn_msg->data;
|
||||||
|
op = vss_msg->vss_hdr.operation;
|
||||||
|
error = HV_S_OK;
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case VSS_OP_FREEZE:
|
||||||
|
case VSS_OP_THAW:
|
||||||
|
error = vss_operate(op);
|
||||||
|
if (error)
|
||||||
|
error = HV_E_FAIL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
syslog(LOG_ERR, "Illegal op:%d\n", op);
|
||||||
|
}
|
||||||
|
vss_msg->error = error;
|
||||||
|
len = netlink_send(fd, incoming_cn_msg);
|
||||||
|
if (len < 0) {
|
||||||
|
syslog(LOG_ERR, "net_link send failed; error:%d", len);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user