Browse Source

Ticket #502 - setup-ds.pl script should wait if "semanage.trans.LOCK" presen

Bug description: If multiple DSCreate or removeDSInstance run
simultaneously, semanage port fails because only one semanage
transaction is allowed to start.

Fix description: This patch puts "semanage port" in the while
loop and it retries until it succeeds or reaches the max retry
count (in total 5 minutes).

Reviewed by Mark (Thank you!!)
Noriko Hosoi 13 years ago
parent
commit
4999849d42
1 changed files with 44 additions and 10 deletions
  1. 44 10
      ldap/admin/src/scripts/DSCreate.pm.in

+ 44 - 10
ldap/admin/src/scripts/DSCreate.pm.in

@@ -553,7 +553,7 @@ sub installSchema {
         push @schemafiles, glob("$inf->{General}->{prefix}@schemadir@/*");
     } else {
         push @schemafiles, "$inf->{General}->{prefix}@schemadir@/00core.ldif",
-        	"$inf->{General}->{prefix}@schemadir@/01core389.ldif";
+            "$inf->{General}->{prefix}@schemadir@/01core389.ldif";
     }
 
     # additional schema files
@@ -1010,7 +1010,19 @@ sub updateSelinuxPolicy {
             }
 
             if ($need_label == 1) {
-                system("semanage port -a -t ldap_port_t -p tcp $inf->{slapd}->{ServerPort}");
+                my $semanage_err;
+                my $rc;
+                my $retry = 60;
+                while (($retry > 0) && ($semanage_err = `semanage port -a -t ldap_port_t -p tcp $inf->{slapd}->{ServerPort} 2>&1`) && ($rc = $?)) {
+                    debug(1, "Adding port $inf->{slapd}->{ServerPort} to selinux policy failed - $semanage_err (return code: $rc).\n");
+                    debug(1, "Retrying in 5 seconds\n");
+                    sleep(5);
+                    $retry--;
+                }
+                if (0 == $retry) {
+                    debug(1, "Adding port $inf->{slapd}->{ServerPort} to selinux policy failed - $semanage_err (return code: $rc).\n");
+                    debug(1, "Reached time limit.\n");
+                }
             }
         }
     }
@@ -1378,24 +1390,46 @@ sub removeDSInstance {
     if ("@with_selinux@") {
         foreach my $port (@{$entry->{"nsslapd-port"}}) 
         {
-            my $semanage_err = `semanage port -d -t ldap_port_t -p tcp $port 2>&1`;
-            if ($? != 0)  {
-                if (($semanage_err !~ /defined in policy, cannot be deleted/) && ($semanage_err !~ /is not defined/)) {
-                    push @errs, [ 'error_removing_port_label', $port, $semanage_err];
+            my $semanage_err;
+            my $rc;
+            my $retry = 60;
+            while (($retry > 0) && ($semanage_err = `semanage port -d -t ldap_port_t -p tcp $port 2>&1`) && ($rc = $?)) {
+                if (($semanage_err =~ /defined in policy, cannot be deleted/) || ($semanage_err =~ /is not defined/)) {
+                    $retry = -1;
+                } else {
                     debug(1, "Warning: Port $port not removed from selinux policy correctly.  Error: $semanage_err\n");
+                    debug(1, "Retrying in 5 seconds\n");
+                    sleep(5);
+                    $retry--;
                 }
             }
+            if (0 == $retry) {
+                push @errs, [ 'error_removing_port_label', $port, $semanage_err];
+                debug(1, "Warning: Port $port not removed from selinux policy correctly.  Error: $semanage_err\n");
+                debug(1, "Reached time limit.\n");
+            }
         }
 
         foreach my $secureport (@{$entry->{"nsslapd-secureport"}})
         {
-            my $semanage_err = `semanage port -d -t ldap_port_t -p tcp $secureport 2>&1`;
-            if ($? != 0)  {
-                if (($semanage_err !~ /defined in policy, cannot be deleted/) && ($semanage_err !~ /is not defined/)) {
-                    push @errs, [ 'error_removing_port_label', $secureport, $semanage_err];
+            my $semanage_err;
+            my $rc;
+            my $retry = 60;
+            while (($retry > 0) && ($semanage_err = `semanage port -d -t ldap_port_t -p tcp $secureport 2>&1`) && ($rc = $?)) {
+                if (($semanage_err =~ /defined in policy, cannot be deleted/) || ($semanage_err =~ /is not defined/)) {
+                    $retry = -1;
+                } else {
                     debug(1, "Warning: Port $secureport not removed from selinux policy correctly.  Error: $semanage_err\n");
+                    debug(1, "Retrying in 5 seconds\n");
+                    sleep(5);
+                    $retry--;
                 }
             }
+            if (0 == $retry) {
+                push @errs, [ 'error_removing_port_label', $secureport, $semanage_err];
+                debug(1, "Warning: Port $secureport not removed from selinux policy correctly.  Error: $semanage_err\n");
+                debug(1, "Reached time limit.\n");
+            }
         }
     }