esx: Generate most SOAP mapping and improve inheritance handling

The Python script generates the mappings based on the type descriptions
in the esx_vi_generator.input file.

This also improves the inheritance handling and allows to get rid of the
ugly, inflexible, and error prone _base/_super approach. Now every struct
that represents a SOAP type contains a _type member, that allows to
recreate C++-like dynamic dispatch for "method" calls in C.
This commit is contained in:
Matthias Bolte 2010-03-06 17:56:28 +01:00
parent b4b0949dd7
commit 50723581b0
10 changed files with 1871 additions and 3070 deletions

View File

@ -26,6 +26,8 @@ INCLUDES = \
EXTRA_DIST = $(conf_DATA)
BUILT_SOURCES =
if WITH_NETWORK
UUID=$(shell uuidgen 2>/dev/null)
endif
@ -250,6 +252,20 @@ ESX_DRIVER_SOURCES = \
esx/esx_vi_types.c esx/esx_vi_types.h \
esx/esx_vmx.c esx/esx_vmx.h
ESX_DRIVER_GENERATED = \
esx/esx_vi_types.generated.c \
esx/esx_vi_types.generated.h \
esx/esx_vi_types.generated.typedef \
esx/esx_vi_types.generated.typeenum \
esx/esx_vi_types.generated.typetostring \
esx/esx_vi_types.generated.typefromstring
ESX_DRIVER_EXTRA_DIST = \
esx/README \
esx/esx_vi_generator.input \
esx/esx_vi_generator.py \
$(ESX_DRIVER_GENERATED)
NETWORK_DRIVER_SOURCES = \
network/bridge_driver.h network/bridge_driver.c
@ -594,7 +610,10 @@ libvirt_driver_one_la_SOURCES = $(ONE_DRIVER_SOURCES)
endif
BUILT_SOURCES += $(ESX_DRIVER_GENERATED)
$(ESX_DRIVER_GENERATED): $(srcdir)/esx/esx_vi_generator.input $(srcdir)/esx/esx_vi_generator.py
-srcdir=$(srcdir) $(srcdir)/esx/esx_vi_generator.py
if WITH_ESX
if WITH_DRIVER_MODULES
@ -610,6 +629,7 @@ if WITH_DRIVER_MODULES
libvirt_driver_esx_la_LDFLAGS += -module -avoid-version
endif
libvirt_driver_esx_la_SOURCES = $(ESX_DRIVER_SOURCES)
libvirt_driver_esx_la_DEPENDENCIES = $(ESX_DRIVER_GENERATED)
endif
if WITH_NETWORK
@ -784,6 +804,7 @@ EXTRA_DIST += \
$(VBOX_DRIVER_SOURCES) \
$(XENAPI_DRIVER_SOURCES) \
$(ESX_DRIVER_SOURCES) \
$(ESX_DRIVER_EXTRA_DIST) \
$(NETWORK_DRIVER_SOURCES) \
$(INTERFACE_DRIVER_SOURCES) \
$(STORAGE_DRIVER_SOURCES) \
@ -867,7 +888,7 @@ EXTRA_DIST += \
libvirt_macvtap.syms \
libvirt_daemon.syms
BUILT_SOURCES = libvirt.syms
BUILT_SOURCES += libvirt.syms
libvirt.syms: libvirt_public.syms $(USED_SYM_FILES)
rm -f $@-tmp $@

1
src/esx/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.generated.*

View File

@ -1924,8 +1924,14 @@ esxDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
perfEntityMetric = perfEntityMetric->_next) {
VIR_DEBUG0("perfEntityMetric ...");
for (perfMetricIntSeries = perfEntityMetric->value;
perfMetricIntSeries != NULL;
perfMetricIntSeries =
esxVI_PerfMetricIntSeries_DynamicCast(perfEntityMetric->value);
if (perfMetricIntSeries == NULL) {
VIR_ERROR0("QueryPerf returned object with unexpected type");
}
for (; perfMetricIntSeries != NULL;
perfMetricIntSeries = perfMetricIntSeries->_next) {
VIR_DEBUG0("perfMetricIntSeries ...");

View File

@ -3,7 +3,7 @@
* esx_vi.c: client for the VMware VI API 2.5 to manage ESX hosts
*
* Copyright (C) 2010 Red Hat, Inc.
* Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
* Copyright (C) 2009-2010 Matthias Bolte <matthias.bolte@googlemail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -480,12 +480,12 @@ esxVI_Context_Connect(esxVI_Context *ctx, const char *url,
dynamicProperty = dynamicProperty->_next) {
if (STREQ(dynamicProperty->name, "vmFolder")) {
if (esxVI_ManagedObjectReference_CastFromAnyType
(dynamicProperty->val, &ctx->vmFolder, "Folder")) {
(dynamicProperty->val, &ctx->vmFolder)) {
goto failure;
}
} else if (STREQ(dynamicProperty->name, "hostFolder")) {
if (esxVI_ManagedObjectReference_CastFromAnyType
(dynamicProperty->val, &ctx->hostFolder, "Folder")) {
(dynamicProperty->val, &ctx->hostFolder)) {
goto failure;
}
} else {
@ -720,6 +720,21 @@ esxVI_Context_Execute(esxVI_Context *ctx, const char *methodName,
switch (occurrence) {
case esxVI_Occurrence_RequiredItem:
if ((*response)->node == NULL) {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
"Call to '%s' returned an empty result, "
"expecting a non-empty result", methodName);
goto failure;
} else if ((*response)->node->next != NULL) {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
"Call to '%s' returned a list, expecting "
"exactly one item", methodName);
goto failure;
}
break;
case esxVI_Occurrence_RequiredList:
if ((*response)->node == NULL) {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
"Call to '%s' returned an empty result, "
@ -740,7 +755,7 @@ esxVI_Context_Execute(esxVI_Context *ctx, const char *methodName,
break;
case esxVI_Occurrence_List:
case esxVI_Occurrence_OptionalList:
/* Any amount of items is valid */
break;
@ -821,10 +836,11 @@ esxVI_Enumeration_CastFromAnyType(const esxVI_Enumeration *enumeration,
*value = 0; /* undefined */
if (STRNEQ(anyType->other, enumeration->type)) {
if (anyType->type != enumeration->type) {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
"Expecting type '%s' but found '%s'", enumeration->type,
anyType->other);
"Expecting type '%s' but found '%s'",
esxVI_Type_ToString(enumeration->type),
esxVI_Type_ToString(anyType->type));
return -1;
}
@ -837,7 +853,7 @@ esxVI_Enumeration_CastFromAnyType(const esxVI_Enumeration *enumeration,
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
"Unknown value '%s' for %s", anyType->value,
enumeration->type);
esxVI_Type_ToString(enumeration->type));
return -1;
}
@ -870,7 +886,8 @@ esxVI_Enumeration_Serialize(const esxVI_Enumeration *enumeration,
return -1;
}
ESV_VI__XML_TAG__OPEN(output, element, enumeration->type);
ESV_VI__XML_TAG__OPEN(output, element,
esxVI_Type_ToString(enumeration->type));
virBufferAdd(output, name, -1);
@ -906,7 +923,7 @@ esxVI_Enumeration_Deserialize(const esxVI_Enumeration *enumeration,
}
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Unknown value '%s' for %s",
name, enumeration->type);
name, esxVI_Type_ToString(enumeration->type));
cleanup:
VIR_FREE(name);
@ -1009,7 +1026,7 @@ esxVI_List_CastFromAnyType(esxVI_AnyType *anyType, esxVI_List **list,
return -1;
}
for (childNode = anyType->_node->children; childNode != NULL;
for (childNode = anyType->node->children; childNode != NULL;
childNode = childNode->next) {
if (childNode->type != XML_ELEMENT_NODE) {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
@ -1151,7 +1168,7 @@ esxVI_BuildFullTraversalSpecItem(esxVI_SelectionSpec **fullTraversalSpecList,
}
if (esxVI_TraversalSpec_Alloc(&traversalSpec) < 0 ||
esxVI_String_DeepCopyValue(&traversalSpec->_base->name, name) < 0 ||
esxVI_String_DeepCopyValue(&traversalSpec->name, name) < 0 ||
esxVI_String_DeepCopyValue(&traversalSpec->type, type) < 0 ||
esxVI_String_DeepCopyValue(&traversalSpec->path, path) < 0) {
goto failure;
@ -1177,7 +1194,8 @@ esxVI_BuildFullTraversalSpecItem(esxVI_SelectionSpec **fullTraversalSpecList,
}
if (esxVI_SelectionSpec_AppendToList(fullTraversalSpecList,
traversalSpec->_base) < 0) {
esxVI_SelectionSpec_DynamicCast
(traversalSpec)) < 0) {
goto failure;
}
@ -1721,8 +1739,7 @@ esxVI_LookupResourcePoolByHostSystem
dynamicProperty = dynamicProperty->_next) {
if (STREQ(dynamicProperty->name, "parent")) {
if (esxVI_ManagedObjectReference_CastFromAnyType
(dynamicProperty->val, &managedObjectReference,
"ComputeResource") < 0) {
(dynamicProperty->val, &managedObjectReference) < 0) {
goto failure;
}
@ -1756,7 +1773,7 @@ esxVI_LookupResourcePoolByHostSystem
dynamicProperty = dynamicProperty->_next) {
if (STREQ(dynamicProperty->name, "resourcePool")) {
if (esxVI_ManagedObjectReference_CastFromAnyType
(dynamicProperty->val, resourcePool, "ResourcePool") < 0) {
(dynamicProperty->val, resourcePool) < 0) {
goto failure;
}
@ -2231,7 +2248,7 @@ esxVI_LookupPendingTaskInfoListByVirtualMachine
dynamicProperty = dynamicProperty->_next) {
if (STREQ(dynamicProperty->name, "recentTask")) {
if (esxVI_ManagedObjectReference_CastListFromAnyType
(dynamicProperty->val, &recentTaskList, "Task") < 0) {
(dynamicProperty->val, &recentTaskList) < 0) {
goto failure;
}

View File

@ -2,7 +2,7 @@
/*
* esx_vi.h: client for the VMware VI API 2.5 to manage ESX hosts
*
* Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
* Copyright (C) 2009-2010 Matthias Bolte <matthias.bolte@googlemail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -61,8 +61,9 @@ enum _esxVI_ProductVersion {
enum _esxVI_Occurrence {
esxVI_Occurrence_Undefined = 0,
esxVI_Occurrence_RequiredItem,
esxVI_Occurrence_RequiredList,
esxVI_Occurrence_OptionalItem,
esxVI_Occurrence_List,
esxVI_Occurrence_OptionalList,
esxVI_Occurrence_None
};
@ -132,7 +133,7 @@ struct _esxVI_EnumerationValue {
};
struct _esxVI_Enumeration {
const char *type;
esxVI_Type type;
esxVI_EnumerationValue values[10];
};

View File

@ -0,0 +1,426 @@
#
# Definitions of vSphere API 2.5 enumeration and objects types used as input
# for the esx_vi_generator.py script.
#
# This format is line-based, so end-of-line is important.
#
#
# Enumeration definition:
#
# enum <name>
# <value>
# ...
# end
#
#
# Object definition:
#
# object <name> [extends <name>]
# <type> <name> <occurrence>
# ...
# end
#
# Possible values for the <occurrence> field are:
#
# - r for a required item
# - rl for a required list
# - o for an optional item
# - ol for an optional list
# - i for an ignored item or list
#
# Object member sequence has to match the WSDL sequence
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Enumerations
#
enum ManagedEntityStatus
gray
green
yellow
red
end
enum ObjectUpdateKind
modify
enter
leave
end
enum PerfStatsType
absolute
delta
rate
end
enum PerfSummaryType
average
maximum
minimum
latest
summation
none
end
enum PropertyChangeOp
add
remove
assign
indirectRemove
end
enum SharesLevel
low
normal
high
custom
end
enum TaskInfoState
queued
running
success
error
end
enum VirtualMachineMovePriority
lowPriority
highPriority
defaultPriority
end
enum VirtualMachinePowerState
poweredOff
poweredOn
suspended
end
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Objects
#
object AboutInfo
String name r
String fullName r
String vendor r
String version r
String build r
String localeVersion o
String localeBuild o
String osType r
String productLineId r
String apiType r
String apiVersion r
end
object ChoiceOption extends OptionType
ElementDescription choiceInfo rl
Int defaultIndex o
end
object Description
String label r
String summary r
end
object DynamicProperty
String name r
AnyType val r
end
object ElementDescription extends Description
String key r
end
object Event
Int key r
Int chainId r
DateTime createdTime r
String userName r
DatacenterEventArgument datacenter i
ComputeResourceEventArgument computeResource i
HostEventArgument host i
VmEventArgument vm i
String fullFormattedMessage o
end
object HostCpuIdInfo
Int level r
String vendor o
String eax o
String ebx o
String ecx o
String edx o
end
object ObjectContent
ManagedObjectReference obj r
DynamicProperty propSet ol
MissingProperty missingSet i
end
object ObjectSpec
ManagedObjectReference obj r
Boolean skip o
SelectionSpec selectSet ol
end
object ObjectUpdate
ObjectUpdateKind kind r
ManagedObjectReference obj r
PropertyChange changeSet ol
MissingProperty missingSet i
end
object OptionType
Boolean valueIsReadonly o
end
object PerfCounterInfo
Int key r
ElementDescription nameInfo r
ElementDescription groupInfo r
ElementDescription unitInfo r
PerfSummaryType rollupType r
PerfStatsType statsType r
Int level o
Int associatedCounterId ol
end
object PerfEntityMetric extends PerfEntityMetricBase
PerfSampleInfo sampleInfo ol
PerfMetricSeries value ol
end
object PerfEntityMetricBase
ManagedObjectReference entity r
end
object PerfMetricId
Int counterId r
String instance r
end
object PerfMetricIntSeries extends PerfMetricSeries
Long value ol
end
object PerfMetricSeries
PerfMetricId id r
end
object PerfQuerySpec
ManagedObjectReference entity r
DateTime startTime o
DateTime endTime o
Int maxSample o
PerfMetricId metricId ol
Int intervalId o
String format o
end
object PerfSampleInfo
DateTime timestamp r
Int interval r
end
object PropertyChange
String name r
PropertyChangeOp op r
AnyType val o
end
object PropertyFilterSpec
PropertySpec propSet rl
ObjectSpec objectSet rl
end
object PropertyFilterUpdate
ManagedObjectReference filter r
ObjectUpdate objectSet ol
MissingObject missingSet i
end
object PropertySpec
String type r
Boolean all o
String pathSet ol
end
object ResourceAllocationInfo
Long reservation o
Boolean expandableReservation o
Long limit o
SharesInfo shares o
Long overheadLimit o
end
object ResourcePoolResourceUsage
Long reservationUsed r
Long reservationUsedForVm r
Long unreservedForPool r
Long unreservedForVm r
Long overallUsage r
Long maxUsage r
end
object SelectionSpec
String name o
end
object ServiceContent
ManagedObjectReference rootFolder r
ManagedObjectReference propertyCollector r
ManagedObjectReference viewManager o
AboutInfo about r
ManagedObjectReference setting o
ManagedObjectReference userDirectory o
ManagedObjectReference sessionManager o
ManagedObjectReference authorizationManager o
ManagedObjectReference perfManager o
ManagedObjectReference scheduledTaskManager o
ManagedObjectReference alarmManager o
ManagedObjectReference eventManager o
ManagedObjectReference taskManager o
ManagedObjectReference extensionManager o
ManagedObjectReference customizationSpecManager o
ManagedObjectReference customFieldsManager o
ManagedObjectReference accountManager o
ManagedObjectReference diagnosticManager o
ManagedObjectReference licenseManager o
ManagedObjectReference searchIndex o
ManagedObjectReference fileManager o
ManagedObjectReference virtualDiskManager o
ManagedObjectReference virtualizationManager o
end
object SharesInfo
Int shares r
SharesLevel level r
end
object TaskInfo
String key r
ManagedObjectReference task r
String name o
String descriptionId r
ManagedObjectReference entity o
String entityName o
ManagedObjectReference locked ol
TaskInfoState state r
Boolean cancelled r
Boolean cancelable r
LocalizedMethodFault error i
AnyType result o
Int progress o
TaskReason reason i
DateTime queueTime r
DateTime startTime o
DateTime completeTime o
Int eventChainId r
end
object TraversalSpec extends SelectionSpec
String type r
String path r
Boolean skip o
SelectionSpec selectSet ol
end
object UpdateSet
String version r
PropertyFilterUpdate filterSet ol
end
object UserSession
String key r
String userName r
String fullName r
DateTime loginTime r
DateTime lastActiveTime r
String locale r
String messageLocale r
end
object VirtualMachineConfigSpec
String changeVersion o
String name o
String version o
String uuid o
Long npivNodeWorldWideName ol
Long npivPortWorldWideName ol
String npivWorldWideNameType o
String npivWorldWideNameOp o
String locationId o
String guestId o
String alternateGuestName o
String annotation o
VirtualMachineFileInfo files i
ToolsConfigInfo tools i
VirtualMachineFlagInfo flags i
VirtualMachineConsolePreferences consolePreferences i
VirtualMachineDefaultPowerOpInfo powerOpInfo i
Int numCPUs o
Long memoryMB o
VirtualDeviceConfigSpec deviceChange i
ResourceAllocationInfo cpuAllocation o
ResourceAllocationInfo memoryAllocation o
VirtualMachineAffinityInfo cpuAffinity i
VirtualMachineAffinityInfo memoryAffinity i
VirtualMachineNetworkShaperInfo networkShaper i
VirtualMachineCpuIdInfoSpec cpuFeatureMask i
OptionValue extraConfig i
String swapPlacement o
VirtualMachineBootOptions bootOptions i
end
object VirtualMachineQuestionInfo
String id r
String text r
ChoiceOption choice r
VirtualMachineMessage message i
end

1025
src/esx/esx_vi_generator.py Executable file

File diff suppressed because it is too large Load Diff

View File

@ -304,7 +304,7 @@ ESX_VI__METHOD(RetrieveProperties,
(esxVI_Context *ctx,
esxVI_PropertyFilterSpec *specSet, /* list */
esxVI_ObjectContent **objectContentList),
List,
OptionalList,
{
ESX_VI__METHOD__CHECK_SERVICE()
ESX_VI__METHOD__PARAMETER__CHECK_OUTPUT(objectContentList)
@ -344,8 +344,7 @@ ESX_VI__METHOD(PowerOnVM_Task,
virtualMachine)
},
{
if (esxVI_ManagedObjectReference_Deserialize(response->node, task,
"Task") < 0) {
if (esxVI_ManagedObjectReference_Deserialize(response->node, task) < 0) {
goto failure;
}
})
@ -369,8 +368,7 @@ ESX_VI__METHOD(PowerOffVM_Task,
virtualMachine)
},
{
if (esxVI_ManagedObjectReference_Deserialize(response->node, task,
"Task") < 0) {
if (esxVI_ManagedObjectReference_Deserialize(response->node, task) < 0) {
goto failure;
}
})
@ -394,8 +392,7 @@ ESX_VI__METHOD(SuspendVM_Task,
virtualMachine)
},
{
if (esxVI_ManagedObjectReference_Deserialize(response->node, task,
"Task") < 0) {
if (esxVI_ManagedObjectReference_Deserialize(response->node, task) < 0) {
goto failure;
}
})
@ -428,8 +425,7 @@ ESX_VI__METHOD(MigrateVM_Task,
ESX_VI__METHOD__PARAMETER__SERIALIZE(VirtualMachinePowerState, state)
},
{
if (esxVI_ManagedObjectReference_Deserialize(response->node, task,
"Task") < 0) {
if (esxVI_ManagedObjectReference_Deserialize(response->node, task) < 0) {
goto failure;
}
})
@ -456,8 +452,7 @@ ESX_VI__METHOD(ReconfigVM_Task,
ESX_VI__METHOD__PARAMETER__SERIALIZE(VirtualMachineConfigSpec, spec)
},
{
if (esxVI_ManagedObjectReference_Deserialize(response->node, task,
"Task") < 0) {
if (esxVI_ManagedObjectReference_Deserialize(response->node, task) < 0) {
goto failure;
}
})
@ -490,8 +485,7 @@ ESX_VI__METHOD(RegisterVM_Task,
ESX_VI__METHOD__PARAMETER__SERIALIZE(ManagedObjectReference, host)
},
{
if (esxVI_ManagedObjectReference_Deserialize(response->node, task,
"Task") < 0) {
if (esxVI_ManagedObjectReference_Deserialize(response->node, task) < 0) {
goto failure;
}
})
@ -583,8 +577,8 @@ ESX_VI__METHOD(CreateFilter,
ESX_VI__METHOD__PARAMETER__SERIALIZE(Boolean, partialUpdates)
},
{
if (esxVI_ManagedObjectReference_Deserialize(response->node, propertyFilter,
"PropertyFilter") < 0) {
if (esxVI_ManagedObjectReference_Deserialize(response->node,
propertyFilter) < 0) {
goto failure;
}
})
@ -684,7 +678,7 @@ ESX_VI__METHOD(ValidateMigration,
esxVI_ManagedObjectReference *pool,
esxVI_ManagedObjectReference *host,
esxVI_Event **eventList),
List,
OptionalList,
{
ESX_VI__METHOD__PARAMETER__CHECK_OUTPUT(eventList)
},
@ -736,10 +730,8 @@ ESX_VI__METHOD(FindByIp,
ESX_VI__METHOD__PARAMETER__SERIALIZE(Boolean, vmSearch)
},
{
if (esxVI_ManagedObjectReference_Deserialize
(response->node, managedObjectReference,
vmSearch == esxVI_Boolean_True ? "VirtualMachine"
: "HostSystem") < 0) {
if (esxVI_ManagedObjectReference_Deserialize(response->node,
managedObjectReference) < 0) {
goto failure;
}
})
@ -771,10 +763,8 @@ ESX_VI__METHOD(FindByUuid,
ESX_VI__METHOD__PARAMETER__SERIALIZE(Boolean, vmSearch)
},
{
if (esxVI_ManagedObjectReference_Deserialize
(response->node, managedObjectReference,
vmSearch == esxVI_Boolean_True ? "VirtualMachine"
: "HostSystem") < 0) {
if (esxVI_ManagedObjectReference_Deserialize(response->node,
managedObjectReference) < 0) {
goto failure;
}
})
@ -789,7 +779,7 @@ ESX_VI__METHOD(QueryAvailablePerfMetric,
esxVI_DateTime *endTime,
esxVI_Int *intervalId,
esxVI_PerfMetricId **perfMetricIdList),
List,
OptionalList,
{
ESX_VI__METHOD__CHECK_SERVICE()
ESX_VI__METHOD__PARAMETER__CHECK_OUTPUT(perfMetricIdList)
@ -820,7 +810,7 @@ ESX_VI__METHOD(QueryPerfCounter,
(esxVI_Context *ctx,
esxVI_Int *counterId, /* list */
esxVI_PerfCounterInfo **perfCounterInfoList),
List,
OptionalList,
{
ESX_VI__METHOD__CHECK_SERVICE()
ESX_VI__METHOD__PARAMETER__CHECK_OUTPUT(perfCounterInfoList)
@ -848,7 +838,7 @@ ESX_VI__METHOD(QueryPerf,
(esxVI_Context *ctx,
esxVI_PerfQuerySpec *querySpec, /* list */
esxVI_PerfEntityMetric **perfEntityMetricList),
List,
OptionalList,
{
ESX_VI__METHOD__CHECK_SERVICE()
ESX_VI__METHOD__PARAMETER__CHECK_OUTPUT(perfEntityMetricList)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff