Index: /branches/rel_avx_2_7_5/lib/feactl/Makefile
===================================================================
--- /branches/rel_avx_2_7_5/lib/feactl/Makefile	(revision 9189)
+++ /branches/rel_avx_2_7_5/lib/feactl/Makefile	(working copy)
@@ -15,7 +15,7 @@
 CC = gcc
 #CFLAGS = -fPIC -Wformat -Wall -O -g  -std=c99
 CFLAGS = -fPIC -Wformat -Wall -Werror -O -g  -std=c99 -D_XOPEN_SOURCE -I../../src/library/avxvainst -I../../src/library/avxnet -I../vtch -I../casnmp -I/usr/include/libvirt/ -lcurl -L../../src/library/avxvainst -lavxvainst -L../../src/library/ca_util -I../../src/library/ca_util -lca_util \
-		-I../../src/library/avxresource/
+		-I../../src/library/avxresource/  -I/usr/include/libxml2/
 
 #make
 all: $(STARGET)
Index: /branches/rel_avx_2_7_5/lib/vtch/Makefile
===================================================================
--- /branches/rel_avx_2_7_5/lib/vtch/Makefile	(revision 9189)
+++ /branches/rel_avx_2_7_5/lib/vtch/Makefile	(working copy)
@@ -18,7 +18,8 @@
 CFLAGS = -fPIC -O -g \
          -lpthread -lmsgpack -lcurl -lresolv\
          -I../feactl -I../../src/library/avxvainst \
-         -I../../src/library/avxresource/
+         -I../../src/library/avxresource/ \
+		 -I/usr/include/libxml2/
 CFLAGS_FEACTL = -lfeactl
 
 #make
Index: /branches/rel_avx_2_7_5/src/avxd/Makefile
===================================================================
--- /branches/rel_avx_2_7_5/src/avxd/Makefile	(revision 9189)
+++ /branches/rel_avx_2_7_5/src/avxd/Makefile	(working copy)
@@ -42,7 +42,7 @@
 SRC=avx_rpcserver.c avx_daemon.c
 OBJS=avx_rpcserver.o avx_daemon.o
 
-FLAGS =$(JSON_LIB) -Wformat -Wall -Wno-long-long -Werror -O -I${TOP}/src/library/avxresource/ 
+FLAGS =$(JSON_LIB) -Wformat -Wall -Wno-long-long -Werror -O -I${TOP}/src/library/avxresource/  -I/usr/include/libxml2/
 
 all: avxd
 
Index: /branches/rel_avx_2_7_5/src/backend/Makefile
===================================================================
--- /branches/rel_avx_2_7_5/src/backend/Makefile	(revision 9189)
+++ /branches/rel_avx_2_7_5/src/backend/Makefile	(working copy)
@@ -52,7 +52,7 @@
 	 -I${TOP}/lib/casnmp -I${TOP}/lib/avxpci -I${TOP}/lib/feactl  \
      -I ${TOP}/src/library/avxnet/ \
 	 -I ${TOP}/src/library/avx_log -I$(TOP)/src/library/avxha \
-	 -I ${TOP}/src/library/avxresource/ -L${TOP}/src/library/avxresource/ 
+	 -I ${TOP}/src/library/avxresource/ -L${TOP}/src/library/avxresource/ -I/usr/include/libxml2/
 
 all: backend recovery res_budget
 
Index: /branches/rel_avx_2_7_5/src/library/avxha/ha_info.c
===================================================================
--- /branches/rel_avx_2_7_5/src/library/avxha/ha_info.c	(revision 9189)
+++ /branches/rel_avx_2_7_5/src/library/avxha/ha_info.c	(working copy)
@@ -28,6 +28,7 @@
 
 #include "ha_info.h"
 #include "../avxvainst/va_log.h"
+#include "../avxvainst/va_info.h"
 
 #define AVX_HA_INFO "/ca/conf/ha/avxha.info"
 
@@ -294,7 +295,11 @@
     ret = 0;
 cleanup:
     if(doc) {
-        xmlSaveFormatFileEnc(AVX_HA_INFO, doc, "UTF-8", 1);
+        if (save_xml_atomic(doc, AVX_HA_INFO) != 0) {
+            va_log_error("%s: Failed to save file(%s)", __func__, AVX_HA_INFO);
+            xmlFreeDoc(doc);
+            return -1;
+        }
         xmlFreeDoc(doc);
         doc = NULL;
     }
Index: /branches/rel_avx_2_7_5/src/library/avxnet/avx_bridge.c
===================================================================
--- /branches/rel_avx_2_7_5/src/library/avxnet/avx_bridge.c	(revision 9189)
+++ /branches/rel_avx_2_7_5/src/library/avxnet/avx_bridge.c	(working copy)
@@ -246,7 +246,11 @@
 
    xmlDocSetRootElement(doc, root_node);
 
-   xmlSaveFormatFileEnc(file, doc, "UTF-8", 1);
+    if (save_xml_atomic(doc, file) != 0) {
+        va_log_error("%s: Failed to save file(%s)", __func__, file);
+        xmlFreeDoc(doc);
+        return -1;
+    }
    xmlFreeDoc(doc);
    return 0;
 }
@@ -320,7 +324,11 @@
         n1 = NULL;
     }
 
-    xmlSaveFormatFileEnc(BRIDGE_CONF, doc, "UTF-8", 1);
+    if (save_xml_atomic(doc, BRIDGE_CONF) != 0) {
+        va_log_error("%s: Failed to save file(%s)", __func__, BRIDGE_CONF);
+        xmlFreeDoc(doc);
+        return -1;
+    }
     xmlFreeDoc(doc);
     return 0;
 }
@@ -840,7 +848,11 @@
 
     save_doc:
     free_xmlstr(&n1);
-    xmlSaveFormatFileEnc(BRIDGE_CONF, doc, "UTF-8", 1);
+    if (save_xml_atomic(doc, BRIDGE_CONF) != 0) {
+        va_log_error("%s: Failed to save file(%s)", __func__, BRIDGE_CONF);
+        xmlFreeDoc(doc);
+        return -1;
+    }
     xmlFreeDoc(doc);
     return 0;   
 }
@@ -2441,7 +2453,11 @@
 
     free_xmlstr(&n1);
 
-    xmlSaveFormatFileEnc(BRIDGE_CONF, doc, "UTF-8", 1);
+    if (save_xml_atomic(doc, BRIDGE_CONF) != 0) {
+        va_log_error("%s: Failed to save file(%s)", __func__, BRIDGE_CONF);
+        xmlFreeDoc(doc);
+        return -1;
+    }
     xmlFreeDoc(doc);
     return 0;
 }
@@ -3108,7 +3124,11 @@
         }
         current_node = current_node->next;
     }
-    xmlSaveFormatFileEnc(VPORT_MAPPING, doc, "UTF-8", 1);
+    if (save_xml_atomic(doc, VPORT_MAPPING) != 0) {
+        va_log_error("%s: Failed to save file(%s)", __func__, VPORT_MAPPING);
+        xmlFreeDoc(doc);
+        return -1;
+    }
     xmlFreeDoc(doc);
     return 0;
 }
@@ -3146,7 +3166,11 @@
         }
     }
 
-    xmlSaveFormatFileEnc(VPORT_MAPPING, doc, "UTF-8", 1);
+    if (save_xml_atomic(doc, VPORT_MAPPING) != 0) {
+        va_log_error("%s: Failed to save file(%s)", __func__, VPORT_MAPPING);
+        xmlFreeDoc(doc);
+        return -1;
+    }
     xmlFreeDoc(doc);
     return 0;
 }
Index: /branches/rel_avx_2_7_5/src/library/avxnet/avx_sriov.c
===================================================================
--- /branches/rel_avx_2_7_5/src/library/avxnet/avx_sriov.c	(revision 9189)
+++ /branches/rel_avx_2_7_5/src/library/avxnet/avx_sriov.c	(working copy)
@@ -396,7 +396,11 @@
         cur = cur->next;
     }
 
-    xmlSaveFormatFileEnc(VLAN_VF_CONF, doc, "UTF-8", 1);
+    if (save_xml_atomic(doc, VLAN_VF_CONF) != 0) {
+        va_log_error("%s: Failed to save file(%s)", __func__, VLAN_VF_CONF);
+        xmlFreeDoc(doc);
+        return -1;
+    }
     xmlFreeDoc(doc);
     return 0;
 }
@@ -459,7 +463,11 @@
         xmlNewProp(newChild, BAD_CAST "tag",BAD_CAST tag_s);
     }
 
-    xmlSaveFormatFileEnc(VLAN_VF_CONF, doc, "UTF-8", 1);
+    if (save_xml_atomic(doc, VLAN_VF_CONF) != 0) {
+        va_log_error("%s: Failed to save file(%s)", __func__, VLAN_VF_CONF);
+        xmlFreeDoc(doc);
+        return -1;
+    }
     xmlFreeDoc(doc);
     return 0;
 }
@@ -550,7 +558,11 @@
 
    xmlDocSetRootElement(doc, root_node);
 
-   xmlSaveFormatFileEnc(file, doc, "UTF-8", 1);
+    if (save_xml_atomic(doc, file) != 0) {
+        va_log_error("%s: Failed to save file(%s)", __func__, file);
+        xmlFreeDoc(doc);
+        return -1;
+    }
    xmlFreeDoc(doc);
    return 0;
 }
Index: /branches/rel_avx_2_7_5/src/library/avxnet/avxbond.c
===================================================================
--- /branches/rel_avx_2_7_5/src/library/avxnet/avxbond.c	(revision 9189)
+++ /branches/rel_avx_2_7_5/src/library/avxnet/avxbond.c	(working copy)
@@ -29,6 +29,8 @@
 #include "avxbond.h"
 #include "va_utils.h"
 #include "../avxvainst/va_constants.h"
+#include "va_info.h"
+#include "va_log.h"
 
 
 
@@ -306,7 +308,11 @@
         current_node = current_node->next;
     }
 
-    xmlSaveFormatFileEnc(BOND_CONF, doc, "UTF-8", 1);
+    if (save_xml_atomic(doc, BOND_CONF) != 0) {
+        va_log_error("%s: Failed to save file(%s)", __func__, BOND_CONF);
+        xmlFreeDoc(doc);
+        return -1;
+    }
     xmlFreeDoc(doc);
     return 0;
 }
@@ -370,7 +376,11 @@
         current_node = current_node->next;
     }
 
-    xmlSaveFormatFileEnc(BOND_CONF, doc, "UTF-8", 1);
+    if (save_xml_atomic(doc, BOND_CONF) != 0) {
+        va_log_error("%s: Failed to save file(%s)", __func__, BOND_CONF);
+        xmlFreeDoc(doc);
+        return -1;
+    }
     xmlFreeDoc(doc);
 
     return 0;
Index: /branches/rel_avx_2_7_5/src/library/avxvainst/avx_dpdk.c
===================================================================
--- /branches/rel_avx_2_7_5/src/library/avxvainst/avx_dpdk.c	(revision 9189)
+++ /branches/rel_avx_2_7_5/src/library/avxvainst/avx_dpdk.c	(working copy)
@@ -35,6 +35,7 @@
 #include "va_instance.h"
 #include "avxnet.h"
 #include "property.h"
+#include "va_info.h"
 
 
 extern int bridge_create(const char * bridge);
@@ -293,7 +294,11 @@
         }
     }
 
-    xmlSaveFormatFileEnc(AVX_OVSDPDK_CONF, doc, "UTF-8", 1);
+    if (save_xml_atomic(doc, AVX_OVSDPDK_CONF) != 0) {
+        va_log_error("%s: Failed to save file(%s)", __func__, AVX_OVSDPDK_CONF);
+        xmlFreeDoc(doc);
+        return -1;
+    }
     xmlFreeDoc(doc);
 
     xmlCleanupParser();
Index: /branches/rel_avx_2_7_5/src/library/avxvainst/va_config.c
===================================================================
--- /branches/rel_avx_2_7_5/src/library/avxvainst/va_config.c	(revision 9189)
+++ /branches/rel_avx_2_7_5/src/library/avxvainst/va_config.c	(working copy)
@@ -38,6 +38,7 @@
 #include "va_utils.h"
 #include "../avxresource/property.h"
 #include "../avxresource/property_model.h"
+#include "va_info.h"
 
 static int
 update_xml_name(xmlNodePtr node, const char *name)
@@ -1082,7 +1083,11 @@
         current_node = current_node->next;
     }
 
-    xmlSaveFormatFileEnc(filename, doc, "UTF-8", 1);
+    if (save_xml_atomic(doc, filename) != 0) {
+        va_log_error("%s: Failed to save file(%s)", __func__, filename);
+        xmlFreeDoc(doc);
+        return -1;
+    }
     xmlFreeDoc(doc);
     return 0;
 }
@@ -1901,7 +1906,11 @@
         }
         current_node = current_node->next;
     }
-    xmlSaveFormatFileEnc(filename, doc, "UTF-8", 1);
+    if (save_xml_atomic(doc, filename) != 0) {
+        va_log_error("%s: Failed to save file(%s)", __func__, filename);
+        xmlFreeDoc(doc);
+        return -1;
+    }
     xmlFreeDoc(doc);
     return 0;
 }
Index: /branches/rel_avx_2_7_5/src/library/avxvainst/va_info.h
===================================================================
--- /branches/rel_avx_2_7_5/src/library/avxvainst/va_info.h	(revision 9189)
+++ /branches/rel_avx_2_7_5/src/library/avxvainst/va_info.h	(working copy)
@@ -21,6 +21,11 @@
 #include "va_constants.h"
 #include <stdint.h>
 
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+
 #ifndef SYSTEM_REBOOT_FLAG
 #define SYSTEM_REBOOT_FLAG "/var/array/public/config/system_reboot_flag"
 #endif
@@ -242,4 +247,6 @@
 int va_instance_backup_list();
 int va_instance_info_del_usb(const char* name, const int usbidx);
 int create_usb_info(const int bus, const int device);
+int save_xml_atomic(xmlDocPtr doc, const char *path);
+int validate_utf8(const char *path);
 #endif
Index: /branches/rel_avx_2_7_5/src/library/avxvainst/va_info.c
===================================================================
--- /branches/rel_avx_2_7_5/src/library/avxvainst/va_info.c	(revision 9189)
+++ /branches/rel_avx_2_7_5/src/library/avxvainst/va_info.c	(working copy)
@@ -17,7 +17,10 @@
 
 #include <unistd.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
+#include <fcntl.h>
+#include <libgen.h>
 
 #include <libxml/tree.h>
 #include <libxml/parser.h>
@@ -495,8 +498,12 @@
     xmlNewChild(root_node, NULL, BAD_CAST "privatelicense",
                     BAD_CAST buff);
 
-    // dumping doc to file and release resource
-    xmlSaveFormatFileEnc(info_file, doc, "UTF-8", 1);
+    // dumping doc to file and release resource with atomic way
+    if (save_xml_atomic(doc, info_file) != 0) {
+        va_log_error("%s: Failed to save file(%s)", __func__, info_file);
+        xmlFreeDoc(doc);
+        return -1;
+    }
     xmlFreeDoc(doc);
 
     ret = 0;
@@ -828,7 +835,11 @@
         xmlNewChild(root_node, NULL, BAD_CAST "privatelicense", BAD_CAST buff);
     }
 
-    xmlSaveFormatFileEnc(info_file, doc, "UTF-8", 1);
+    if (save_xml_atomic(doc, info_file) != 0) {
+        va_log_error("%s: Failed to save file(%s)", __func__, info_file);
+        xmlFreeDoc(doc);
+        return -1;
+    }
     xmlFreeDoc(doc);
 
     ret = 0;
@@ -2210,7 +2221,11 @@
     }
     back_node = xmlNewChild(root_node, NULL, BAD_CAST "backpair", BAD_CAST va_name);
     xmlNewProp(back_node, BAD_CAST "backname", BAD_CAST backup_name); 
-    xmlSaveFormatFileEnc(AVX_VA_BACKUP_MAPPING, doc, "UTF-8", 1);
+    if (save_xml_atomic(doc, AVX_VA_BACKUP_MAPPING) != 0) {
+        va_log_error("%s: Failed to save file(%s)", __func__, AVX_VA_BACKUP_MAPPING);
+        xmlFreeDoc(doc);
+        return -1;
+    }
     xmlFreeDoc(doc);
     return 0;
 }
@@ -2247,7 +2262,11 @@
         }
         xmlFree(str_name);
     }
-    xmlSaveFormatFileEnc(AVX_VA_BACKUP_MAPPING, doc, "UTF-8", 1);
+    if (save_xml_atomic(doc, AVX_VA_BACKUP_MAPPING) != 0) {
+        va_log_error("%s: Failed to save file(%s)", __func__, AVX_VA_BACKUP_MAPPING);
+        xmlFreeDoc(doc);
+        return -1;
+    }
     xmlFreeDoc(doc);
     return 0;
 }
@@ -2419,7 +2438,11 @@
                     xmlSetProp(addr_node, BAD_CAST "bus", BAD_CAST buff);
                     snprintf(buff, sizeof(buff), "0x%x", device);
                     xmlSetProp(addr_node, BAD_CAST "device", BAD_CAST buff);
-                    xmlSaveFormatFileEnc("/tmp/usb.xml", doc, "UTF-8", 1);
+                    if (save_xml_atomic(doc, "/tmp/usb.xml") != 0) {
+                        va_log_error("%s: Failed to save file(%s)", __func__, "/tmp/usb.xml");
+                        xmlFreeDoc(doc);
+                        return -1;
+                    }
                     xmlFreeDoc(doc);
                     return 0;
                 }
@@ -2448,6 +2471,125 @@
     return 0;
 }
 
+int save_xml_atomic(xmlDocPtr doc, const char *path)
+{
+    char tmp[AVX_MAX_PATH_LEN + 1];
+    snprintf(tmp, sizeof(tmp), "%s.tmp", path);
+
+    // 1. dumping doc to temp file and release resource
+    int ret = xmlSaveFormatFileEnc(tmp, doc, "UTF-8", 1);
+    if (ret < 0)
+        goto fail;
+
+    // 2. fsync temp file
+    int fd = open(tmp, O_RDONLY);
+    if (fd < 0)
+        goto fail;
+
+    if (fsync(fd) != 0) {
+        close(fd);
+        goto fail;
+    }
+    close(fd);
+
+    // 3. UTF-8 validation BEFORE rename
+    // Any invalid byte (e.g. 0x98) aborts replace
+    if (validate_utf8(tmp) != 0) {
+        va_log_error("%s: ERROR: invalid UTF-8(%s)", __func__, tmp);
+        goto fail;
+    }
+    va_log_debug("%s: OK: valid UTF-8(%s)", __func__, tmp);
+
+    // 4. atomic replace
+    if (rename(tmp, path) != 0)
+        goto fail;
+
+    // 5. fsync directory (metadata durability)
+    char dir[AVX_MAX_PATH_LEN + 1];
+    strncpy(dir, path, sizeof(dir));
+    dir[sizeof(dir) - 1] = '\0';
+    dirname(dir);
+
+    int dfd = open(dir, O_DIRECTORY | O_RDONLY);
+    if (dfd < 0)
+        goto fail;
+
+    if (fsync(dfd) != 0) {
+        close(dfd);
+        goto fail;
+    }
+    close(dfd);
+
+
+    return 0;
+
+fail:
+    /*
+     * Cleanup temp file
+     * Old target file remains untouched
+     */
+    unlink(tmp);
+    return -1;
+}
+
+/*
+ * Validate UTF-8 encoding and explicitly reject byte 0x98
+ * return 0 = valid
+ * return -1 = invalid
+ */
+int validate_utf8(const char *path)
+{
+    int fd = open(path, O_RDONLY);
+    if (fd < 0)
+        return -1;
+
+    unsigned char buf[4096];
+    ssize_t n;
+    int expect_cont = 0;
+    ssize_t i;
+
+    while ((n = read(fd, buf, sizeof(buf))) > 0) {
+        for (i = 0; i < n; i++) {
+            unsigned char c = buf[i];
+
+            if (expect_cont > 0) {
+                /* must be 10xxxxxx */
+                if ((c & 0xC0) != 0x80) {
+                    close(fd);
+                    return -1;
+                }
+                expect_cont--;
+                continue;
+            }
+
+            /* ASCII */
+            if (c <= 0x7F)
+                continue;
+
+            /* EXPLICITLY reject 0x98 */
+            if (c == 0x98) {
+                close(fd);
+                return -1;
+            }
+
+            /* determine UTF-8 length */
+            if ((c & 0xE0) == 0xC0) {        // 110xxxxx
+                expect_cont = 1;
+            } else if ((c & 0xF0) == 0xE0) { // 1110xxxx
+                expect_cont = 2;
+            } else if ((c & 0xF8) == 0xF0) { // 11110xxx
+                expect_cont = 3;
+            } else {
+                close(fd);
+                return -1;
+            }
+        }
+    }
+
+    close(fd);
+    return (expect_cont == 0) ? 0 : -1;
+}
+
 #if 0
 int main()
 {
