line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Flexnet::lmutil; |
2
|
|
|
|
|
|
|
|
3
|
2
|
|
|
2
|
|
56382
|
use 5.006; |
|
2
|
|
|
|
|
9
|
|
4
|
2
|
|
|
2
|
|
12
|
use strict; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
46
|
|
5
|
2
|
|
|
2
|
|
10
|
use warnings; |
|
2
|
|
|
|
|
7
|
|
|
2
|
|
|
|
|
74
|
|
6
|
2
|
|
|
2
|
|
1730
|
use File::Which; |
|
2
|
|
|
|
|
2115
|
|
|
2
|
|
|
|
|
5167
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
=head1 NAME |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
Flexnet::lmutil - Convenient OO-interface for Flexnet license server utility lmutil |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
=head1 VERSION |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
Version 1.4 |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
=cut |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
our $VERSION = '1.4'; |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
=head1 DESCRIPTION |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
Flexnet::lmutil is a small wrapper around the Flexnet license server utility lmutil, |
23
|
|
|
|
|
|
|
currently implementing the sub-functions lmstat and lmremove. The module parses the |
24
|
|
|
|
|
|
|
output of lmstat and returns an easy-to-use data structure. This makes it easy to |
25
|
|
|
|
|
|
|
work further with lmstat output for e.g. web pages, monitoring plugins etc. |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
=head1 SYNOPSIS |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
use Flexnet::lmutil; |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
my $lmutil = new Flexnet::lmutil ( |
33
|
|
|
|
|
|
|
lm_license_path => 'port@host', |
34
|
|
|
|
|
|
|
... |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
); |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
$status = $lmutil->lmstat ( |
39
|
|
|
|
|
|
|
feature => 'feature', |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
OR |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
daemon => 'daemon', |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
OR |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
'all' |
48
|
|
|
|
|
|
|
); |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
$lmutil->lmremove ( |
51
|
|
|
|
|
|
|
feature => 'feature', |
52
|
|
|
|
|
|
|
serverhost => 'host', |
53
|
|
|
|
|
|
|
port => 'port', |
54
|
|
|
|
|
|
|
handle => 'handle' |
55
|
|
|
|
|
|
|
); |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
=head1 DETAILS |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
=over 1 |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
=item new |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
Possible arguments for the constructor are: |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
=over 4 |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
=item C |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
either the full pathname of the license file or the string C |
70
|
|
|
|
|
|
|
or even C... |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
=item C |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
show command line call |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
=item C |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
textfile containing lmstat output (for testing), does not run lmstat |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
=back |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
=item lmstat |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
Possible arguments for C are: |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
=over 4 |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
=item C |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
get info about feature usage |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
=item C |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
get info about daemon usage |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
=item C |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
get info about usage of all daemons and features |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
=back |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
C returns a hash reference with the following keys: |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
=over 4 |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
=item * C |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=item * C |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
=item * C |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
=back |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
B points to another structure like |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
'server' => { |
117
|
|
|
|
|
|
|
'elba.uni-paderborn.de' => { |
118
|
|
|
|
|
|
|
'ok' => 1, |
119
|
|
|
|
|
|
|
'status' => 'UP' |
120
|
|
|
|
|
|
|
} |
121
|
|
|
|
|
|
|
}, |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
B points to a structure like |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
'vendor' => { |
126
|
|
|
|
|
|
|
'cdslmd' => { |
127
|
|
|
|
|
|
|
'ok' => 1, |
128
|
|
|
|
|
|
|
'status' => 'UP v11.11', |
129
|
|
|
|
|
|
|
'version' => '11.11' |
130
|
|
|
|
|
|
|
} |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
B points to a structure like |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
'feature' => { |
136
|
|
|
|
|
|
|
'MATLAB' => { |
137
|
|
|
|
|
|
|
'reservations' => [ |
138
|
|
|
|
|
|
|
{ |
139
|
|
|
|
|
|
|
'reservations' => '1', |
140
|
|
|
|
|
|
|
'group' => 'etechnik-labor', |
141
|
|
|
|
|
|
|
'type' => 'HOST_GROUP' |
142
|
|
|
|
|
|
|
} |
143
|
|
|
|
|
|
|
], |
144
|
|
|
|
|
|
|
'issued' => '115', |
145
|
|
|
|
|
|
|
'used' => '36', |
146
|
|
|
|
|
|
|
'users' => [ |
147
|
|
|
|
|
|
|
{ |
148
|
|
|
|
|
|
|
'serverhost' => 'dabu.uni-paderborn.de', |
149
|
|
|
|
|
|
|
'startdate' => 'Wed 8/12 17:18', |
150
|
|
|
|
|
|
|
'port' => '27000', |
151
|
|
|
|
|
|
|
'licenses' => 1, |
152
|
|
|
|
|
|
|
'display' => 'bessel', |
153
|
|
|
|
|
|
|
'host' => 'bessel', |
154
|
|
|
|
|
|
|
'handle' => '4401', |
155
|
|
|
|
|
|
|
'user' => 'hangmann' |
156
|
|
|
|
|
|
|
}, |
157
|
|
|
|
|
|
|
] |
158
|
|
|
|
|
|
|
}, |
159
|
|
|
|
|
|
|
}, |
160
|
|
|
|
|
|
|
... |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
=item lmremove |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
The C method expects the following arguments as a hash: |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
feature => 'feature', |
167
|
|
|
|
|
|
|
serverhost => 'host', |
168
|
|
|
|
|
|
|
port => 'port', |
169
|
|
|
|
|
|
|
handle => 'handle' |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
=back |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
=head1 AUTHOR |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
Christopher Odenbach, C<< >> |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
=head1 BUGS |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
Please report any bugs or feature requests to C, or through |
180
|
|
|
|
|
|
|
the web interface at L. I will be notified, and then you'll |
181
|
|
|
|
|
|
|
automatically be notified of progress on your bug as I make changes. |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
=head1 SUPPORT |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command. |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
perldoc Flexnet::lmutil |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
You can also look for information at: |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
=over 4 |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
=item * RT: CPAN's request tracker (report bugs here) |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
L |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
=item * AnnoCPAN: Annotated CPAN documentation |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
L |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
=item * CPAN Ratings |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
L |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
=item * Search CPAN |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
L |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
=back |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
=head1 ACKNOWLEDGEMENTS |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
=head1 LICENSE AND COPYRIGHT |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
Copyright 2015 Christopher Odenbach. |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it |
224
|
|
|
|
|
|
|
under the terms of either: the GNU General Public License as published |
225
|
|
|
|
|
|
|
by the Free Software Foundation; or the Artistic License. |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
See http://dev.perl.org/licenses/ for more information. |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
=cut |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
sub new { |
233
|
1
|
|
|
1
|
1
|
14
|
my $pkg = shift; |
234
|
1
|
|
|
|
|
6
|
my %args = @_; |
235
|
|
|
|
|
|
|
|
236
|
1
|
|
50
|
|
|
12
|
my $lmutil = ($args{lmutil} or which ('lmutil') or ''); |
237
|
|
|
|
|
|
|
|
238
|
1
|
0
|
33
|
|
|
454
|
if (not defined $args{testfile} and not -x $lmutil ) { |
239
|
0
|
|
|
|
|
0
|
die "lmutil not executable\n"; |
240
|
|
|
|
|
|
|
} |
241
|
|
|
|
|
|
|
|
242
|
1
|
|
|
|
|
6
|
my $self = { |
243
|
|
|
|
|
|
|
lmutil => $lmutil, |
244
|
|
|
|
|
|
|
%args |
245
|
|
|
|
|
|
|
}; |
246
|
1
|
|
|
|
|
7
|
return bless ($self, $pkg); |
247
|
|
|
|
|
|
|
} |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
sub lmstat { |
250
|
1
|
|
|
1
|
1
|
7
|
my $self = shift; |
251
|
|
|
|
|
|
|
|
252
|
1
|
|
|
|
|
2
|
my @args = @_; |
253
|
|
|
|
|
|
|
|
254
|
1
|
50
|
|
|
|
8
|
if (@args == 1) { |
255
|
1
|
|
|
|
|
3
|
push @args, 1; |
256
|
|
|
|
|
|
|
} |
257
|
1
|
|
|
|
|
4
|
my %args = @args; |
258
|
|
|
|
|
|
|
|
259
|
1
|
|
|
|
|
2
|
my ($feature, $status); |
260
|
|
|
|
|
|
|
|
261
|
1
|
|
|
|
|
7
|
my $cmd = "$self->{lmutil} lmstat"; |
262
|
|
|
|
|
|
|
|
263
|
1
|
50
|
|
|
|
5
|
if ( defined ($self->{lm_license_path})) { |
264
|
0
|
|
|
|
|
0
|
$cmd .= " -c $self->{lm_license_path}"; |
265
|
|
|
|
|
|
|
} |
266
|
|
|
|
|
|
|
|
267
|
1
|
50
|
|
|
|
3
|
if ( defined ($args{all}) ) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
268
|
1
|
|
|
|
|
4
|
$cmd .= " -a"; |
269
|
|
|
|
|
|
|
} elsif ( defined ($args{feature}) ) { |
270
|
0
|
|
|
|
|
0
|
$cmd .= " -f $args{feature}"; |
271
|
|
|
|
|
|
|
} elsif ( defined ($args{daemon}) ) { |
272
|
0
|
|
|
|
|
0
|
$cmd .= " -S $args{daemon}"; |
273
|
|
|
|
|
|
|
} |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
# for testing purpose we can provide a text file with the output of lmstat |
276
|
1
|
|
|
|
|
1
|
my $fh; |
277
|
1
|
50
|
|
|
|
4
|
if ( defined ($self->{testfile}) ) { |
278
|
1
|
50
|
|
|
|
40
|
open ($fh, $self->{testfile}) or die "Could not open $self->{testfile}: $!"; |
279
|
|
|
|
|
|
|
} else { |
280
|
0
|
0
|
|
|
|
0
|
print "Running command: $cmd\n" if $self->{verbose}; |
281
|
0
|
|
|
|
|
0
|
open ($fh, "$cmd |"); |
282
|
|
|
|
|
|
|
} |
283
|
|
|
|
|
|
|
|
284
|
1
|
|
|
|
|
28
|
while (<$fh>) { |
285
|
98
|
50
|
|
|
|
244
|
print "lmstat: $_" if $self->{verbose}; |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
# lmgrd status |
288
|
98
|
100
|
|
|
|
1043
|
if ( my ($server, $server_status) = /^\s*([\w.-]+): license server (\S+)/ ) { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
289
|
1
|
|
|
|
|
6
|
$status->{server}->{$server}->{status} = $server_status; |
290
|
1
|
50
|
|
|
|
5
|
if ( $server_status eq "UP" ) { |
291
|
1
|
|
|
|
|
12
|
$status->{server}->{$server}->{ok} = 1; |
292
|
|
|
|
|
|
|
} else { |
293
|
0
|
|
|
|
|
0
|
$status->{server}->{$server}->{ok} = 0; |
294
|
|
|
|
|
|
|
} |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
# vendor daemon status |
297
|
|
|
|
|
|
|
} elsif ( my ($vendor, $state) = /^\s*(\S+?): (.*)/ ) { |
298
|
3
|
|
|
|
|
12
|
$status->{vendor}->{$vendor}->{status} = $state; |
299
|
3
|
50
|
|
|
|
13
|
if ( $state =~ /^UP v([\d.]+)/ ) { |
300
|
3
|
|
|
|
|
10
|
$status->{vendor}->{$vendor}->{ok} = 1; |
301
|
3
|
|
|
|
|
25
|
$status->{vendor}->{$vendor}->{version} = $1; |
302
|
|
|
|
|
|
|
} else { |
303
|
0
|
|
|
|
|
0
|
$status->{vendor}->{$vendor}->{ok} = 0; |
304
|
|
|
|
|
|
|
} |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
# feature usage info |
307
|
|
|
|
|
|
|
} elsif ( /^Users of (\S+):\s*\(Total of (\d+) licenses? issued;\s*Total of (\d+) lic/ ) { |
308
|
11
|
|
|
|
|
24
|
$feature = $1; |
309
|
11
|
|
|
|
|
19
|
my $issued = $2; |
310
|
11
|
|
|
|
|
18
|
my $used = $3; |
311
|
11
|
|
|
|
|
36
|
$status->{feature}->{$feature}->{issued} = $issued; |
312
|
11
|
|
|
|
|
72
|
$status->{feature}->{$feature}->{used} = $used; |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
# user info |
315
|
|
|
|
|
|
|
} elsif ( my ($clientinfo, $version, $serverhost, $port, $handle, $rest) = |
316
|
|
|
|
|
|
|
m{^\s+(.+) \(v([\d\.]+)\) \(([^/]+)/(\d+) (\d+)\), start (.*)} ) { |
317
|
|
|
|
|
|
|
|
318
|
36
|
|
|
|
|
54
|
my ($user, $host); |
319
|
36
|
|
|
|
|
50
|
my $display = ''; |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
# split clientinfo |
322
|
|
|
|
|
|
|
|
323
|
36
|
|
|
|
|
89
|
my @parts = split / /, $clientinfo; |
324
|
36
|
100
|
|
|
|
103
|
if (@parts == 2) { |
|
|
100
|
|
|
|
|
|
325
|
4
|
|
|
|
|
8
|
($user, $host) = @parts; |
326
|
|
|
|
|
|
|
} elsif (@parts == 3) { |
327
|
28
|
|
|
|
|
52
|
($user, $host, $display) = @parts; |
328
|
|
|
|
|
|
|
} else { |
329
|
4
|
|
|
|
|
6
|
my $max = @parts; |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
# host = display? |
332
|
4
|
100
|
|
|
|
13
|
if ($parts[$max - 2] eq $parts[$max - 1]) { |
333
|
1
|
|
|
|
|
2
|
$display = pop @parts; |
334
|
1
|
|
|
|
|
2
|
$host = pop @parts; |
335
|
1
|
|
|
|
|
3
|
$user = join (' ', @parts); |
336
|
|
|
|
|
|
|
} else { |
337
|
|
|
|
|
|
|
# display contains / or : ? |
338
|
3
|
|
|
|
|
4
|
my $i = 2; |
339
|
3
|
|
|
|
|
10
|
while ($i <= @parts) { |
340
|
3
|
50
|
|
|
|
12
|
if ($parts[$i] =~ m{^[:/]}) { |
341
|
3
|
|
|
|
|
4
|
$display = $parts[$i]; |
342
|
3
|
|
|
|
|
4
|
$host = $parts[$i - 1]; |
343
|
3
|
|
|
|
|
9
|
$user = join (' ', map { $parts[$_] } 0..$i-2); |
|
3
|
|
|
|
|
10
|
|
344
|
3
|
|
|
|
|
6
|
last; |
345
|
|
|
|
|
|
|
} |
346
|
0
|
|
|
|
|
0
|
$i++; |
347
|
|
|
|
|
|
|
} |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
# if still no luck, just guess |
350
|
3
|
50
|
|
|
|
10
|
unless (defined $user) { |
351
|
0
|
|
|
|
|
0
|
($user, $host, $display) = @parts; |
352
|
|
|
|
|
|
|
} |
353
|
|
|
|
|
|
|
} |
354
|
|
|
|
|
|
|
} |
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
# starttime and optional number of licenses |
357
|
36
|
|
|
|
|
46
|
my $startdate; |
358
|
36
|
|
|
|
|
49
|
my $licenses = 1; |
359
|
36
|
100
|
|
|
|
80
|
if ($rest =~ /^([^,]+), (\d+) license/) { |
360
|
1
|
|
|
|
|
3
|
$startdate = $1; |
361
|
1
|
|
|
|
|
2
|
$licenses = $2; |
362
|
|
|
|
|
|
|
} else { |
363
|
35
|
|
|
|
|
47
|
$startdate = $rest; |
364
|
|
|
|
|
|
|
} |
365
|
|
|
|
|
|
|
|
366
|
36
|
|
|
|
|
48
|
push @{$status->{feature}->{$feature}->{users}}, { |
|
36
|
|
|
|
|
472
|
|
367
|
|
|
|
|
|
|
user=>$user, |
368
|
|
|
|
|
|
|
host=>$host, |
369
|
|
|
|
|
|
|
display=>$display, |
370
|
|
|
|
|
|
|
licenses=>$licenses, |
371
|
|
|
|
|
|
|
serverhost=>$serverhost, |
372
|
|
|
|
|
|
|
port=>$port, |
373
|
|
|
|
|
|
|
handle=>$handle, |
374
|
|
|
|
|
|
|
startdate=>$startdate |
375
|
|
|
|
|
|
|
}; |
376
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
# reservation info |
378
|
|
|
|
|
|
|
} elsif ( my ($reservations, $type, $group) = /^\s+(\d+)\s+RESERVATIONs? for ([\w_]+) ([\w_-]+) / ) { |
379
|
4
|
|
|
|
|
6
|
push @{$status->{feature}->{$feature}->{reservations}}, |
|
4
|
|
|
|
|
36
|
|
380
|
|
|
|
|
|
|
{type=>$type, group=>$group, reservations=>$reservations}; |
381
|
|
|
|
|
|
|
} |
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
} |
384
|
1
|
|
|
|
|
9
|
close ($fh); |
385
|
|
|
|
|
|
|
|
386
|
1
|
|
|
|
|
8
|
return $status; |
387
|
|
|
|
|
|
|
} |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
sub lmremove { |
390
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
391
|
0
|
|
|
|
|
|
my %args = @_; |
392
|
0
|
|
|
|
|
|
my $cmd; |
393
|
|
|
|
|
|
|
|
394
|
0
|
|
|
|
|
|
foreach my $arg (qw (feature serverhost port handle)) { |
395
|
0
|
0
|
|
|
|
|
die "Parameter '$arg' missing\n" unless $args{$arg}; |
396
|
|
|
|
|
|
|
} |
397
|
|
|
|
|
|
|
|
398
|
0
|
|
|
|
|
|
$cmd = "$self->{lmutil} lmremove"; |
399
|
0
|
0
|
|
|
|
|
if ( defined ($self->{lm_license_path})) { |
400
|
0
|
|
|
|
|
|
$cmd .= " -c $self->{lm_license_path}"; |
401
|
|
|
|
|
|
|
} |
402
|
0
|
|
|
|
|
|
$cmd .= " -h $args{feature} $args{serverhost} $args{port} $args{handle}"; |
403
|
|
|
|
|
|
|
|
404
|
0
|
0
|
|
|
|
|
print "Running command: $cmd\n" if $self->{verbose}; |
405
|
0
|
|
|
|
|
|
system($cmd); |
406
|
|
|
|
|
|
|
} |
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
1; # End of Flexnet::lmutil |