Hello community,
here is the log from the commit of package hyper-v for openSUSE:Factory checked in at 2013-07-16 15:32:58
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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 2012-11-30 12:25:40.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.hyper-v.new/hyper-v.changes 2013-07-16 15:33:00.000000000 +0200
@@ -1,0 +2,49 @@
+Mon Jul 15 16:16:06 CEST 2013 - ohering@suse.de
+
+- update hv_kvp_daemon (merge 0783d72fa from v3.9-rc1)
+ Fix how ifcfg-* file is created
+
+-------------------------------------------------------------------
+Mon Jul 15 15:24:00 CEST 2013 - ohering@suse.de
+
+- update hv_kvp_daemon (changes up to 3.11-rc1):
+ Improve error logging in KVP daemon.
+ Fix file descriptor leaks
+ Check retrun value of strchr call
+ Check return value of poll call
+ Check return value of setsockopt call
+ daemon should check type of received Netlink msg
+ daemon setsockopt should use options macros
+ daemon should subscribe only to CN_KVP_IDX group
+
+-------------------------------------------------------------------
+Mon Jul 15 12:04:05 CEST 2013 - ohering@suse.de
+
+- Fix a bug in IPV6 subnet enumeration (bnc#828714)
+
+-------------------------------------------------------------------
+Tue Mar 26 18:03:47 CET 2013 - ohering@suse.de
+
+- Update hv_vss_daemon (bnc#811033)
+
+-------------------------------------------------------------------
+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
+
+- build hv_kvp_daemon with -D_GNU_SOURCE to get O_CLOEXEC
+
+-------------------------------------------------------------------
+Fri Mar 22 16:19:38 CET 2013 - ohering@suse.de
+
+- update hv_kvp_daemon
+ Use CLOEXEC when opening kvp_pool files
+ Fix permissions of created directory and files
+ Fix /var subdirectory (move state files from /var/opt to /var/lib)
+ Fix string types
+
+-------------------------------------------------------------------
New:
----
hyper-v.init.vss.sh
hyper-v.tools.hv.hv_vss_daemon.c
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ hyper-v.spec ++++++
--- /var/tmp/diff_new_pack.XcST14/_old 2013-07-16 15:33:01.000000000 +0200
+++ /var/tmp/diff_new_pack.XcST14/_new 2013-07-16 15:33:01.000000000 +0200
@@ -1,7 +1,7 @@
#
# spec file for package hyper-v
#
-# Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -17,22 +17,27 @@
%define hv_kvp_daemon hv_kvp_daemon
+%define hv_vss_daemon hv_vss_daemon
Name: hyper-v
ExclusiveArch: %ix86 x86_64
PreReq: %insserv_prereq
+Requires(pre): coreutils
Summary: Microsoft Hyper-V tools
License: GPL-2.0
Group: System/Kernel
Supplements: modalias(dmi*:svn*MicrosoftCorporation*:pn*VirtualMachine*:rn*VirtualMachine*)
Supplements: modalias(pci:v00001414d00005353sv*sd*bc*sc*i*)
Url: http://www.kernel.org
-Version: 4
+# Arbitrary version number
+Version: 5
Release: 0
Source5: hyper-v.kvptest.ps1.txt
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
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
@@ -47,23 +52,38 @@
cp -avL %{S:5} kvptest.ps1.txt
cp -vL %{S:9} %{hv_kvp_daemon}.h
cp -vL %{S:10} %{hv_kvp_daemon}.c
+cp -vL %{S:12} %{hv_vss_daemon}.c
%build
sed -i~ '/#include /d' %{hv_kvp_daemon}.c
+sed -i~ '/#include /d' %{hv_vss_daemon}.c
gcc \
$RPM_OPT_FLAGS \
-Wno-unused-variable \
-Wno-pointer-sign \
+ -D_GNU_SOURCE \
-g \
%{hv_kvp_daemon}.c \
-include %{hv_kvp_daemon}.h \
-DCN_KVP_IDX=0x9 \
-DCN_KVP_VAL=0x1 \
-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
mkdir -p $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
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
@@ -72,15 +92,35 @@
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/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
%defattr (-,root,root)
%doc kvptest.ps1.txt
-/etc/init.d/%{hv_kvp_daemon}
-/usr/sbin/rc%{hv_kvp_daemon}
-/usr/sbin/%{hv_kvp_daemon}
+/etc/init.d/*
+/usr/sbin/*
/usr/lib/%{name}
+%pre
+# hv_kvp_daemon in SLES11 SP2 stored temporary state files in /var/opt
+# move them to /var/lib and remove old directory, if possible.
+if test -d /var/opt/hyperv
+then
+ if mkdir -p -v -m 0755 /var/lib/hyperv && pushd /var/lib/hyperv > /dev/null
+ then
+ for oldfile in /var/opt/hyperv/ifcfg-* /var/opt/hyperv/.kvp_pool_*
+ do
+ if test -e "${oldfile}"
+ then
+ mv -vfb "${oldfile}" . || :
+ fi
+ done
+ popd > /dev/null
+ fi
+ rmdir -v /var/opt/hyperv || :
+fi
+
%post
board_vendor=
product_name=
@@ -100,10 +140,13 @@
then
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}}
fi
%preun
%stop_on_removal %{hv_kvp_daemon}
+%stop_on_removal %{hv_vss_daemon}
%postun
# no restart on update because the daemon can not be restarted
++++++ hyper-v.include.linux.hyperv.h ++++++
--- /var/tmp/diff_new_pack.XcST14/_old 2013-07-16 15:33:01.000000000 +0200
+++ /var/tmp/diff_new_pack.XcST14/_new 2013-07-16 15:33:01.000000000 +0200
@@ -27,6 +27,63 @@
#include
+
+/*
+ * 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.
*
++++++ hyper-v.init.vss.sh ++++++
#!/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
++++++ hyper-v.tools.hv.hv_kvp_daemon.c ++++++
--- /var/tmp/diff_new_pack.XcST14/_old 2013-07-16 15:33:01.000000000 +0200
+++ /var/tmp/diff_new_pack.XcST14/_new 2013-07-16 15:33:01.000000000 +0200
@@ -97,11 +97,15 @@
* The location of the interface configuration file.
*/
-#define KVP_CONFIG_LOC "/var/opt/"
+#define KVP_CONFIG_LOC "/var/lib/hyperv"
#define MAX_FILE_NAME 100
#define ENTRIES_PER_BLOCK 50
+#ifndef SOL_NETLINK
+#define SOL_NETLINK 270
+#endif
+
struct kvp_record {
char key[HV_KVP_EXCHANGE_MAX_KEY_SIZE];
char value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE];
@@ -123,7 +127,8 @@
fl.l_pid = getpid();
if (fcntl(kvp_file_info[pool].fd, F_SETLKW, &fl) == -1) {
- syslog(LOG_ERR, "Failed to acquire the lock pool: %d", pool);
+ syslog(LOG_ERR, "Failed to acquire the lock pool: %d; error: %d %s", pool,
+ errno, strerror(errno));
exit(EXIT_FAILURE);
}
}
@@ -134,8 +139,8 @@
fl.l_pid = getpid();
if (fcntl(kvp_file_info[pool].fd, F_SETLK, &fl) == -1) {
- perror("fcntl");
- syslog(LOG_ERR, "Failed to release the lock pool: %d", pool);
+ syslog(LOG_ERR, "Failed to release the lock pool: %d; error: %d %s", pool,
+ errno, strerror(errno));
exit(EXIT_FAILURE);
}
}
@@ -151,10 +156,11 @@
*/
kvp_acquire_lock(pool);
- filep = fopen(kvp_file_info[pool].fname, "w");
+ filep = fopen(kvp_file_info[pool].fname, "we");
if (!filep) {
+ syslog(LOG_ERR, "Failed to open file, pool: %d; error: %d %s", pool,
+ errno, strerror(errno));
kvp_release_lock(pool);
- syslog(LOG_ERR, "Failed to open file, pool: %d", pool);
exit(EXIT_FAILURE);
}
@@ -182,10 +188,11 @@
kvp_acquire_lock(pool);
- filep = fopen(kvp_file_info[pool].fname, "r");
+ filep = fopen(kvp_file_info[pool].fname, "re");
if (!filep) {
+ syslog(LOG_ERR, "Failed to open file, pool: %d; error: %d %s", pool,
+ errno, strerror(errno));
kvp_release_lock(pool);
- syslog(LOG_ERR, "Failed to open file, pool: %d", pool);
exit(EXIT_FAILURE);
}
for (;;) {
@@ -234,9 +241,10 @@
int i;
int alloc_unit = sizeof(struct kvp_record) * ENTRIES_PER_BLOCK;
- if (access("/var/opt/hyperv", F_OK)) {
- if (mkdir("/var/opt/hyperv", S_IRUSR | S_IWUSR | S_IROTH)) {
- syslog(LOG_ERR, " Failed to create /var/opt/hyperv");
+ if (access(KVP_CONFIG_LOC, F_OK)) {
+ if (mkdir(KVP_CONFIG_LOC, 0755 /* rwxr-xr-x */)) {
+ syslog(LOG_ERR, "Failed to create '%s'; error: %d %s", KVP_CONFIG_LOC,
+ errno, strerror(errno));
exit(EXIT_FAILURE);
}
}
@@ -245,20 +253,23 @@
fname = kvp_file_info[i].fname;
records_read = 0;
num_blocks = 1;
- sprintf(fname, "/var/opt/hyperv/.kvp_pool_%d", i);
- fd = open(fname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IROTH);
+ sprintf(fname, "%s/.kvp_pool_%d", KVP_CONFIG_LOC, i);
+ fd = open(fname, O_RDWR | O_CREAT | O_CLOEXEC, 0644 /* rw-r--r-- */);
if (fd == -1)
return 1;
- filep = fopen(fname, "r");
- if (!filep)
+ filep = fopen(fname, "re");
+ if (!filep) {
+ close(fd);
return 1;
+ }
record = malloc(alloc_unit * num_blocks);
if (record == NULL) {
fclose(filep);
+ close(fd);
return 1;
}
for (;;) {
@@ -282,6 +293,7 @@
num_blocks);
if (record == NULL) {
fclose(filep);
+ close(fd);
return 1;
}
continue;
@@ -299,7 +311,7 @@
return 0;
}
-static int kvp_key_delete(int pool, __u8 *key, int key_size)
+static int kvp_key_delete(int pool, const char *key, int key_size)
{
int i;
int j, k;
@@ -342,7 +354,7 @@
return 1;
}
-static int kvp_key_add_or_modify(int pool, __u8 *key, int key_size, __u8 *value,
+static int kvp_key_add_or_modify(int pool, const char *key, int key_size, const char *value,
int value_size)
{
int i;
@@ -396,7 +408,7 @@
return 0;
}
-static int kvp_get_value(int pool, __u8 *key, int key_size, __u8 *value,
+static int kvp_get_value(int pool, const char *key, int key_size, char *value,
int value_size)
{
int i;
@@ -428,8 +440,8 @@
return 1;
}
-static int kvp_pool_enumerate(int pool, int index, __u8 *key, int key_size,
- __u8 *value, int value_size)
+static int kvp_pool_enumerate(int pool, int index, char *key, int key_size,
+ char *value, int value_size)
{
struct kvp_record *record;
@@ -761,7 +773,9 @@
break;
x = strchr(p, '\n');
- *x = '\0';
+ if (x)
+ *x = '\0';
+
strcat(config_buf, p);
strcat(config_buf, ";");
}
@@ -1012,9 +1026,10 @@
if (sn_offset == 0)
strcpy(sn_str, cidr_mask);
- else
+ else {
+ strcat((char *)ip_buffer->sub_net, ";");
strcat(sn_str, cidr_mask);
- strcat((char *)ip_buffer->sub_net, ";");
+ }
sn_offset += strlen(sn_str) + 1;
}
@@ -1162,16 +1177,13 @@
snprintf(str, sizeof(str), "%s", "DNS");
break;
}
- if (i != 0) {
- if (type != DNS) {
- snprintf(sub_str, sizeof(sub_str),
- "_%d", i++);
- } else {
- snprintf(sub_str, sizeof(sub_str),
- "%d", ++i);
- }
- } else if (type == DNS) {
+
+ if (type == DNS) {
snprintf(sub_str, sizeof(sub_str), "%d", ++i);
+ } else if (type == GATEWAY && i == 0) {
+ ++i;
+ } else {
+ snprintf(sub_str, sizeof(sub_str), "%d", i++);
}
@@ -1191,17 +1203,13 @@
snprintf(str, sizeof(str), "%s", "DNS");
break;
}
- if ((j != 0) || (type == DNS)) {
- if (type != DNS) {
- snprintf(sub_str, sizeof(sub_str),
- "_%d", j++);
- } else {
- snprintf(sub_str, sizeof(sub_str),
- "%d", ++i);
- }
- } else if (type == DNS) {
- snprintf(sub_str, sizeof(sub_str),
- "%d", ++i);
+
+ if (type == DNS) {
+ snprintf(sub_str, sizeof(sub_str), "%d", ++i);
+ } else if (j == 0) {
+ ++j;
+ } else {
+ snprintf(sub_str, sizeof(sub_str), "_%d", j++);
}
} else {
return HV_INVALIDARG;
@@ -1244,18 +1252,19 @@
* Here is the format of the ip configuration file:
*
* HWADDR=macaddr
- * IF_NAME=interface name
- * DHCP=yes (This is optional; if yes, DHCP is configured)
+ * DEVICE=interface name
+ * BOOTPROTO=<protocol> (where <protocol> is "dhcp" if DHCP is configured
+ * or "none" if no boot-time protocol should be used)
*
- * IPADDR=ipaddr1
- * IPADDR_1=ipaddr2
- * IPADDR_x=ipaddry (where y = x + 1)
+ * IPADDR0=ipaddr1
+ * IPADDR1=ipaddr2
+ * IPADDRx=ipaddry (where y = x + 1)
*
- * NETMASK=netmask1
- * NETMASK_x=netmasky (where y = x + 1)
+ * NETMASK0=netmask1
+ * NETMASKx=netmasky (where y = x + 1)
*
* GATEWAY=ipaddr1
- * GATEWAY_x=ipaddry (where y = x + 1)
+ * GATEWAYx=ipaddry (where y = x + 1)
*
* DNSx=ipaddrx (where first DNS address is tagged as DNS1 etc)
*
@@ -1271,12 +1280,13 @@
*/
snprintf(if_file, sizeof(if_file), "%s%s%s", KVP_CONFIG_LOC,
- "hyperv/ifcfg-", if_name);
+ "/ifcfg-", if_name);
file = fopen(if_file, "w");
if (file == NULL) {
- syslog(LOG_ERR, "Failed to open config file");
+ syslog(LOG_ERR, "Failed to open config file; error: %d %s",
+ errno, strerror(errno));
return HV_E_FAIL;
}
@@ -1294,12 +1304,12 @@
if (error)
goto setval_error;
- error = kvp_write_file(file, "IF_NAME", "", if_name);
+ error = kvp_write_file(file, "DEVICE", "", if_name);
if (error)
goto setval_error;
if (new_val->dhcp_enabled) {
- error = kvp_write_file(file, "DHCP", "", "yes");
+ error = kvp_write_file(file, "BOOTPROTO", "", "dhcp");
if (error)
goto setval_error;
@@ -1307,6 +1317,11 @@
* We are done!.
*/
goto setval_done;
+
+ } else {
+ error = kvp_write_file(file, "BOOTPROTO", "", "none");
+ if (error)
+ goto setval_error;
}
/*
@@ -1408,7 +1423,7 @@
int main(void)
{
- int fd, len, sock_opt;
+ int fd, len, nl_group;
int error;
struct cn_msg *message;
struct pollfd pfd;
@@ -1438,23 +1453,30 @@
fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
if (fd < 0) {
- syslog(LOG_ERR, "netlink socket creation failed; error:%d", fd);
+ syslog(LOG_ERR, "netlink socket creation failed; error: %d %s", errno,
+ strerror(errno));
exit(EXIT_FAILURE);
}
addr.nl_family = AF_NETLINK;
addr.nl_pad = 0;
addr.nl_pid = 0;
- addr.nl_groups = CN_KVP_IDX;
+ addr.nl_groups = 0;
error = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
if (error < 0) {
- syslog(LOG_ERR, "bind failed; error:%d", error);
+ syslog(LOG_ERR, "bind failed; error: %d %s", errno, strerror(errno));
close(fd);
exit(EXIT_FAILURE);
}
- sock_opt = addr.nl_groups;
- setsockopt(fd, 270, 1, &sock_opt, sizeof(sock_opt));
+ nl_group = CN_KVP_IDX;
+
+ if (setsockopt(fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &nl_group, sizeof(nl_group)) < 0) {
+ syslog(LOG_ERR, "setsockopt failed; error: %d %s", errno, strerror(errno));
+ close(fd);
+ exit(EXIT_FAILURE);
+ }
+
/*
* Register ourselves with the kernel.
*/
@@ -1469,7 +1491,7 @@
len = netlink_send(fd, message);
if (len < 0) {
- syslog(LOG_ERR, "netlink_send failed; error:%d", len);
+ syslog(LOG_ERR, "netlink_send failed; error: %d %s", errno, strerror(errno));
close(fd);
exit(EXIT_FAILURE);
}
@@ -1481,7 +1503,16 @@
socklen_t addr_l = sizeof(addr);
pfd.events = POLLIN;
pfd.revents = 0;
- poll(&pfd, 1, -1);
+
+ if (poll(&pfd, 1, -1) < 0) {
+ syslog(LOG_ERR, "poll failed; error: %d %s", errno, strerror(errno));
+ if (errno == EINVAL) {
+ close(fd);
+ exit(EXIT_FAILURE);
+ }
+ else
+ continue;
+ }
len = recvfrom(fd, kvp_recv_buffer, sizeof(kvp_recv_buffer), 0,
addr_p, &addr_l);
@@ -1500,6 +1531,10 @@
}
incoming_msg = (struct nlmsghdr *)kvp_recv_buffer;
+
+ if (incoming_msg->nlmsg_type != NLMSG_DONE)
+ continue;
+
incoming_cn_msg = (struct cn_msg *)NLMSG_DATA(incoming_msg);
hv_msg = (struct hv_kvp_msg *)incoming_cn_msg->data;
@@ -1688,7 +1723,8 @@
len = netlink_send(fd, incoming_cn_msg);
if (len < 0) {
- syslog(LOG_ERR, "net_link send failed; error:%d", len);
+ syslog(LOG_ERR, "net_link send failed; error: %d %s", errno,
+ strerror(errno));
exit(EXIT_FAILURE);
}
}
++++++ hyper-v.tools.hv.hv_set_ifconfig.sh ++++++
--- /var/tmp/diff_new_pack.XcST14/_old 2013-07-16 15:33:01.000000000 +0200
+++ /var/tmp/diff_new_pack.XcST14/_new 2013-07-16 15:33:01.000000000 +0200
@@ -10,18 +10,19 @@
# Here is the format of the ip configuration file:
#
# HWADDR=macaddr
-# IF_NAME=interface name
-# DHCP=yes (This is optional; if yes, DHCP is configured)
+# DEVICE=interface name
+# BOOTPROTO=<protocol> (where <protocol> is "dhcp" if DHCP is configured
+# or "none" if no boot-time protocol should be used)
+#
+# IPADDR0=ipaddr1
+# IPADDR1=ipaddr2
+# IPADDRx=ipaddry (where y = x + 1)
#
-# IPADDR=ipaddr1
-# IPADDR_1=ipaddr2
-# IPADDR_x=ipaddry (where y = x + 1)
-#
-# NETMASK=netmask1
-# NETMASK_x=netmasky (where y = x + 1)
+# NETMASK0=netmask1
+# NETMASKx=netmasky (where y = x + 1)
#
# GATEWAY=ipaddr1
-# GATEWAY_x=ipaddry (where y = x + 1)
+# GATEWAYx=ipaddry (where y = x + 1)
#
# DNSx=ipaddrx (where first DNS address is tagged as DNS1 etc)
#
@@ -53,8 +54,8 @@
fi
# remove known config variables from environment
unset HWADDR
-unset DHCP
-unset IF_NAME
+unset BOOTPROTO
+unset DEVICE
unset ${!IPADDR*}
unset ${!NETMASK*}
unset ${!GATEWAY*}
@@ -64,9 +65,9 @@
unset ${!DNS*}
. "$1"
#
-if test -z "${IF_NAME}"
+if test -z "${DEVICE}"
then
- echo "Missing IF_NAME= in ${cfg}"
+ echo "Missing DEVICE= in ${cfg}"
exit 1
fi
#
@@ -91,7 +92,7 @@
: # ignore HWADDR, it just repeats the existing MAC value
fi
#
- if test "${DHCP}" = "yes"
+ if test "${BOOTPROTO}" = "dhcp"
then
echo "BOOTPROTO=dhcp"
fi
@@ -145,11 +146,11 @@
(
if test -n "${GATEWAY}"
then
- echo "default $GATEWAY - $IF_NAME"
+ echo "default $GATEWAY - $DEVICE"
fi
if test -n "${IPV6_DEFAULTGW}"
then
- echo "default $IPV6_DEFAULTGW - $IF_NAME"
+ echo "default $IPV6_DEFAULTGW - $DEVICE"
fi
) >> "${t_ifroute}"
# Only a single default gateway is supported
@@ -172,14 +173,14 @@
fi
done
#
-echo "$0: working on network interface ifcfg-${IF_NAME}"
-cp -fb ${t_ifcfg} "/etc/sysconfig/network/ifcfg-${IF_NAME}"
-cp -fb ${t_ifroute} "/etc/sysconfig/network/ifroute-${IF_NAME}"
+echo "$0: working on network interface ifcfg-${DEVICE}"
+cp -fb ${t_ifcfg} "/etc/sysconfig/network/ifcfg-${DEVICE}"
+cp -fb ${t_ifroute} "/etc/sysconfig/network/ifroute-${DEVICE}"
if test -w /etc/sysconfig/network/config
then
sed -i "s@^NETCONFIG_DNS_STATIC_SERVERS=.*@NETCONFIG_DNS_STATIC_SERVERS='$_DNS_'@" /etc/sysconfig/network/config
netconfig update -m dns
fi
-ifdown "${IF_NAME}"
-ifup "${IF_NAME}"
+ifdown "${DEVICE}"
+ifup "${DEVICE}"
) 2>&1 | logger -t "${0##*/}[$PPID / $$]"
++++++ hyper-v.tools.hv.hv_vss_daemon.c ++++++
/*
* An implementation of the host initiated guest snapshot for Hyper-V.
*
*
* Copyright (C) 2013, Microsoft, Inc.
* Author : K. Y. Srinivasan
*
* 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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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_do_freeze(char *dir, unsigned int cmd, char *fs_op)
{
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));
close(fd);
return !!ret;
}
static int vss_operate(int operation)
{
char *fs_op;
char match[] = "/dev/";
FILE *mounts;
struct mntent *ent;
unsigned int cmd;
int error = 0, root_seen = 0;
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;
}
mounts = setmntent("/proc/mounts", "r");
if (mounts == NULL)
return -1;
while((ent = getmntent(mounts))) {
if (strncmp(ent->mnt_fsname, match, strlen(match)))
continue;
if (strcmp(ent->mnt_dir, "/") == 0) {
root_seen = 1;
continue;
}
error |= vss_do_freeze(ent->mnt_dir, cmd, fs_op);
}
endmntent(mounts);
if (root_seen) {
error |= vss_do_freeze("/", cmd, fs_op);
}
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) {
syslog(LOG_ERR, "recvfrom failed; pid:%u error:%d %s",
addr.nl_pid, errno, strerror(errno));
close(fd);
return -1;
}
if (addr.nl_pid) {
syslog(LOG_WARNING, "Received packet from untrusted pid:%u",
addr.nl_pid);
continue;
}
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);
}
}
}
--
To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org
For additional commands, e-mail: opensuse-commit+help@opensuse.org