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