2 # Common functions for partitioning and formatting disks under solaris
4 BEGIN { push(@INC, ".."); };
7 &foreign_require("mount", "mount-lib.pl");
8 &foreign_require("proc", "proc-lib.pl");
10 %access = &get_module_acl();
14 # Returns a list of structures, one per disk
18 local $temp = &transname();
22 open(FORMAT, "format -f $temp |");
24 local $rv = &wait_for(FORMAT, 'Specify', '\s+\d+\. (\S+) <(.*) cyl (\d+) alt (\d+) hd (\d+) sec (\d+)>\s*(\S*)', '\s+\d+\. (\S+) <drive type unknown>', 'space for more');
25 if ($rv <= 0) { last; }
27 local $disk = { 'device' => "/dev/dsk/$matches[1]",
28 'type' => $matches[2] eq 'DEFAULT' ?
34 'volume' => $matches[7] };
35 if ($matches[1] =~ /c(\d+)t(\d+)d(\d+)$/) {
36 $disk->{'desc'} = &text('select_device',
39 elsif ($matches[1] =~ /c(\d+)d(\d+)$/) {
40 $disk->{'desc'} = &text('select_idedevice',
52 # Returns an array containing a disks vendor, product and revision
58 &fast_wait_for($fh, 'format>');
60 &wait_for($fh, 'Vendor:\s+(.*)\r\nProduct:\s+(.*)\r\nRevision:\s+(.*)\r\n');
61 @rv = ($matches[1],$matches[2],$matches[3]);
62 &wait_for($fh, 'format>');
66 # list_partitions(device)
67 # Returns a list of structures, one per partition
70 local(@rv, $secs, $i);
71 local @tag = &list_tags();
72 open(VTOC, "prtvtoc $_[0]s0 |");
74 if (/(\d+)\s+sectors\/cylinder/) {
77 if (/^\s+(\d+)\s+(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/) {
79 local $part = { 'tag' => $tag[$2],
80 'flag' => $3 eq "00" ? "wm" :
82 $3 eq "10" ? "rm" : "ru",
83 'start' => int($4 / $secs),
84 'end' => int($6 / $secs),
85 'device' => $_[0]."s$n" };
90 for($i=0; $i<8 || $i<@rv; $i++) {
91 $rv[$i] = { 'tag' => 'unassigned',
93 'device' => $_[0]."s$i" } if (!$rv[$i]);
94 if ($_[0] =~ /c(\d+)t(\d+)d(\d+)$/) {
95 $rv[$i]->{'desc'} = &text('select_part',
96 "$1", "$2", "$3", $i);
98 elsif ($_[0] =~ /c(\d+)d(\d+)$/) {
99 $rv[$i]->{'desc'} = &text('select_idepart',
100 chr($1*2 + $2 + 65), $i);
106 #&choose_disk($_[0]);
107 #if (!&wait_for($fh, 'unformatted', 'formatted')) { return (); }
108 #&wait_for($fh, 'format>');
109 #&wprint("partition\n");
110 #&wait_for($fh, 'partition>');
112 #&wait_for($fh, 'Blocks\r\n');
113 #while(&wait_for($fh, 'partition>', '\s+\d+\s+(\S+)\s+(\S+)\s+(\d+)(\s+-\s+(\d+))?.*\r\n')) {
114 # local $part = { 'tag' => $matches[1],
115 # 'flag' => $matches[2],
116 # 'start' => $matches[3],
117 # 'end' => $matches[5] ? $matches[5] : $matches[3] };
118 # if ($matches[1] =~ /c(\d+)t(\d+)d(\d+)s(\d+)$/) {
119 # $part->{'desc'} = &text('select_part', "$1", "$2", "$3", "$4");
124 #&wait_for($fh, 'format>');
128 # modify_partition(disk, partition, tag, flag, start, end)
129 # Changes an existing partition
135 &wait_for($fh, 'format>');
136 &wprint("partition\n");
137 local $fd = &wait_for($fh, 'partition>', 'run fdisk');
142 &wait_for($fh, 'partition>');
145 &wait_for($fh, 'Enter.*:'); &wprint("$_[2]\n");
146 &wait_for($fh, 'Enter.*:'); &wprint("$_[3]\n");
147 &wait_for($fh, 'Enter.*:'); &wprint("$_[4]\n");
148 &wait_for($fh, 'Enter.*:');
149 if ($_[4] || $_[5]) { &wprint(($_[5]-$_[4]+1)."c\n"); }
151 # deleting this partition..
154 &wait_for($fh, 'partition>');
156 if (&wait_for($fh, 'continue', 'Cannot')) {
157 &error($text{'emounted'});
160 if (&wait_for($fh, 'partition>', 'no backup labels')) {
161 &error($text{'elast'});
164 &wait_for($fh, 'format>');
168 # Returns a list of all known tags
171 return ("unassigned", "boot", "root", "swap",
172 "usr", "backup", "stand", "var", "home", "alternates", "cache");
176 # device_status(device)
177 # Returns the mount point, type and status of some device. Uses the mount module
178 # to query the list of known and mounted filesystems
181 @mounted = &foreign_call("mount", "list_mounted") if (!@mounted);
182 @mounts = &foreign_call("mount", "list_mounts") if (!@mounts);
183 local ($mounted) = grep { $_->[1] eq $_[0] } @mounted;
184 local ($mount) = grep { $_->[1] eq $_[0] } @mounts;
185 if ($mounted) { return ($mounted->[0], $mounted->[2], 1,
186 &indexof($mount, @mounts),
187 &indexof($mounted, @mounted)); }
188 elsif ($mount) { return ($mount->[0], $mount->[2], 0,
189 &indexof($mount, @mounts)); }
192 if ($metastat{$_[0]}) { return ("meta", "meta", 1); }
193 if ($metadb{$_[0]}) { return ("meta", "metadb", 1); }
200 # Returns a human-readable filesystem name
203 return $text{"fstype_$_[0]"} ? $text{"fstype_$_[0]"}
204 : $text{'fstype_unknown'};
207 # filesystem_type(device)
208 # Calls fstyp to get the filesystem on some device
212 chop($out = `fstyp $_[0] 2>&1`);
213 if ($out =~ /^\S+$/) { return $out; }
218 # Translate an error code from fsck
221 return $text{"fsck_$_[0]"} ? $text{"fsck_$_[0]"} : $text{'fsck_unknown'};
225 #############################################################################
227 #############################################################################
229 # Internal function to run the 'format' command
232 return if ($format_already_open);
233 ($fh, $fpid) = &foreign_call("proc", "pty_process_exec", "format");
235 local $rv = &wait_for($fh, 'Specify.*:', 'no disks found', 'space for more');
236 if ($rv == 0) { last; }
237 elsif ($rv == 1) { &error($text{'eformat'}); }
238 else { &wprint(" "); }
241 &wait_for($fh, 'format>');
242 $format_already_open++;
247 syswrite($fh, $_[0], length($_[0]));
252 print $_[2] ? "<tr>" : "";
253 print "<td align=right><b>$text{$_[0]}</b></td> <td nowrap>\n";
254 print "<input type=radio name=$_[0]_def value=1 checked> $text{'default'}\n";
255 print " <input type=radio name=$_[0]_def value=0>\n";
256 print "<input name=$_[0] size=6> $_[1]</td>";
257 print $_[2] ? "\n" : "</tr>\n";
262 if ($in{"$_[0]_def"}) { return ""; }
263 elsif ($in{$_[0]} !~ /^$_[1]$/) {
264 &error(&text('opt_error', $in{$_[0]}, $text{$_[0]}));
266 else { return " $_[2] $in{$_[0]}"; }
270 # internal function to build %metastat and %metadb arrays
273 if ($done_metamap_init) { return; }
274 $done_metamap_init = 1;
275 if (-x $config{metastat_path} && -x $config{metadb_path}) {
276 open(METASTAT, "$config{metastat_path} 2>&1 |");
278 if (/(c\d+t\d+d\d+s\d+)/) { $metastat{"/dev/dsk/$1"}++; }
281 open(METADB, "$config{metadb_path} -i 2>&1 |");
283 if (/(c\d+t\d+d\d+s\d+)/) { $metadb{"/dev/dsk/$1"}++; }
292 while(&wait_for($fh, 'Specify.*:', 'space for more')) {
298 # can_edit_disk(device)
301 $_[0] =~ /(c\d+t\d+d\d+)/;
302 foreach (split(/\s+/, $access{'disks'})) {
303 return 1 if ($_ eq "*" || $_ eq $1);
308 # partition_select(name, value, mode, &found)
309 # Returns HTML for selecting a disk or partition
310 # mode 0 = disk partitions
312 # 2 = disks and disk partitions
315 local $rv = "<select name=$_[0]>\n";
316 local ($found, $d, $p);
317 local @dlist = &list_disks();
318 foreach $d (@dlist) {
320 local $name = $d->{'desc'};
321 $name .= " ($d->{'type'})" if ($d->{'type'});
322 $rv .= sprintf "<option value=%s %s>%s\n",
324 $_[1] eq $d->{'device'} ? "selected" : "", $name;
325 $found++ if ($_[1] eq $d->{'device'});
328 local @parts = &list_partitions($d->{'device'});
329 foreach $p (@parts) {
330 local $name = $p->{'desc'};
331 next if (!$p->{'end'});
332 $name .= " ($p->{'tag'})" if ($p->{'tag'});
333 $rv .= sprintf "<option %s value=%s>%s\n",
334 $_[1] eq $p->{'device'} ? "selected" : "",
335 $p->{'device'}, $name;
336 $found++ if ($_[1] eq $p->{'device'});
340 if (!$found && $_[1] && !$_[3]) {
341 $rv .= "<option selected>$_[1]\n";
346 $rv .= "</select>\n";
351 # Returns the amount of total and free space for some filesystem, or an
352 # empty array if not appropriate.
355 local $out = `df -k $_[0] 2>&1`;
356 $out =~ /(\/dev\/\S+)\s+(\d+)\s+\S+\s+(\d+)/ || return ();