1 | # $HeadURL: svn+ssh://svn.mit.edu/moira/trunk/moira/incremental/afs/afs_utils.pl $ $Id: afs_utils.pl 3964 2010-01-07 20:54:34Z zacheiss $ |
---|
2 | |
---|
3 | use Fcntl; |
---|
4 | |
---|
5 | $aklog="/bin/athena/aklog"; |
---|
6 | if ( ! -x $aklog ) { $aklog="/usr/bin/aklog"; } |
---|
7 | |
---|
8 | system("$aklog"); |
---|
9 | |
---|
10 | $afsbin="/moira/bin"; |
---|
11 | $vos="$afsbin/vos"; |
---|
12 | $pts="$afsbin/pts"; |
---|
13 | $fs="$afsbin/fs"; |
---|
14 | $zwrite="/usr/athena/bin/zwrite"; |
---|
15 | if ( ! -x $zwrite ) { $zwrite="/usr/local/bin/zwrite"; } |
---|
16 | |
---|
17 | $afs_data="/moira/afs/afs_data"; |
---|
18 | $afs_save="$afs_data.tmp"; |
---|
19 | |
---|
20 | %vtypes_ATHENA_MIT_EDU = |
---|
21 | ("ACTIVITY", "activity", |
---|
22 | "APROJ", "aproj", |
---|
23 | "AREF", "aref", |
---|
24 | "CONTRIB", "contrib", |
---|
25 | "COURSE", "course", |
---|
26 | "HOMEDIR", "user", |
---|
27 | "LEASE", "dept", |
---|
28 | "ORG", "org", |
---|
29 | "PROJECT", "project", |
---|
30 | "REF", "ref", |
---|
31 | "SW", "sw", |
---|
32 | "SYSTEM", "system", |
---|
33 | "UROP", "urop", |
---|
34 | ); |
---|
35 | |
---|
36 | # File format: |
---|
37 | # cell server partition total used alloc |
---|
38 | |
---|
39 | # Locking/re-write algorithm: |
---|
40 | # 1. Open the data file. |
---|
41 | # 2. Obtain a lock on the data file. |
---|
42 | # 3. Check for the existence of a temporary data file - die if it exists. |
---|
43 | # 4. Save current contents into temporary data file. |
---|
44 | # 5. Re-write output (with line-buffering). |
---|
45 | # 6. Unlink temporary file. |
---|
46 | # 7. Unlock data file. |
---|
47 | # 8. Close the data file. |
---|
48 | |
---|
49 | |
---|
50 | $flock_t="ssllllllll"; |
---|
51 | |
---|
52 | sub afs_lock |
---|
53 | { |
---|
54 | open(SRV,"+<$afs_data") || die "Unable to open $afs_data\n"; |
---|
55 | select((select(SRV), $|=1)[$[]); |
---|
56 | $flkarr[0]=&F_WRLCK; |
---|
57 | $flkarr[1]=$flkarr[2]=$flkarr[3]=$flkarr[4]=$flkarr[5]=$flkarr[6]=0; |
---|
58 | $flkarr[7]=$flkarr[8]=$flkarr[9]=0; |
---|
59 | $flk=pack($flock_t,@flkarr); |
---|
60 | fcntl(SRV, &F_SETLKW, $flk) || die "Unable to lock $afs_data:$!\n"; |
---|
61 | die "Temporary status file: $afs_save exists... aborting\n" |
---|
62 | if (-f $afs_save); |
---|
63 | open(SRV2, ">$afs_save"); |
---|
64 | @afs_data = <SRV>; |
---|
65 | print SRV2 @afs_data; |
---|
66 | close(SRV2); |
---|
67 | seek(SRV, 0, 0); |
---|
68 | } |
---|
69 | |
---|
70 | sub afs_unlock |
---|
71 | { |
---|
72 | unlink($afs_save); |
---|
73 | close(SRV); |
---|
74 | } |
---|
75 | |
---|
76 | # Find server/partition for allocation. |
---|
77 | # |
---|
78 | # Best fit algorithm used: |
---|
79 | # max[ (2*free space) - (unused quota) ] |
---|
80 | # = max(2*total - usage - alloc) |
---|
81 | # |
---|
82 | # Note: This routine does not actually adjust the quota; |
---|
83 | # the calling routine should use afs_quota_adj(); |
---|
84 | |
---|
85 | sub afs_find |
---|
86 | { |
---|
87 | local($cell,$type,$quota,@except) = @_; |
---|
88 | local($j,$k); |
---|
89 | local(@max) = ("", "", undef); |
---|
90 | |
---|
91 | &afs_lock; |
---|
92 | chop(@afs_data); |
---|
93 | |
---|
94 | sloop: |
---|
95 | for (@afs_data) { |
---|
96 | local ($a, $asrv, $apart, $t, $total, $used, $alloc) = split(/\s+/,$_); |
---|
97 | next if ($a ne $cell || !$total || $type !~ /$t/); |
---|
98 | for $j (@except) { |
---|
99 | next sloop if ($j eq $asrv); |
---|
100 | } |
---|
101 | $alloc = $used if ($alloc < $used); |
---|
102 | $j = 2*$total - $used - $alloc; |
---|
103 | @max = ($asrv,$apart,$j) if (!$max[2] || $j > $max[2]); |
---|
104 | } |
---|
105 | |
---|
106 | &afs_unlock; |
---|
107 | return(@max); |
---|
108 | } |
---|
109 | |
---|
110 | # |
---|
111 | # Quota adjustments |
---|
112 | # |
---|
113 | sub afs_quota_adj |
---|
114 | { |
---|
115 | local($cell,$asrv,$apart,$adj,$dusage) = @_; |
---|
116 | local($found) = 0; |
---|
117 | |
---|
118 | &afs_lock; |
---|
119 | chop(@afs_data); |
---|
120 | truncate(SRV, 0); |
---|
121 | for (@afs_data) { |
---|
122 | local ($c, $as, $ap, $t, $total, $used, $alloc) = split(/\s+/,$_); |
---|
123 | if ($c eq $cell && $as eq $asrv && $ap eq $apart) { |
---|
124 | $dusage = $used unless ($dusage); |
---|
125 | $alloc += $adj; |
---|
126 | $_ = join(' ',$c,$asrv,$apart,$t,$total,$dusage,$alloc); |
---|
127 | $found = 1; |
---|
128 | } |
---|
129 | print SRV "$_\n"; |
---|
130 | } |
---|
131 | &afs_unlock; |
---|
132 | return($found); |
---|
133 | } |
---|