summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMahesh Salgaonkar <mahesh@linux.vnet.ibm.com>2022-02-27 21:46:18 +0530
committerGitHub <noreply@github.com>2022-02-27 21:46:18 +0530
commitcf4c0ce74313643230c7cd21b07ad101f7ef7c77 (patch)
tree05a955ee266ee7dc4894f97022aa83c2592cc07f
parent10b4659a1e9f9ee76779f7b64e9abd85b8d48d1e (diff)
parent25e11c079194f410240c4d4dc7aae492d5b65130 (diff)
Merge pull request #3 from hramrach/master
Prevent corruption of database file when running vpdupdate
-rw-r--r--configure.ac4
-rw-r--r--src/internal/updater.cpp52
2 files changed, 29 insertions, 27 deletions
diff --git a/configure.ac b/configure.ac
index e9fc871..dc80e1e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -56,8 +56,8 @@ AC_CHECK_LIB(sgutils2,sg_lib_version, [SGUTILS_LIB="sgutils2"],[])
# exit 1 ])
AM_CONDITIONAL([SGUTIL1], [ test x$SGUTILS_LIB == xsgutils ])
AM_CONDITIONAL([SGUTIL2], [ test x$SGUTILS_LIB == xsgutils2 ])
-AC_CHECK_LIB(vpd,unpack_system,[],[
- echo "VPD library(libvpd) version 2 is required for lsvpd"
+PKG_CHECK_MODULES([LIBVPD2], [libvpd_cxx-2 >= 2.2.9],[],[
+ echo "VPD library(libvpd) version 2.2.9 is required for lsvpd"
exit 1])
AC_FUNC_CLOSEDIR_VOID
diff --git a/src/internal/updater.cpp b/src/internal/updater.cpp
index 391a6e6..d509cce 100644
--- a/src/internal/updater.cpp
+++ b/src/internal/updater.cpp
@@ -62,9 +62,9 @@ int storeComponents( System* root, VpdDbEnv& db );
int storeComponents( Component* root, VpdDbEnv& db );
void printUsage( );
void printVersion( );
-int ensureEnv( const string& env );
+int ensureEnv( const string& env, const string& file );
void archiveDB( const string& fullPath );
-int __lsvpdInit(string env, string file);
+int __lsvpdInit( VpdDbEnv::UpdateLock *lock );
void __lsvpdFini(void);
void lsvpdSighandler(int sig);
@@ -74,6 +74,7 @@ const string BASE( "/sys/bus" );
bool isRoot(void);
VpdDbEnv *db;
+VpdDbEnv::UpdateLock *dblock;
string env = DB_DIR, file = DB_FILENAME;
@@ -83,6 +84,7 @@ int main( int argc, char** argv )
bool done = false;
int index = 0, rc = 1;
bool limitSCSISize = false;
+ VpdDbEnv::UpdateLock *lock;
string platform = PlatformCollector::get_platform_name();
switch (PlatformCollector::platform_type) {
@@ -127,7 +129,9 @@ int main( int argc, char** argv )
return 0;
case 'a':
+ lock = new VpdDbEnv::UpdateLock(env, file, false);
archiveDB( env + '/' + file );
+ delete lock;
return 0;
case -1:
@@ -151,12 +155,9 @@ int main( int argc, char** argv )
l.log( "vpdupdate: Constructing full devices database", LOG_NOTICE );
rc = initializeDB( limitSCSISize );
- if (rc) {
- __lsvpdFini();
- return rc;
- }
__lsvpdFini();
+ return rc;
}
bool isRoot()
@@ -325,23 +326,28 @@ ZDONE:;
*/
int initializeDB( bool limitSCSI )
{
+ VpdDbEnv::UpdateLock *lock;
System * root;
int ret;
- if( ensureEnv( env ) != 0 )
+ if( ensureEnv( env, file ) != 0 )
return -1;
string fullPath = env + "/" + file;
+ lock = new VpdDbEnv::UpdateLock(env, file, false);
removeOldArchiveDB( );
archiveDB( fullPath );
+ /* The db is now archived so when signal handler runs it should remove
+ * any db it finds */
+ dblock = lock;
Gatherer info( limitSCSI );
- ret = __lsvpdInit(env, file);
+ ret = __lsvpdInit(lock);
if ( ret != 0 ) {
Logger l;
- l.log( " Could not allocate memory for the VPD database.", LOG_ERR);
+ l.log( "Could not allocate memory for the VPD database.", LOG_ERR);
return ret;
}
@@ -358,11 +364,10 @@ int initializeDB( bool limitSCSI )
{
Logger l;
l.log( "Saving components to database failed.", LOG_ERR );
- return ret;
}
delete root;
- return 0;
+ return ret;
}
/**
@@ -409,7 +414,7 @@ int storeComponents( System* root, VpdDbEnv& db )
return 0;
}
-int ensureEnv( const string& env )
+int ensureEnv( const string& env, const string& file )
{
struct stat info;
int ret = -1;
@@ -418,14 +423,14 @@ int ensureEnv( const string& env )
if( stat( env.c_str( ), &info ) == 0 )
{
if (!S_ISDIR(info.st_mode & S_IFMT)) {
- logger.log("/var/lib/lsvpd is not a directory\n", LOG_ERR);
+ logger.log(env + " is not a directory\n", LOG_ERR);
return ret;
}
if ( ((info.st_mode & S_IRWXU) != S_IRWXU) ||
((info.st_mode & S_IRGRP) != S_IRGRP) ||
((info.st_mode & S_IROTH) != S_IROTH) ) {
- logger.log("Failed to create vpd.db, no valid "
+ logger.log("Failed to create " + file + ", no valid "
"permission\n", LOG_ERR);
return ret;
}
@@ -438,7 +443,7 @@ int ensureEnv( const string& env )
return ret;
}
- if( ( ret = ensureEnv( env.substr( 0, idx ) ) ) != 0 )
+ if( ( ret = ensureEnv( env.substr( 0, idx ) , env.substr( idx + 1 ) ) ) != 0 )
{
return ret;
}
@@ -448,7 +453,7 @@ int ensureEnv( const string& env )
S_IRGRP | S_IWGRP | S_IXGRP |
S_IROTH | S_IXOTH ) != 0 )
{
- logger.log( "Failed to create directory for vpd db.", LOG_ERR );
+ logger.log( "Failed to create directory " + env + " for vpd db.", LOG_ERR );
return -1;
}
return ret;
@@ -458,7 +463,7 @@ int ensureEnv( const string& env )
* @brief initializes data base access, sets up signal handling
* to ensure proper cleanup if process if prematurely aborted
*/
-int __lsvpdInit(string env, string file)
+int __lsvpdInit( VpdDbEnv::UpdateLock *lock )
{
struct sigaction sigact;
@@ -475,7 +480,7 @@ int __lsvpdInit(string env, string file)
sigaction(SIGQUIT, &sigact, NULL);
sigaction(SIGTERM, &sigact, NULL);
- db = new VpdDbEnv( env, file, false );
+ db = new VpdDbEnv( *lock );
if ( db == NULL )
return -1;
else
@@ -491,6 +496,7 @@ void __lsvpdFini()
if (db != NULL) {
try {
delete db;
+ dblock = NULL;
} catch (VpdException & ve) { }
} /* if */
@@ -499,7 +505,6 @@ void __lsvpdFini()
void lsvpdSighandler(int sig)
{
- int fp;
struct sigaction sigact;
switch (sig) {
@@ -516,12 +521,9 @@ void lsvpdSighandler(int sig)
sigemptyset(&sigact.sa_mask);
sigaction(sig, &sigact, NULL);
- /* Remove temporary file */
- unlink((env + "/" + file).c_str());
- fp = open(env.c_str(), O_RDWR);
- if (fp >= 0) {
- fsync(fp);
- close(fp);
+ if (dblock != NULL) {
+ /* Remove temporary file */
+ unlink((env + "/" + file).c_str());
}
__lsvpdFini();