VirtualBox

Changeset 48538 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
Sep 19, 2013 3:17:43 PM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
89083
Message:

Main/NetworkAdapter+Machine+Appliance+SystemProperties+Medium+Console+Settings+IDL: make NAT networking a separate network attachment type which improves the user experience, store the necessary settings, plus changing the design of the methods which will move images and entire VMs, they lacked a progress object
Frontends/VirtualBox: adapted fully, can configure NAT networks with proper drop down list support
Frontends/VBoxManage: also supports NAT networks completely, and adds the long missing code to list intnets

Location:
trunk/src/VBox/Main
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r48505 r48538  
    13831383  /////////////////////////////////////////////////////////////////////////
    13841384  -->
    1385   <!-- This is experimental interface to LWIP based NAT server -->
     1385
    13861386  <interface name="INATNetwork" extends="$unknown"
    13871387    uuid="a63c75da-4c99-4e9d-8351-eb73651c18cc"
     
    25862586      <!-- Here we create a record in NAT network array with name
    25872587           and gateway/network parameters this information should
    2588            be enough for VBoxNet[Lwip]NAT and VBoxNetDHCP for
     2588           be enough for VBoxNetNAT and VBoxNetDHCP for
    25892589           servicing the guests.
    25902590      -->
     
    41224122  <interface
    41234123    name="IMachine" extends="$unknown"
    4124     uuid="8c931034-83f6-46b8-97f0-31e70d30402e"
     4124    uuid="7108c7c7-2c0a-47ee-9c69-022fe2a466bf"
    41254125    wsmap="managed"
    41264126    >
     
    45484548    </attribute>
    45494549
    4550     <attribute name="settingsFilePath" type="wstring">
     4550    <attribute name="settingsFilePath" type="wstring" readonly="yes">
    45514551      <desc>
    45524552        Full name of the file containing machine settings data.
    4553 
    4554         Currently, it is an error to change this property on any machine.
    4555         Later this will allow setting a new path for the settings file, with
    4556         automatic relocation of all files (including snapshots and disk images)
    4557         which are inside the base directory.
    4558 
    4559         <note>
    4560           Setting this property to @c null or to an empty string is forbidden.
    4561         </note>
    4562         <note>
    4563           When setting this property, the specified path must be absolute. When
    4564           reading this property, an absolute (full) path is always returned.
    4565         </note>
    4566         <note>
    4567           The specified path may not exist, it will be created when necessary.
    4568         </note>
    45694553      </desc>
    45704554    </attribute>
     
    63136297          New property value.
    63146298        </desc>
     6299      </param>
     6300    </method>
     6301
     6302    <method name="setSettingsFilePath">
     6303      <desc>
     6304        Currently, it is an error to change this property on any machine.
     6305        Later this will allow setting a new path for the settings file, with
     6306        automatic relocation of all files (including snapshots and disk images)
     6307        which are inside the base directory. This operation is only allowed
     6308        when there are no pending unsaved settings.
     6309
     6310        <note>
     6311          Setting this property to @c null or to an empty string is forbidden.
     6312          When setting this property, the specified path must be absolute.
     6313          The specified path may not exist, it will be created when necessary.
     6314        </note>
     6315
     6316        <result name="E_NOTIMPL">
     6317          The operation is not implemented yet.
     6318        </result>
     6319      </desc>
     6320
     6321      <param name="settingsFilePath" type="wstring" dir="in">
     6322        <desc>New settings file path, will be used to determine the new
     6323        location for the attached media if it is in the same directory or
     6324        below as the original settings file.</desc>
     6325      </param>
     6326      <param name="progress" type="IProgress" dir="return">
     6327        <desc>Progress object to track the operation completion.</desc>
    63156328      </param>
    63166329    </method>
     
    1304513058  <interface
    1304613059    name="IMedium" extends="$unknown"
    13047     uuid="8df5fc17-503a-4171-85bc-039b6f24d86b"
     13060    uuid="05f2bbb6-a3a6-4fb9-9b49-6d0dda7142ac"
    1304813061    wsmap="managed"
    1304913062    >
     
    1325913272    </attribute>
    1326013273
    13261     <attribute name="location" type="wstring">
     13274    <attribute name="location" type="wstring" readonly="yes">
    1326213275      <desc>
    1326313276        Location of the storage unit holding medium data.
     
    1326613279        types using regular files in a host's file system, the location
    1326713280        string is the full file name.
    13268 
    13269         Some medium types may support changing the storage unit location by
    13270         simply changing the value of this property. If this operation is not
    13271         supported, the implementation will return E_NOTIMPL in attempt to set
    13272         this attribute's value.
    13273 
    13274         When setting a value of the location attribute which is a regular file
    13275         in the host's file system, the given file name may be either relative to
    13276         the <link to="IVirtualBox::homeFolder">VirtualBox home folder</link> or
    13277         absolute. Note that if the given location specification does not contain
    13278         the file extension part then a proper default extension will be
    13279         automatically appended by the implementation depending on the medium type.
    1328013281      </desc>
    1328113282    </attribute>
     
    1418614187    <!-- other methods -->
    1418714188
     14189    <method name="setLocation">
     14190      <desc>
     14191        Changes the location of this medium. Some medium types may support
     14192        changing the storage unit location by simply changing the value of the
     14193        associated property. In this case the operation is performed
     14194        immediately, and @a progress is returning a @c null reference.
     14195        Otherwise on success there is a progress object returned, which
     14196        signals progress and completion of the operation. This distinction is
     14197        necessary because for some formats the operation is very fast, while
     14198        for others it can be very slow (moving the image file by copying all
     14199        data), and in the former case it'd be a waste of resources to create
     14200        a progress object which will immediately signal completion.
     14201
     14202        When setting a location for a medium which corresponds to a/several
     14203        regular file(s) in the host's file system, the given file name may be
     14204        either relative to the <link to="IVirtualBox::homeFolder">VirtualBox
     14205        home folder</link> or absolute. Note that if the given location
     14206        specification does not contain the file extension part then a proper
     14207        default extension will be automatically appended by the implementation
     14208        depending on the medium type.
     14209
     14210        <result name="E_NOTIMPL">
     14211          The operation is not implemented yet.
     14212        </result>
     14213        <result name="VBOX_E_NOT_SUPPORTED">
     14214          Medium format does not support changing the location.
     14215        </result>
     14216      </desc>
     14217      <param name="location" type="wstring" dir="in">
     14218        <desc>New location.</desc>
     14219      </param>
     14220      <param name="progress" type="IProgress" dir="return">
     14221        <desc>Progress object to track the operation completion.</desc>
     14222      </param>
     14223    </method>
     14224
    1418814225    <method name="compact">
    1418914226      <desc>
     
    1565115688  <enum
    1565215689    name="NetworkAttachmentType"
    15653     uuid="2ac4bc71-6b82-417a-acd1-f7426d2570d6"
     15690    uuid="524a8f9d-4b86-4b51-877d-1aa27c4ebeac"
    1565415691    >
    1565515692    <desc>
     
    1566515702    <const name="HostOnly"              value="4"/>
    1566615703    <const name="Generic"               value="5"/>
     15704    <const name="NATNetwork"            value="6"/>
    1566715705  </enum>
    1566815706
  • trunk/src/VBox/Main/include/MachineImpl.h

    r48505 r48538  
    457457    STDMETHOD(COMGETTER(USBDeviceFilters))(IUSBDeviceFilters * *aUSBDeviceFilters);
    458458    STDMETHOD(COMGETTER(SettingsFilePath))(BSTR *aFilePath);
    459     STDMETHOD(COMSETTER(SettingsFilePath))(IN_BSTR aFilePath);
    460459    STDMETHOD(COMGETTER(SettingsModified))(BOOL *aModified);
    461460    STDMETHOD(COMGETTER(SessionState))(SessionState_T *aSessionState);
     
    568567    STDMETHOD(GetHWVirtExProperty)(HWVirtExPropertyType_T property, BOOL *aVal);
    569568    STDMETHOD(SetHWVirtExProperty)(HWVirtExPropertyType_T property, BOOL aVal);
     569    STDMETHOD(SetSettingsFilePath)(IN_BSTR aFilePath, IProgress **aProgress);
    570570    STDMETHOD(SaveSettings)();
    571571    STDMETHOD(DiscardSettings)();
  • trunk/src/VBox/Main/include/MediumImpl.h

    r48297 r48538  
    106106    STDMETHOD(COMGETTER(Variant))(ComSafeArrayOut(MediumVariant_T, aVariant));
    107107    STDMETHOD(COMGETTER(Location))(BSTR *aLocation);
    108     STDMETHOD(COMSETTER(Location))(IN_BSTR aLocation);
    109108    STDMETHOD(COMGETTER(Name))(BSTR *aName);
    110109    STDMETHOD(COMGETTER(DeviceType))(DeviceType_T *aDeviceType);
     
    154153    STDMETHOD(CloneToBase)(IMedium *aTarget, ComSafeArrayIn(MediumVariant_T, aVariant),
    155154                           IProgress **aProgress);
     155    STDMETHOD(SetLocation)(IN_BSTR aLocation, IProgress **aProgress);
    156156    STDMETHOD(Compact)(IProgress **aProgress);
    157157    STDMETHOD(Resize)(LONG64 aLogicalSize, IProgress **aProgress);
  • trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp

    r48528 r48538  
    48574857            }
    48584858
     4859            case NetworkAttachmentType_NATNetwork:
     4860            {
     4861                hrc = aNetworkAdapter->COMGETTER(NATNetwork)(bstr.asOutParam());            H();
     4862                if (!bstr.isEmpty())
     4863                {
     4864                    /** @todo add intnet prefix to separate namespaces, and add trunk if dealing with vboxnatX */
     4865                    InsertConfigString(pLunL0, "Driver", "IntNet");
     4866                    InsertConfigNode(pLunL0, "Config", &pCfg);
     4867                    InsertConfigString(pCfg, "Network", bstr);
     4868                    InsertConfigInteger(pCfg, "TrunkType", kIntNetTrunkType_WhateverNone);
     4869                    InsertConfigString(pCfg, "IfPolicyPromisc", pszPromiscuousGuestPolicy);
     4870                    networkName = bstr;
     4871                    trunkType = Bstr(TRUNKTYPE_WHATEVER);
     4872                }
     4873                break;
     4874            }
     4875
    48594876            default:
    48604877                AssertMsgFailed(("should not get here!\n"));
     
    48754892            case NetworkAttachmentType_NAT:
    48764893            case NetworkAttachmentType_Generic:
     4894            case NetworkAttachmentType_NATNetwork:
    48774895            {
    48784896                if (SUCCEEDED(hrc) && SUCCEEDED(rc))
  • trunk/src/VBox/Main/src-server/ApplianceImpl.cpp

    r47716 r48538  
    66
    77/*
    8  * Copyright (C) 2008-2012 Oracle Corporation
     8 * Copyright (C) 2008-2013 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    305305        case NetworkAttachmentType_HostOnly: strType = "HostOnly"; break;
    306306        case NetworkAttachmentType_Generic: strType = "Generic"; break;
     307        case NetworkAttachmentType_NATNetwork: strType = "NATNetwork"; break;
    307308        case NetworkAttachmentType_Null: strType = "Null"; break;
    308309    }
     
    775776    /** @todo: Maybe too cost-intensive; try to find a lighter way */
    776777    while (    RTPathExists(tmpName)
    777             || mVirtualBox->OpenMedium(Bstr(tmpName).raw(), DeviceType_HardDisk, AccessMode_ReadWrite, FALSE /* fForceNewUuid */,  &harddisk) != VBOX_E_OBJECT_NOT_FOUND 
     778            || mVirtualBox->OpenMedium(Bstr(tmpName).raw(), DeviceType_HardDisk, AccessMode_ReadWrite, FALSE /* fForceNewUuid */,  &harddisk) != VBOX_E_OBJECT_NOT_FOUND
    778779          )
    779780    {
  • trunk/src/VBox/Main/src-server/ApplianceImplImport.cpp

    r48117 r48538  
    27142714                        if (FAILED(rc)) throw rc;
    27152715                        /* Set the interface name to attach to */
    2716                         pNetworkAdapter->COMSETTER(BridgedInterface)(name.raw());
     2716                        rc = pNetworkAdapter->COMSETTER(BridgedInterface)(name.raw());
    27172717                        if (FAILED(rc)) throw rc;
    27182718                        break;
     
    27472747                        if (FAILED(rc)) throw rc;
    27482748                        /* Set the interface name to attach to */
    2749                         pNetworkAdapter->COMSETTER(HostOnlyInterface)(name.raw());
     2749                        rc = pNetworkAdapter->COMSETTER(HostOnlyInterface)(name.raw());
    27502750                        if (FAILED(rc)) throw rc;
    27512751                        break;
     
    27662766                rc = pNetworkAdapter->COMSETTER(AttachmentType)(NetworkAttachmentType_Generic);
    27672767                if (FAILED(rc)) throw rc;
     2768            }
     2769            /* Next test for NAT network interfaces */
     2770            else if (pvsys->strExtraConfigCurrent.endsWith("type=NATNetwork", Utf8Str::CaseInsensitive))
     2771            {
     2772                /* Attach to the right interface */
     2773                rc = pNetworkAdapter->COMSETTER(AttachmentType)(NetworkAttachmentType_NATNetwork);
     2774                if (FAILED(rc)) throw rc;
     2775                com::SafeIfaceArray<INATNetwork> nwNATNetworks;
     2776                rc = mVirtualBox->COMGETTER(NATNetworks)(ComSafeArrayAsOutParam(nwNATNetworks));
     2777                if (FAILED(rc)) throw rc;
     2778                // Pick the first NAT network (if there is any)
     2779                if (nwNATNetworks.size())
     2780                {
     2781                    Bstr name;
     2782                    rc = nwNATNetworks[0]->COMGETTER(NetworkName)(name.asOutParam());
     2783                    if (FAILED(rc)) throw rc;
     2784                    /* Set the NAT network name to attach to */
     2785                    rc = pNetworkAdapter->COMSETTER(NATNetwork)(name.raw());
     2786                    if (FAILED(rc)) throw rc;
     2787                    break;
     2788                }
    27682789            }
    27692790        }
     
    33253346        it1->fEnabled = false;
    33263347        if (!(   fKeepAllMACs
    3327               || (fKeepNATMACs && it1->mode == NetworkAttachmentType_NAT)))
     3348              || (fKeepNATMACs && it1->mode == NetworkAttachmentType_NAT)
     3349              || (fKeepNATMACs && it1->mode == NetworkAttachmentType_NATNetwork)))
    33283350            Host::generateMACAddress(it1->strMACAddress);
    33293351    }
  • trunk/src/VBox/Main/src-server/MachineImpl.cpp

    r48505 r48538  
    27522752    mData->m_strConfigFileFull.cloneTo(aFilePath);
    27532753    return S_OK;
    2754 }
    2755 
    2756 STDMETHODIMP Machine::COMSETTER(SettingsFilePath)(IN_BSTR aFilePath)
    2757 {
    2758     CheckComArgStrNotEmptyOrNull(aFilePath);
    2759 
    2760     AutoCaller autoCaller(this);
    2761     if (FAILED(autoCaller.rc())) return autoCaller.rc();
    2762 
    2763     ReturnComNotImplemented();
    27642754}
    27652755
     
    52875277
    52885278    return S_OK;
     5279}
     5280
     5281STDMETHODIMP Machine::SetSettingsFilePath(IN_BSTR aFilePath, IProgress **aProgress)
     5282{
     5283    CheckComArgStrNotEmptyOrNull(aFilePath);
     5284    CheckComArgOutPointerValid(aProgress);
     5285
     5286    AutoCaller autoCaller(this);
     5287    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     5288
     5289    *aProgress = NULL;
     5290    ReturnComNotImplemented();
    52895291}
    52905292
  • trunk/src/VBox/Main/src-server/MediumImpl.cpp

    r48297 r48538  
    15431543}
    15441544
    1545 STDMETHODIMP Medium::COMSETTER(Location)(IN_BSTR aLocation)
    1546 {
    1547     CheckComArgStrNotEmptyOrNull(aLocation);
    1548 
    1549     AutoCaller autoCaller(this);
    1550     if (FAILED(autoCaller.rc())) return autoCaller.rc();
    1551 
    1552     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    1553 
    1554     /// @todo NEWMEDIA for file names, add the default extension if no extension
    1555     /// is present (using the information from the VD backend which also implies
    1556     /// that one more parameter should be passed to setLocation() requesting
    1557     /// that functionality since it is only allowed when called from this method
    1558 
    1559     /// @todo NEWMEDIA rename the file and set m->location on success, then save
    1560     /// the global registry (and local registries of portable VMs referring to
    1561     /// this medium), this will also require to add the mRegistered flag to data
    1562 
    1563     ReturnComNotImplemented();
    1564 }
    1565 
    15661545STDMETHODIMP Medium::COMGETTER(Name)(BSTR *aName)
    15671546{
     
    28922871
    28932872    return rc;
     2873}
     2874
     2875STDMETHODIMP Medium::SetLocation(IN_BSTR aLocation, IProgress **aProgress)
     2876{
     2877    CheckComArgStrNotEmptyOrNull(aLocation);
     2878    CheckComArgOutPointerValid(aProgress);
     2879
     2880    AutoCaller autoCaller(this);
     2881    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     2882
     2883    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     2884
     2885    /// @todo NEWMEDIA for file names, add the default extension if no extension
     2886    /// is present (using the information from the VD backend which also implies
     2887    /// that one more parameter should be passed to setLocation() requesting
     2888    /// that functionality since it is only allowed when called from this method
     2889
     2890    /// @todo NEWMEDIA rename the file and set m->location on success, then save
     2891    /// the global registry (and local registries of portable VMs referring to
     2892    /// this medium), this will also require to add the mRegistered flag to data
     2893
     2894    *aProgress = NULL;
     2895    ReturnComNotImplemented();
    28942896}
    28952897
     
    59865988    pToken->Abandon();
    59875989    pToken.setNull();
    5988    
     5990
    59895991    if (FAILED(rc)) return rc;
    59905992
  • trunk/src/VBox/Main/src-server/NetworkAdapterImpl.cpp

    r42825 r48538  
    55
    66/*
    7  * Copyright (C) 2006-2012 Oracle Corporation
     7 * Copyright (C) 2006-2013 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    478478        }
    479479
     480        /* there must a NAT network name */
     481        if (mData->mNATNetwork.isEmpty())
     482        {
     483            Log(("NAT network name not defined, setting to default \"NatNetwork\"\n"));
     484            mData->mNATNetwork = "NatNetwork";
     485        }
     486
    480487        mData->mAttachmentType = aAttachmentType;
    481488
     
    526533    if (mData->mBridgedInterface != aBridgedInterface)
    527534    {
     535        /* if an empty/null string is to be set, bridged interface must be
     536         * turned off */
     537        if (   (aBridgedInterface == NULL || *aBridgedInterface == '\0')
     538            && mData->mAttachmentType == NetworkAttachmentType_Bridged)
     539        {
     540            return setError(E_FAIL,
     541                            tr("Empty or null bridged interface name is not valid"));
     542        }
     543
    528544        mData.backup();
    529545        mData->mBridgedInterface = aBridgedInterface;
     
    577593    if (mData->mHostOnlyInterface != aHostOnlyInterface)
    578594    {
     595        /* if an empty/null string is to be set, host only interface must be
     596         * turned off */
     597        if (   (aHostOnlyInterface == NULL || *aHostOnlyInterface == '\0')
     598            && mData->mAttachmentType == NetworkAttachmentType_HostOnly)
     599        {
     600            return setError(E_FAIL,
     601                            tr("Empty or null host only interface name is not valid"));
     602        }
     603
    579604        mData.backup();
    580605        mData->mHostOnlyInterface = aHostOnlyInterface;
     
    684709    if (mData->mNATNetwork != aNATNetwork)
    685710    {
     711        /* if an empty/null string is to be set, host only interface must be
     712         * turned off */
     713        if (   (aNATNetwork == NULL || *aNATNetwork == '\0')
     714            && mData->mAttachmentType == NetworkAttachmentType_NATNetwork)
     715        {
     716            return setError(E_FAIL,
     717                            tr("Empty or null NAT network name is not valid"));
     718        }
     719
    686720        mData.backup();
    687721        mData->mNATNetwork = aNATNetwork;
     
    695729        mlock.release();
    696730
    697         /* Changing the NAT network isn't allowed during runtime, therefore
    698          * no immediate replug in CFGM logic => changeAdapter=FALSE */
    699         mParent->onNetworkAdapterChange(this, FALSE);
     731        /* When changing the host adapter, adapt the CFGM logic to make this
     732         * change immediately effect and to notify the guest that the network
     733         * might have changed, therefore changeAdapter=TRUE. */
     734        mParent->onNetworkAdapterChange(this, TRUE);
    700735    }
    701736
     
    12091244    mData->mGenericDriver = data.strGenericDriver;
    12101245    mData->mGenericProperties = data.genericProperties;
     1246    mData->mNATNetwork = data.strNATNetworkName;
    12111247
    12121248    // leave the lock before setting attachment type
     
    12691305    data.genericProperties = mData->mGenericProperties;
    12701306
     1307    data.strNATNetworkName = mData->mNATNetwork;
     1308
    12711309    // after saving settings, we are no longer different from the XML on disk
    12721310    m_fModified = false;
  • trunk/src/VBox/Main/src-server/SystemPropertiesImpl.cpp

    r48004 r48538  
    390390        case NetworkAttachmentType_NAT:
    391391        case NetworkAttachmentType_Internal:
     392        case NetworkAttachmentType_NATNetwork:
    392393            /* chipset default is OK */
    393394            break;
  • trunk/src/VBox/Main/xml/Settings.cpp

    r48408 r48538  
    24222422        }
    24232423    }
     2424    else if (elmMode.nameEquals("NATNetwork"))
     2425    {
     2426        enmAttachmentType = NetworkAttachmentType_NATNetwork;
     2427
     2428        if (!elmMode.getAttributeValue("name", nic.strNATNetworkName))    // required network name
     2429            throw ConfigFileError(this, &elmMode, N_("Required NATNetwork/@name element is missing"));
     2430    }
    24242431    else if (elmMode.nameEquals("VDE"))
    24252432    {
     
    44604467            if (nic.mode != NetworkAttachmentType_Generic)
    44614468                buildNetworkXML(NetworkAttachmentType_Generic, *pelmDisabledNode, false, nic);
     4469            if (nic.mode != NetworkAttachmentType_NATNetwork)
     4470                buildNetworkXML(NetworkAttachmentType_NATNetwork, *pelmDisabledNode, false, nic);
    44624471            buildNetworkXML(nic.mode, *pelmAdapter, true, nic);
    44634472        }
     
    47724781                }
    47734782            }
     4783            break;
     4784
     4785        case NetworkAttachmentType_NATNetwork:
     4786            if (fEnabled || !nic.strNATNetworkName.isEmpty())
     4787                elmParent.createChild("NATNetwork")->setAttribute("name", nic.strNATNetworkName);
    47744788            break;
    47754789
     
    53195333    {
    53205334        // VirtualBox 4.3 adds default frontend setting, graphics controller
    5321         // setting, explicit long mode setting and video capturing.
     5335        // setting, explicit long mode setting, video capturing and NAT networking.
    53225336        if (   !hardwareMachine.strDefaultFrontend.isEmpty()
    53235337            || hardwareMachine.graphicsControllerType != GraphicsControllerType_VBoxVGA
     
    53255339            || machineUserData.ovIcon.length() > 0
    53265340            || hardwareMachine.fVideoCaptureEnabled)
     5341        {
    53275342            m->sv = SettingsVersion_v1_14;
     5343            return;
     5344        }
     5345        NetworkAdaptersList::const_iterator netit;
     5346        for (netit = hardwareMachine.llNetworkAdapters.begin();
     5347             netit != hardwareMachine.llNetworkAdapters.end();
     5348             ++netit)
     5349        {
     5350            if (netit->mode == NetworkAttachmentType_NATNetwork)
     5351            {
     5352                m->sv = SettingsVersion_v1_14;
     5353                break;
     5354            }
     5355        }
    53285356    }
    53295357
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette