r4141 getMessagesCount added. Returns unshown messages count by type
[racktables] / syncdomain.php
1 #!/usr/local/bin/php
2 <?php
3
4 $script_mode = TRUE;
5 require 'inc/init.php';
6
7 function usage()
8 {
9 echo "Usage: <this file> <options>\n";
10 echo "\t\t--vdid=<VLAN domain ID>\n";
11 echo "\t\t--mode=pull\n";
12 echo "\t\t--mode=pullall\n";
13 echo "\t\t--mode=push\n";
14 echo "\t\t[--max=<max_to_do>]\n";
15 echo "\t\t[--verbose]\n";
16 exit (1);
17 }
18
19 $options = getopt ('', array ('vdid:', 'max::', 'mode:', 'verbose'));
20 if (!array_key_exists ('vdid', $options) or !array_key_exists ('mode', $options))
21 usage();
22
23 switch ($options['mode'])
24 {
25 case 'pullall':
26 $do_push = FALSE;
27 break;
28 case 'pull':
29 $do_push = FALSE;
30 break;
31 case 'push':
32 $do_push = TRUE;
33 break;
34 default:
35 usage();
36 }
37
38 $max = array_key_exists ('max', $options) ? $options['max'] : 0;
39 $verbose = array_key_exists ('verbose', $options);
40
41 if (NULL === $mydomain = getVLANDomain ($options['vdid']))
42 {
43 echo "Cannot load domain data with ID ${options['vdid']}\n";
44 exit (1);
45 }
46
47 $todo = array
48 (
49 'pull' => array ('sync_ready', 'resync_ready'),
50 'push' => array ('sync_ready'),
51 'pullall' => array ('sync_ready', 'resync_ready', 'sync_aging', 'resync_aging', 'done'),
52 );
53
54 $filename = '/var/tmp/RackTables-syncdomain-' . $options['vdid'] . '.pid';
55 if (FALSE === $fp = @fopen ($filename, 'x+'))
56 {
57 if (FALSE === $pidfile_mtime = filemtime ($filename))
58 {
59 echo "Failed to obtain mtime of ${filename}\n";
60 exit (1);
61 }
62 $current_time = time();
63 if ($current_time < $pidfile_mtime)
64 {
65 echo "Warning: pidfile ${filename} mtime is in future!\n";
66 exit (1);
67 }
68 // don't indicate failure unless the pidfile is 15 minutes or more old
69 if ($current_time < $pidfile_mtime + 15 * 60)
70 exit (0);
71 echo "Failed to lock ${filename}, already locked by PID " . mb_substr (file_get_contents ($filename), 0, 6) . "\n";
72 exit (1);
73 }
74
75 ftruncate ($fp, 0);
76 fwrite ($fp, getmypid() . "\n");
77 fclose ($fp);
78
79 // fetch all the needed data from DB (preparing for DB connection loss)
80 $switch_queue = array();
81 foreach ($mydomain['switchlist'] as $switch)
82 if (in_array (detectVLANSwitchQueue (getVLANSwitchInfo ($switch['object_id'])), $todo[$options['mode']]))
83 $switch_queue[] = spotEntity ('object', $switch['object_id']);
84
85 // YOU SHOULD NOT USE DB FUNCTIONS BELOW IN THE PARENT PROCESS
86 // THE PARENT'S DB CONNECTION IS LOST DUE TO RECONNECTING IN THE CHILD
87 $fork_slots = getConfigVar ('SYNCDOMAIN_MAX_PROCESSES');
88 $do_fork = ($fork_slots > 1) and extension_loaded ('pcntl');
89 if ($fork_slots > 1 and ! $do_fork)
90 throw new RackTablesError ('PHP extension \'pcntl\' not found, can not use childs', RackTablesError::MISCONFIGURED);
91 $switches_working = 0;
92 $switchesdone = 0;
93 foreach ($switch_queue as $object)
94 {
95 if ($do_fork)
96 {
97 // wait for the next free slot
98 while ($fork_slots <= $switches_working)
99 {
100 pcntl_waitpid (-1, $wait_status);
101 --$switches_working;
102 }
103 $i_am_child = (0 === $fork_res = pcntl_fork());
104 }
105 if (! $do_fork or $i_am_child)
106 {
107 try
108 {
109 // make a separate DB connection for correct concurrent transactions handling
110 if ($i_am_child)
111 connectDB();
112 $portsdone = exec8021QDeploy ($object['id'], $do_push);
113 if ($portsdone or $verbose)
114 echo "Done '${object['dname']}': ${portsdone}\n";
115 }
116 catch (RackTablesError $e)
117 {
118 echo "FAILED '${object['dname']}': " . $e->getMessage() . "\n";
119 }
120 if ($i_am_child)
121 exit (0);
122 }
123 if (isset ($fork_res) and $fork_res > 0)
124 ++$switches_working;
125
126 if (++$switchesdone == $max)
127 {
128 if ($verbose)
129 echo "Maximum of ${max} items reached, terminating\n";
130 break;
131 }
132 }
133
134 // wait for all childs to exit
135 while ($switches_working > 0)
136 {
137 --$switches_working;
138 pcntl_waitpid (-1, $wait_status);
139 }
140
141 if (FALSE === unlink ($filename))
142 {
143 echo "Failed removing pidfile ${filename}\n";
144 exit (1);
145 }
146 exit (0);
147 ?>