670
670
m->vdIfCallsTcpNet.cbSize = sizeof(VDINTERFACETCPNET);
671
671
m->vdIfCallsTcpNet.enmInterface = VDINTERFACETYPE_TCPNET;
672
672
m->vdIfCallsTcpNet.pfnClientConnect = RTTcpClientConnect;
673
m->vdIfCallsTcpNet.pfnClientClose = RTTcpClientClose;
673
m->vdIfCallsTcpNet.pfnClientClose = vdTcpClientClose;
674
674
m->vdIfCallsTcpNet.pfnSelectOne = RTTcpSelectOne;
675
675
m->vdIfCallsTcpNet.pfnRead = RTTcpRead;
676
676
m->vdIfCallsTcpNet.pfnWrite = RTTcpWrite;
3514
3514
uOpenFlags |= VD_OPEN_FLAGS_SHAREABLE;
3516
3516
/* Lock the medium, which makes the behavior much more consistent */
3517
if (uOpenFlags & (VD_OPEN_FLAGS_READONLY || VD_OPEN_FLAGS_SHAREABLE))
3517
if (uOpenFlags & (VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_SHAREABLE))
3518
3518
rc = LockRead(NULL);
3520
3520
rc = LockWrite(NULL);
3534
3534
uint64_t mediumSize = 0;
3535
3535
uint64_t mediumLogicalSize = 0;
3537
/* Flag whether a base image has a non-zero parent UUID and thus
3538
* need repairing after it was closed again. */
3539
bool fRepairImageZeroParentUuid = false;
3537
3541
/* leave the lock before a lengthy operation */
3538
3542
vrc = RTSemEventMultiReset(m->queryInfoSem);
3539
3543
AssertRCReturn(vrc, E_FAIL);
3689
3693
if (m->pParent.isNull())
3695
/* Due to a bug in VDCopy() in VirtualBox 3.0.0-3.0.14
3696
* and 3.1.0-3.1.8 there are base images out there
3697
* which have a non-zero parent UUID. No point in
3698
* complaining about them, instead automatically
3699
* repair the problem. Later we can bring back the
3700
* error message, but we should wait until really
3701
* most users have repaired their images, either with
3702
* VBoxFixHdd or this way. */
3704
fRepairImageZeroParentUuid = true;
3691
3706
lastAccessError = Utf8StrFmt(
3692
3707
tr("Medium type of '%s' is differencing but it is not associated with any parent medium in the media registry ('%s')"),
3693
3708
location.c_str(),
3694
3709
m->pVirtualBox->settingsFilePath().c_str());
3698
3714
AutoReadLock parentLock(m->pParent COMMA_LOCKVAL_SRC_POS);
3699
if ( m->pParent->getState() != MediumState_Inaccessible
3700
&& m->pParent->getId() != parentId)
3715
if ( !fRepairImageZeroParentUuid
3716
&& m->pParent->getState() != MediumState_Inaccessible
3717
&& m->pParent->getId() != parentId)
3702
3719
lastAccessError = Utf8StrFmt(
3703
3720
tr("Parent UUID {%RTuuid} of the medium '%s' does not match UUID {%RTuuid} of its parent medium stored in the media registry ('%s')"),
3761
3777
m->preLockState = MediumState_Inaccessible;
3763
if (uOpenFlags & (VD_OPEN_FLAGS_READONLY || VD_OPEN_FLAGS_SHAREABLE))
3764
rc = UnlockRead(NULL);
3780
if (uOpenFlags & (VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_SHAREABLE))
3781
rc2 = UnlockRead(NULL);
3783
rc2 = UnlockWrite(NULL);
3784
if (SUCCEEDED(rc) && FAILED(rc2))
3786
if (FAILED(rc)) return rc;
3788
/* If this is a base image which incorrectly has a parent UUID set,
3789
* repair the image now by zeroing the parent UUID. This is only done
3790
* when we have structural information from a config file, on import
3791
* this is not possible. If someone would accidentally call openMedium
3792
* with a diff image before the base is registered this would destroy
3793
* the diff. Not acceptable. */
3794
if (fRepairImageZeroParentUuid)
3796
rc = LockWrite(NULL);
3797
if (FAILED(rc)) return rc;
3804
vrc = VDCreate(m->vdDiskIfaces, &hdd);
3805
ComAssertRCThrow(vrc, E_FAIL);
3812
uOpenFlags & ~VD_OPEN_FLAGS_READONLY,
3814
if (RT_FAILURE(vrc))
3817
RTUUID zeroParentUuid;
3818
RTUuidClear(&zeroParentUuid);
3819
vrc = VDSetParentUuid(hdd, 0, &zeroParentUuid);
3820
ComAssertRCThrow(vrc, E_FAIL);
3766
3836
rc = UnlockWrite(NULL);
3767
if (FAILED(rc)) return rc;
3837
if (SUCCEEDED(rc) && FAILED(rc2))
3839
if (FAILED(rc)) return rc;
5012
5085
return VINF_SUCCESS;
5088
/** Wrapper for closing a connection as we always want a forceful shutdown. */
5089
DECLCALLBACK(int) Medium::vdTcpClientClose(RTSOCKET Sock)
5091
return RTTcpClientCloseEx(Sock, false /* fGracefulShutdown */);
5016
5096
* Starts a new thread driven by the appropriate Medium::Task::handler() method.