Author: aschnell
Date: Sun Aug 3 16:09:24 2008
New Revision: 49604
URL: http://svn.opensuse.org/viewcvs/yast?rev=49604&view=rev
Log:
- implemented global lock for libstorage (fate #302971)
Added:
trunk/storage/libstorage/examples/TestLock.cc
trunk/storage/libstorage/src/Lock.cc
trunk/storage/libstorage/src/Lock.h
Modified:
trunk/storage/VERSION
trunk/storage/disk/src/disk_worker.ycp
trunk/storage/libstorage/examples/Makefile.am
trunk/storage/libstorage/examples/Makefile.example
trunk/storage/libstorage/src/Makefile.am
trunk/storage/libstorage/src/Storage.cc
trunk/storage/libstorage/src/Storage.h
trunk/storage/libstorage/src/StorageInterface.h
trunk/storage/package/yast2-storage.changes
trunk/storage/storage/src/modules/Storage.ycp
Modified: trunk/storage/VERSION
URL: http://svn.opensuse.org/viewcvs/yast/trunk/storage/VERSION?rev=49604&r1=49603&r2=49604&view=diff
==============================================================================
--- trunk/storage/VERSION (original)
+++ trunk/storage/VERSION Sun Aug 3 16:09:24 2008
@@ -1 +1 @@
-2.17.8
+2.17.9
Modified: trunk/storage/disk/src/disk_worker.ycp
URL: http://svn.opensuse.org/viewcvs/yast/trunk/storage/disk/src/disk_worker.ycp?rev=49604&r1=49603&r2=49604&view=diff
==============================================================================
--- trunk/storage/disk/src/disk_worker.ycp (original)
+++ trunk/storage/disk/src/disk_worker.ycp Sun Aug 3 16:09:24 2008
@@ -25,6 +25,9 @@
any DiskSequence()
{
+ if (!Storage::InitLibstorage(false))
+ return `abort;
+
Storage::SwitchUiAutomounter(false);
any ret = WFM::CallFunction("inst_disk", [ true, true ]);
Storage::SwitchUiAutomounter(true);
Modified: trunk/storage/libstorage/examples/Makefile.am
URL: http://svn.opensuse.org/viewcvs/yast/trunk/storage/libstorage/examples/Makefile.am?rev=49604&r1=49603&r2=49604&view=diff
==============================================================================
--- trunk/storage/libstorage/examples/Makefile.am (original)
+++ trunk/storage/libstorage/examples/Makefile.am Sun Aug 3 16:09:24 2008
@@ -9,7 +9,7 @@
AM_CXXFLAGS =
-noinst_PROGRAMS = TestDisk TestDiskLog TestStorage TestProbing TestLvm TestMd TestLoop
+noinst_PROGRAMS = TestDisk TestDiskLog TestStorage TestProbing TestLvm TestMd TestLoop TestLock
TestDisk_SOURCES = TestDisk.cc
@@ -25,6 +25,8 @@
TestLoop_SOURCES = TestLoop.cc
+TestLock_SOURCES = TestLock.cc
+
exampledir = $(docdir)/examples/libstorage
example_DATA = TestDisk.cc TestDiskLog.cc TestProbing.cc TestLvm.cc TestMd.cc TestLoop.cc
Modified: trunk/storage/libstorage/examples/Makefile.example
URL: http://svn.opensuse.org/viewcvs/yast/trunk/storage/libstorage/examples/Makefile.example?rev=49604&r1=49603&r2=49604&view=diff
==============================================================================
--- trunk/storage/libstorage/examples/Makefile.example (original)
+++ trunk/storage/libstorage/examples/Makefile.example Sun Aug 3 16:09:24 2008
@@ -1,9 +1,9 @@
-CXXFLAGS=-MMD -g -I /usr/include/YaST2
+CXXFLAGS = -MMD -g -I /usr/include/YaST2
LDFLAGS = -ly2storage
-PROG=TestDisk TestDiskLog TestProbing TestLvm TestMd TestLoop
+PROGRAMS = TestDisk TestDiskLog TestProbing TestLvm TestMd TestLoop
-all: $(PROG)
+all: $(PROGRAMS)
TestDisk: TestDisk.o
@@ -18,7 +18,7 @@
TestLoop: TestLoop.o
clean:
- rm -f *.d *.o $(PROG)
+ rm -f *.d *.o $(PROGRAMS)
ifneq "$(strip $(wildcard *.d))" ""
include $(wildcard *.d)
Added: trunk/storage/libstorage/examples/TestLock.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/storage/libstorage/examples/TestLock.cc?rev=49604&view=auto
==============================================================================
--- trunk/storage/libstorage/examples/TestLock.cc (added)
+++ trunk/storage/libstorage/examples/TestLock.cc Sun Aug 3 16:09:24 2008
@@ -0,0 +1,128 @@
+/*
+ * Author: Arvin Schnell
+ */
+
+
+#include
+#include <iostream>
+
+#include
+#include
+
+using namespace std;
+using namespace storage;
+
+
+const char* program_name;
+
+
+void help() __attribute__ ((__noreturn__));
+
+void
+help()
+{
+ cout << "Usage: " << program_name << " [OPTION]..." << endl
+ << endl
+ << "Mandatory arguments to long options are mandatory for short options too." << endl
+ << " -r, --rd get read-only lock (default)" << endl
+ << " -w, --wr get read-write lock" << endl
+ << endl
+ << " -s, --sleep=SECONDS sleep for SECONDS seconds after getting lock (30 seconds default)" << endl
+ << endl
+ << " -h, --help show this help" << endl;
+
+ exit(EXIT_SUCCESS);
+}
+
+
+void usage() __attribute__ ((__noreturn__));
+
+void
+usage()
+{
+ cerr << "Try " << program_name << " --help for more information." << endl;
+ exit(EXIT_FAILURE);
+}
+
+
+int
+main(int argc, char** argv)
+{
+ program_name = argv[0];
+
+ bool readonly = true;
+ int sleep = 30;
+
+ struct option long_options[] = {
+ { "rd", 0, 0, 'r' },
+ { "wr", 0, 0, 'w' },
+ { "sleep", 1, 0, 's' },
+ { "help", 0, 0, 'h' },
+ { 0, 0, 0, 0 }
+ };
+
+ while (true)
+ {
+ int c = getopt_long(argc, argv, "rws:h", long_options, 0);
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case 'r':
+ readonly = true;
+ break;
+
+ case 'w':
+ readonly = false;
+ break;
+
+ case 's':
+ sleep = atoi(optarg);
+ break;
+
+ case 'h':
+ help();
+
+ default:
+ usage();
+ }
+ }
+
+ if (optind < argc)
+ {
+ cerr << program_name << ": unrecognized option '" << argv[optind] << "'" << endl;
+ usage();
+ }
+
+ Storage::initDefaultLogger();
+
+ cout << "pid is " << getpid() << endl;
+
+ Lock* lock = NULL;
+
+ try
+ {
+ lock = new Lock(readonly);
+ }
+ catch (LockException& e)
+ {
+ cerr << "lock failed" << endl;
+ cerr << "locker-pid is " << e.GetLockerPid() << endl;
+ exit(EXIT_FAILURE);
+ }
+
+ cout << "lock (" << (readonly ? "read-only" : "read-write") << ") succeeded" << endl;
+
+ if (sleep > 0)
+ {
+ cout << "(sleeping for " << sleep << " seconds)" << endl;
+ ::sleep(sleep);
+ }
+
+ cout << "releasing lock" << endl;
+
+ delete lock;
+
+ exit(EXIT_SUCCESS);
+}
Added: trunk/storage/libstorage/src/Lock.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/storage/libstorage/src/Lock.cc?rev=49604&view=auto
==============================================================================
--- trunk/storage/libstorage/src/Lock.cc (added)
+++ trunk/storage/libstorage/src/Lock.cc Sun Aug 3 16:09:24 2008
@@ -0,0 +1,81 @@
+/*
+ * Author: Arvin Schnell
+ */
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "y2storage/AppUtil.h"
+#include "y2storage/Lock.h"
+
+
+namespace storage
+{
+
+ LockException::LockException(pid_t locker_pid)
+ : locker_pid(locker_pid)
+ {
+ }
+
+
+ LockException::~LockException() throw()
+ {
+ }
+
+
+ Lock::Lock(bool readonly)
+ : fd(-1)
+ {
+ y2mil("getting " << (readonly ? "read-only" : "read-write") << " lock");
+
+ // TODO filename
+ fd = open("/tmp/lock-test", (readonly ? O_RDONLY : O_WRONLY) | O_CREAT,
+ S_IRUSR | S_IWUSR);
+ if (fd < 0)
+ {
+ // Opening lock-file failed.
+ y2err("opening lock-file failed: " << strerror(errno));
+ throw(LockException(0));
+ }
+
+ struct flock lock;
+ memset(&lock, 0, sizeof(lock));
+ lock.l_whence = SEEK_SET;
+ lock.l_type = (readonly ? F_RDLCK : F_WRLCK);
+ if (fcntl(fd, F_SETLK, &lock) < 0)
+ {
+ switch (errno)
+ {
+ case EACCES:
+ case EAGAIN:
+ // Another process has a lock. Between the two fcntl
+ // calls the lock of the other process could be
+ // release. In that case we don't get the pid (and it is
+ // still 0).
+ fcntl(fd, F_GETLK, &lock);
+ y2err("locked by process " << lock.l_pid);
+ throw(LockException(lock.l_pid));
+
+ default:
+ // Some other error.
+ y2err("getting lock failed: " << strerror(errno));
+ throw(LockException(0));
+ }
+ }
+
+ y2mil("lock succeeded");
+ }
+
+
+ Lock::~Lock() throw()
+ {
+ y2mil("releasing lock");
+ close(fd);
+ }
+
+}
Added: trunk/storage/libstorage/src/Lock.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/storage/libstorage/src/Lock.h?rev=49604&view=auto
==============================================================================
--- trunk/storage/libstorage/src/Lock.h (added)
+++ trunk/storage/libstorage/src/Lock.h Sun Aug 3 16:09:24 2008
@@ -0,0 +1,52 @@
+#ifndef LOCK_H
+#define LOCK_H
+
+
+/*
+ * Author: Arvin Schnell
+ */
+
+
+#include <stdexcept>
+#include
+
+
+namespace storage
+{
+
+ class LockException : public std::exception
+ {
+
+ public:
+
+ LockException(pid_t locker_pid);
+ virtual ~LockException() throw();
+
+ pid_t GetLockerPid() const { return locker_pid; }
+
+ protected:
+
+ pid_t locker_pid;
+
+ };
+
+ /**
+ * Implement a global read-only or read-write lock.
+ */
+ class Lock : boost::noncopyable
+ {
+
+ public:
+
+ Lock(bool readonly);
+ ~Lock() throw();
+
+ private:
+
+ int fd;
+
+ };
+}
+
+
+#endif
Modified: trunk/storage/libstorage/src/Makefile.am
URL: http://svn.opensuse.org/viewcvs/yast/trunk/storage/libstorage/src/Makefile.am?rev=49604&r1=49603&r2=49604&view=diff
==============================================================================
--- trunk/storage/libstorage/src/Makefile.am (original)
+++ trunk/storage/libstorage/src/Makefile.am Sun Aug 3 16:09:24 2008
@@ -55,6 +55,7 @@
ProcMounts.cc ProcMounts.h \
EtcFstab.cc EtcFstab.h \
AppUtil.cc AppUtil.h \
+ Lock.cc Lock.h \
StorageTypes.cc StorageTypes.h \
FilterIterator.h ListListIterator.h \
DerefIterator.h IterPair.h \
Modified: trunk/storage/libstorage/src/Storage.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/storage/libstorage/src/Storage.cc?rev=49604&r1=49603&r2=49604&view=diff
==============================================================================
--- trunk/storage/libstorage/src/Storage.cc (original)
+++ trunk/storage/libstorage/src/Storage.cc Sun Aug 3 16:09:24 2008
@@ -73,9 +73,10 @@
}
-Storage::Storage( bool ronly, bool tmode, bool autodetec ) :
- readonly(ronly), testmode(tmode), initialized(false), autodetect(autodetec)
- {
+Storage::Storage( bool ronly, bool tmode, bool autodetec )
+ : lock(ronly), readonly(ronly), testmode(tmode), initialized(false),
+ autodetect(autodetec)
+{
y2milestone( "constructed Storage ronly:%d testmode:%d autodetect:%d",
ronly, testmode, autodetect );
y2milestone( "package string \"%s\"", PACKAGE_STRING );
@@ -1046,6 +1047,27 @@
return new Storage (ronly, testmode, autodetect);
}
+ StorageInterface* createStorageInterfacePid (bool ronly, bool testmode, bool autodetect,
+ pid_t& locker_pid)
+ {
+ try
+ {
+ return new Storage (ronly, testmode, autodetect);
+ }
+ catch (LockException& e)
+ {
+ locker_pid = e.GetLockerPid();
+ y2mil("returning NULL");
+ return NULL;
+ }
+ catch (...)
+ {
+ locker_pid = 0;
+ y2mil("returning NULL");
+ return NULL;
+ }
+ }
+
void destroyStorageInterface (StorageInterface* p)
{
delete p;
Modified: trunk/storage/libstorage/src/Storage.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/storage/libstorage/src/Storage.h?rev=49604&r1=49603&r2=49604&view=diff
==============================================================================
--- trunk/storage/libstorage/src/Storage.h (original)
+++ trunk/storage/libstorage/src/Storage.h Sun Aug 3 16:09:24 2008
@@ -29,6 +29,7 @@
#include "y2storage/DerefIterator.h"
#include "y2storage/ListListIterator.h"
#include "y2storage/IterPair.h"
+#include "y2storage/Lock.h"
namespace storage
{
@@ -1720,6 +1721,7 @@
bool& resize_ok );
// protected internal member variables
+ Lock lock;
bool readonly;
bool testmode;
bool inst_sys;
Modified: trunk/storage/libstorage/src/StorageInterface.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/storage/libstorage/src/StorageInterface.h?rev=49604&r1=49603&r2=49604&view=diff
==============================================================================
--- trunk/storage/libstorage/src/StorageInterface.h (original)
+++ trunk/storage/libstorage/src/StorageInterface.h Sun Aug 3 16:09:24 2008
@@ -2251,18 +2251,33 @@
/**
* Factory for creating a concrete StorageInterface object.
+ *
+ * Throws an exception when locking fails.
*/
StorageInterface* createDefaultStorageInterface ();
/**
* Factory for creating a concrete StorageInterface object.
+ *
+ * Throws an exception when locking fails.
*/
StorageInterface* createStorageInterface (bool readonly, bool testmode,
bool autodetect);
/**
+ * Factory for creating a concrete StorageInterface object.
+ *
+ * Returns NULL if locking failed. In that case locker_pid is set to the
+ * pid of one process holding a conflicting lock. If the pid cannot be
+ * determined it is set to 0. The lock holder may run on another system.
+ */
+ StorageInterface* createStorageInterfacePid (bool readonly, bool testmode,
+ bool autodetect, int& locker_pid);
+
+
+ /**
* Destroy a StorageInterface object.
*/
void destroyStorageInterface (StorageInterface*);
Modified: trunk/storage/package/yast2-storage.changes
URL: http://svn.opensuse.org/viewcvs/yast/trunk/storage/package/yast2-storage.changes?rev=49604&r1=49603&r2=49604&view=diff
==============================================================================
--- trunk/storage/package/yast2-storage.changes (original)
+++ trunk/storage/package/yast2-storage.changes Sun Aug 3 16:09:24 2008
@@ -1,4 +1,10 @@
-------------------------------------------------------------------
+Sun Aug 03 16:01:46 CEST 2008 - aschnell@suse.de
+
+- implemented global lock for libstorage (fate #302971)
+- version 2.17.9
+
+-------------------------------------------------------------------
Fri Aug 01 10:42:52 CEST 2008 - aschnell@suse.de
- redesigned expert partitioner (fate #302054)
Modified: trunk/storage/storage/src/modules/Storage.ycp
URL: http://svn.opensuse.org/viewcvs/yast/trunk/storage/storage/src/modules/Storage.ycp?rev=49604&r1=49603&r2=49604&view=diff
==============================================================================
--- trunk/storage/storage/src/modules/Storage.ycp (original)
+++ trunk/storage/storage/src/modules/Storage.ycp Sun Aug 3 16:09:24 2008
@@ -247,7 +247,6 @@
]
*/
- global boolean ZeroNewPartitions = false;
map StorageMap = $[];
map StorageMaps = $[];
@@ -282,40 +281,56 @@
any sint = nil;
list<map> conts = [];
-define any createInterface()
+
+any CreateInterface(boolean readonly)
+{
+ while (sint == nil)
{
- any ret = LibStorage::createStorageInterface(false, Mode::test(), true);
- if( ZeroNewPartitions )
- LibStorage::StorageInterface::setZeroNewPartitions(ret,true);
+ integer locker_pid = 0;
+ sint = LibStorage::createStorageInterfacePid(readonly, Mode::test(), true, locker_pid);
+ y2milestone("sint:%1", sint);
- return( ret );
+ if (sint == nil)
+ {
+ y2milestone("locker_pid:%1", locker_pid);
+
+ // TODO
+
+ if (!Popup::YesNo("Retry TODO"))
+ break;
+ }
}
+ y2milestone("sint:%1", sint);
+ return sint;
+}
+
+
list<map> getContainers();
-global define void InitLibstorage()
+global boolean InitLibstorage(boolean readonly)
+{
+ if (sint != nil)
+ return true;
+
+ y2milestone("InitLibstorage");
+ sint = CreateInterface(readonly);
+ if (sint == nil)
+ return false;
+
+ if (Stage::initial())
{
- if( sint==nil )
- {
- y2milestone( "InitLibstorage" );
- sint = createInterface();
- boolean evco = ProductFeatures::GetBooleanFeature( "partitioning",
- "evms_config" );
- y2milestone( "InitLibstorage evco %1", evco );
- if( evco!=nil && !evco )
- LibStorage::StorageInterface::setNoEvms(sint,true);
- if( Stage::initial() )
- {
- LibStorage::StorageInterface::setDetectMountedVolumes(sint,false);
- LibStorage::StorageInterface::setRootPrefix( sint,
- Installation::destdir );
- }
- conts = getContainers();
- y2milestone( "InitLibstorage conts:%1", conts );
- FileSystems::InitSlib( sint );
- }
+ LibStorage::StorageInterface::setDetectMountedVolumes(sint, false);
+ LibStorage::StorageInterface::setRootPrefix(sint, Installation::destdir);
}
+ conts = getContainers();
+ y2milestone("InitLibstorage conts:%1", conts);
+ FileSystems::InitSlib(sint);
+
+ return true;
+}
+
global string ByteToHumanString(integer bytes)
{
@@ -1296,7 +1311,8 @@
global define boolean CheckBackupState( string who )
{
y2milestone( "CheckBackupStates who:%1", who );
- InitLibstorage();
+ if (!InitLibstorage(false))
+ return nil;
boolean ret = LibStorage::StorageInterface::checkBackupState( sint, who );
y2milestone( "CheckBackupStates ret:%1", ret );
return( ret );
@@ -3674,7 +3690,8 @@
global void RemoveDmMapsTo( string device )
{
y2milestone( "RemoveDmMapsTo device:%1", device );
- InitLibstorage();
+ if (!InitLibstorage(false))
+ return;
LibStorage::StorageInterface::removeDmTableTo( sint, device );
}
@@ -3742,11 +3759,13 @@
* ... ?
* ]
*/
-global define map GetTargetMap()
- ``{
+global map GetTargetMap()
+{
+ if (!InitLibstorage(false))
+ return nil;
+
map tmp = $[];
boolean changed = false;
- InitLibstorage();
if( !probe_done && !Mode::config() )
{
map bios_id_raid = $[];
@@ -4054,17 +4073,20 @@
*
* @see GetTargetMap();
*/
-global define map ReReadTargetMap()
- ``{
- y2milestone("start reread sint:%1", sint );
+global map ReReadTargetMap()
+{
+ boolean need_reread = sint != nil;
+
+ if (!InitLibstorage(false))
+ return nil;
+
+ y2milestone("start reread need_reread:%1", need_reread);
probe_done = false;
- if( sint == nil )
- InitLibstorage();
- else
- LibStorage::StorageInterface::rescanEverything( sint );
+ if (need_reread)
+ LibStorage::StorageInterface::rescanEverything(sint);
conts = getContainers();
return GetTargetMap();
- };
+}
/**
* Apply storage changes
@@ -7009,11 +7031,12 @@
}
global void DumpObjectList()
- {
- if( sint == nil )
- InitLibstorage();
+{
+ if (!InitLibstorage(false))
+ return;
+
LibStorage::StorageInterface::dumpObjectList(sint);
- }
+}
global define list<string> NoProposeDisks()
{
@@ -7111,14 +7134,16 @@
}
global string GetUsedFs()
- {
- InitLibstorage();
+{
+ if (!InitLibstorage(false))
+ return nil;
+
string r = LibStorage::StorageInterface::getAllUsedFs( sint );
list<string> lr = sort(splitstring(r," \t"));
r = mergestring( lr, " " );
y2milestone( "GetUsedFs ret:%1", r );
return( r );
- }
+}
list FindUsedFsLine( map file )
{
--
To unsubscribe, e-mail: yast-commit+unsubscribe@opensuse.org
For additional commands, e-mail: yast-commit+help@opensuse.org