00001
00002
00003
00004
00005
00006
00007
00008
00012 #include "zypp/media/MediaISO.h"
00013 #include "zypp/base/Logger.h"
00014 #include "zypp/media/Mount.h"
00015
00016 #include <iostream>
00017
00019 namespace zypp
00020 {
00021
00023 namespace media
00024 {
00025
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00041 MediaISO::MediaISO(const Url &url_r,
00042 const Pathname &attach_point_hint_r)
00043 : MediaHandler(url_r, attach_point_hint_r,
00044 url_r.getPathName(),
00045 false)
00046 {
00047 MIL << "MediaISO::MediaISO(" << url_r << ", "
00048 << attach_point_hint_r << ")" << std::endl;
00049
00050 _isofile = _url.getQueryParam("iso");
00051 if( _isofile.empty())
00052 {
00053 ERR << "Media url does not contain iso filename" << std::endl;
00054 ZYPP_THROW(MediaBadUrlEmptyDestinationException(_url));
00055 }
00056
00057 _filesystem = _url.getQueryParam("filesystem");
00058 if( _filesystem.empty())
00059 _filesystem = "auto";
00060
00061 std::string arg;
00062 zypp::Url src;
00063 try
00064 {
00065 arg = _url.getQueryParam("url");
00066 if( arg.empty() && _isofile.dirname().absolute())
00067 {
00068 src = std::string("dir:///");
00069 src.setPathName(_isofile.dirname().asString());
00070 _isofile = _isofile.basename();
00071 }
00072 else
00073 {
00074 src = arg;
00075 }
00076 }
00077 catch(const zypp::url::UrlException &e)
00078 {
00079 ZYPP_CAUGHT(e);
00080 ERR << "Unable to parse iso filename source media url" << std::endl;
00081 ZYPP_THROW(MediaBadUrlException(_url));
00082 }
00083 if( !src.isValid())
00084 {
00085 ERR << "Invalid iso filename source media url" << std::endl;
00086 ZYPP_THROW(MediaBadUrlException(src));
00087 }
00088 if( src.getScheme() == "iso")
00089 {
00090 ERR << "ISO filename source media url with iso scheme (nested iso): "
00091 << src.asString() << std::endl;
00092 ZYPP_THROW(MediaUnsupportedUrlSchemeException(src));
00093 }
00094 #if 1
00095 else
00096 if( !(src.getScheme() == "hd" ||
00097 src.getScheme() == "dir" ||
00098 src.getScheme() == "file" ||
00099 src.getScheme() == "nfs" ||
00100 src.getScheme() == "smb" ||
00101 src.getScheme() == "cifs"))
00102 {
00103 ERR << "ISO filename source media url scheme is not supported: "
00104 << src.asString() << std::endl;
00105 ZYPP_THROW(MediaUnsupportedUrlSchemeException(src));
00106 }
00107 #endif
00108
00109 MediaManager manager;
00110
00111 _parentId = manager.open(src, _url.getQueryParam("mnt"));
00112 }
00113
00114
00115 MediaISO::~MediaISO()
00116 {
00117 try
00118 {
00119 release();
00120
00121 if( _parentId)
00122 {
00123 DBG << "Closing parent handler..." << std::endl;
00124 MediaManager manager;
00125 if(manager.isOpen(_parentId))
00126 manager.close(_parentId);
00127 _parentId = 0;
00128 }
00129 }
00130 catch( ... )
00131 {}
00132 }
00133
00134
00135 bool
00136 MediaISO::isAttached() const
00137 {
00138 return checkAttached(false);
00139 }
00140
00141
00142 void MediaISO::attachTo(bool next)
00143 {
00144 if(next)
00145 ZYPP_THROW(MediaNotSupportedException(_url));
00146
00147 MediaManager manager;
00148 manager.attach(_parentId, false);
00149
00150 try
00151 {
00152 manager.provideFile(_parentId, _isofile);
00153 }
00154 catch(const MediaException &e1)
00155 {
00156 ZYPP_CAUGHT(e1);
00157 try
00158 {
00159 manager.release(_parentId, false);
00160 }
00161 catch(const MediaException &e2)
00162 {
00163 ZYPP_CAUGHT(e2);
00164 }
00165 ZYPP_THROW(MediaMountException(
00166 "Unable to find iso filename on source media",
00167 _url.asString(), attachPoint().asString()
00168 ));
00169 }
00170
00171 Pathname isofile = manager.localPath(_parentId, _isofile);
00172 PathInfo isoinfo( isofile, PathInfo::LSTAT);
00173 if( !isoinfo.isFile())
00174 {
00175 ZYPP_THROW(MediaNotSupportedException(_url));
00176 }
00177
00178 MediaSourceRef media( new MediaSource(
00179 "iso", isofile.asString()
00180 ));
00181
00182 AttachedMedia ret( findAttachedMedia( media));
00183 if( ret.mediaSource &&
00184 ret.attachPoint &&
00185 !ret.attachPoint->empty())
00186 {
00187 DBG << "Using a shared media "
00188 << ret.mediaSource->name
00189 << " attached on "
00190 << ret.attachPoint->path
00191 << std::endl;
00192 removeAttachPoint();
00193 setAttachPoint(ret.attachPoint);
00194 setMediaSource(ret.mediaSource);
00195 return;
00196 }
00197
00198 std::string mountpoint = attachPoint().asString();
00199 if( !isUseableAttachPoint(attachPoint()))
00200 {
00201 mountpoint = createAttachPoint().asString();
00202 if( mountpoint.empty())
00203 ZYPP_THROW( MediaBadAttachPointException(url()));
00204 setAttachPoint( mountpoint, true);
00205 }
00206
00207 std::string mountopts("ro,loop");
00208
00209 Mount mount;
00210 mount.mount(isofile.asString(), mountpoint,
00211 _filesystem, mountopts);
00212
00213 setMediaSource(media);
00214
00215
00216
00217 int limit = 3;
00218 bool mountsucceeded;
00219 while( !(mountsucceeded=isAttached()) && --limit)
00220 {
00221 sleep(1);
00222 }
00223
00224 if( !mountsucceeded)
00225 {
00226 setMediaSource(MediaSourceRef());
00227 try
00228 {
00229 mount.umount(attachPoint().asString());
00230 manager.release(_parentId);
00231 }
00232 catch (const MediaException & excpt_r)
00233 {
00234 ZYPP_CAUGHT(excpt_r);
00235 }
00236 ZYPP_THROW(MediaMountException(isofile.asString(), mountpoint,
00237 "Unable to verify that the media was mounted"
00238 ));
00239 }
00240 }
00241
00242
00243 void MediaISO::releaseFrom(bool eject)
00244 {
00245 Mount mount;
00246 mount.umount(attachPoint().asString());
00247
00248 if( _parentId)
00249 {
00250 MediaManager manager;
00251 manager.release(_parentId);
00252 }
00253
00254
00255
00256 }
00257
00258
00259 void MediaISO::getFile(const Pathname &filename) const
00260 {
00261 MediaHandler::getFile(filename);
00262 }
00263
00264
00265 void MediaISO::getDir(const Pathname &dirname,
00266 bool recurse_r) const
00267 {
00268 MediaHandler::getDir(dirname, recurse_r);
00269 }
00270
00271
00272 void MediaISO::getDirInfo(std::list<std::string> &retlist,
00273 const Pathname &dirname,
00274 bool dots) const
00275 {
00276 MediaHandler::getDirInfo( retlist, dirname, dots );
00277 }
00278
00279
00280 void MediaISO::getDirInfo(filesystem::DirContent &retlist,
00281 const Pathname &dirname,
00282 bool dots) const
00283 {
00284 MediaHandler::getDirInfo(retlist, dirname, dots);
00285 }
00286
00287
00289 }
00291
00293 }
00295
00296
00297