in host/common/sun/portablehelpersminor.cpp [1686:1914]
bool MountDevice(const std::string& device,const std::string& mountPoint,const std::string& fsType,bool bSetReadOnly, int &exitCode,
std::string &errorMsg)
{
if ( mountPoint.empty())
{
std::stringstream strerr;
strerr << "Empty mountpoint specified.";
strerr << "Cannot mount device " << device << '\n';
DebugPrintf(SV_LOG_ERROR,"%s", strerr.str().c_str());
errorMsg = strerr.str();
return false;
}
std::string errmsg;
if(!IsValidMountPoint(mountPoint,errmsg))
{
std::stringstream strerr;
strerr << "Cannot mount device " << device << " on mount point " << mountPoint << ". " << errmsg << "\n";
DebugPrintf(SV_LOG_ERROR,"%s", strerr.str().c_str());
errorMsg = strerr.str();
return false;
}
if(SVMakeSureDirectoryPathExists(mountPoint.c_str()).failed())
{
std::stringstream strerr;
strerr << "Failed to create mount point directory " << mountPoint
<< '\n';
DebugPrintf(SV_LOG_ERROR,"%s", strerr.str().c_str());
errorMsg = strerr.str();
return false;
}
bool bCanMount = false;
bool remount = false;
std::string flag;
if(bSetReadOnly)
flag="ro ";
else
flag="rw ";
std::string sFileSystem = fsType;
if(sFileSystem == "")
{
/* NEEDTOASK:
* Linux handles this situation by specifying
* auto as the filesystem. There is not equivalent
* of auto in solaris. No manual page mentions about autofs
* being similar to auto filesystem type in linux.
* (linux manual page recommends against use of auto)
* and even if we mount using autofs, it gets mounted
* but ls on mountpoint hangs
* sFileSystem = "autofs"; */
std::stringstream strerr;
strerr << "The filesystem supplied to mount is empty.";
strerr << "Hence cannot mount device " << device << '\n';
DebugPrintf(SV_LOG_ERROR,"%s", strerr.str().c_str());
errorMsg = strerr.str();
return false;
}
std::string flags = flag; //This is used only in case of Uncomment FSTAB. flag gets updated with -o remount where as flags doesn't.
std::string sMount = "";
std::string mode;
if ( IsVolumeMounted(device,sMount,mode))
{
if ( sMount == mountPoint) //need to check if mode is same or not. If the mode is same, we will say already mounted, else we will do ewmount
{
if ("ufs" == sFileSystem)
{
bCanMount = true;
flag+="-o remount ";
}
else
{
std::stringstream strerr;
strerr << "the device " << device
<< " is already mounted on " << sMount << '\n';
DebugPrintf(SV_LOG_ERROR,"%s", strerr.str().c_str());
errorMsg = strerr.str();
return false;
}
}
else
{
bCanMount = false;
std::stringstream strerr;
strerr << "Failed to unhide volume "
<< "since already visible on mount point " << sMount
<< " and requested mount point is " << mountPoint << '\n';
DebugPrintf(SV_LOG_ERROR,"%s", strerr.str().c_str());
errorMsg = strerr.str();
return false;
}
}
else /* volume is not mounted */
{
bCanMount = true;
}
if ( bCanMount)
{
sFileSystem = ToLower(sFileSystem);
if(!strcmp(sFileSystem.c_str(),"fat32") ||
!strcmp(sFileSystem.c_str(),"fat") ||
!strcmp(sFileSystem.c_str(), "vfat"))
{
sFileSystem = "pcfs";
}
std::string fsmount;
/* mount -F pcfs -o rw special mntpoint */
fsmount += MOUNT_COMMAND;
fsmount += " ";
fsmount += OPTION_TO_SPECIFY_FILESYSTEM;
fsmount += " ";
fsmount += sFileSystem.c_str();
fsmount += " -o ";
fsmount += flag ;
fsmount += " ";
fsmount += device.c_str() ;
fsmount += " ";
fsmount += "\"";
fsmount += mountPoint.c_str() ;
fsmount += "\"";
DebugPrintf(SV_LOG_DEBUG, "@ LINE %d in FILE %s THE MOUNT COMMAND FORMED is %s\n", LINE_NO, FILE_NAME, fsmount.c_str());
std::string fsck_replay;
std::string fsck_full;
// For vxfs filesystems, we need to run fsck
// with log replay when trying to perform mount
// on a non frozen source image (ie without issuing a tag)
// log replay: fsck -F vxfs -y special
fsck_replay += FSCK_COMMAND;
fsck_replay += " ";
fsck_replay += FSCK_FS_OPTION ;
fsck_replay += " ";
fsck_replay += sFileSystem.c_str();
fsck_replay += " -y ";
fsck_replay += device.c_str() ;
// full fsck: fsck -F vxfs -y -o full,nolog special
fsck_full += FSCK_COMMAND;
fsck_full += " ";
fsck_full += FSCK_FS_OPTION ;
fsck_full += " ";
fsck_full += sFileSystem.c_str();
fsck_full += " -y ";
fsck_full += FSCK_FULL_OPTION ;
fsck_full += " ";
fsck_full += device.c_str() ;
if(flag!=flags)
remount=true;
int retriesformount = 0;
bool mounted = false;
bool fsck_replay_done = false;
bool fsck_full_done = false;
// fsck needs to be done only for vxfs when performing
// read write mount. in other cases, we will set
// fsck done as true so it does not get executed
if(bSetReadOnly || strcmp(sFileSystem.c_str(),"vxfs"))
{
fsck_replay_done = true;
fsck_full_done = true;
}
do
{
DebugPrintf(SV_LOG_INFO, "executing %s...\n", fsmount.c_str());
mounted = ExecuteInmCommand(fsmount, errorMsg, exitCode);
if (mounted)
{
return true;
}
else
{
DebugPrintf(SV_LOG_DEBUG,
"mount %s with filesystem %s failed on %s with error message = %s. Retrying again\n",
device.c_str(),sFileSystem.c_str(),mountPoint.c_str(), errorMsg.c_str());
}
retriesformount++;
if(!fsck_replay_done)
{
DebugPrintf(SV_LOG_INFO, "executing %s...\n", fsck_replay.c_str());
if(!ExecuteInmCommand(fsck_replay, errorMsg, exitCode))
{
DebugPrintf(SV_LOG_INFO,
"%s failed with exit code (%d) error message = %s.\n",
fsck_replay.c_str(), exitCode, errorMsg.c_str());
}
fsck_replay_done = true;
continue;
}
if(!fsck_full_done)
{
DebugPrintf(SV_LOG_INFO, "executing %s...\n", fsck_full.c_str());
if(!ExecuteInmCommand(fsck_full, errorMsg, exitCode))
{
DebugPrintf(SV_LOG_INFO,
"%s failed with exit code (%d) error message = %s.\n",
fsck_full.c_str(), exitCode, errorMsg.c_str());
}
fsck_full_done = true;
continue;
}
} while (retriesformount < RETRIES_FOR_MOUNT);
DebugPrintf(SV_LOG_ERROR,
"mount %s with filesystem %s failed on %s with error message = %s\n",
device.c_str(),sFileSystem.c_str(),mountPoint.c_str(), errorMsg.c_str());
return false;
}
return true;
}