1*9781SMoriah.Waterland@Sun.COM /*
2*9781SMoriah.Waterland@Sun.COM * CDDL HEADER START
3*9781SMoriah.Waterland@Sun.COM *
4*9781SMoriah.Waterland@Sun.COM * The contents of this file are subject to the terms of the
5*9781SMoriah.Waterland@Sun.COM * Common Development and Distribution License (the "License").
6*9781SMoriah.Waterland@Sun.COM * You may not use this file except in compliance with the License.
7*9781SMoriah.Waterland@Sun.COM *
8*9781SMoriah.Waterland@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*9781SMoriah.Waterland@Sun.COM * or http://www.opensolaris.org/os/licensing.
10*9781SMoriah.Waterland@Sun.COM * See the License for the specific language governing permissions
11*9781SMoriah.Waterland@Sun.COM * and limitations under the License.
12*9781SMoriah.Waterland@Sun.COM *
13*9781SMoriah.Waterland@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
14*9781SMoriah.Waterland@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*9781SMoriah.Waterland@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
16*9781SMoriah.Waterland@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
17*9781SMoriah.Waterland@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
18*9781SMoriah.Waterland@Sun.COM *
19*9781SMoriah.Waterland@Sun.COM * CDDL HEADER END
20*9781SMoriah.Waterland@Sun.COM */
21*9781SMoriah.Waterland@Sun.COM
22*9781SMoriah.Waterland@Sun.COM /*
23*9781SMoriah.Waterland@Sun.COM * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24*9781SMoriah.Waterland@Sun.COM * Use is subject to license terms.
25*9781SMoriah.Waterland@Sun.COM */
26*9781SMoriah.Waterland@Sun.COM
27*9781SMoriah.Waterland@Sun.COM /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28*9781SMoriah.Waterland@Sun.COM /* All Rights Reserved */
29*9781SMoriah.Waterland@Sun.COM
30*9781SMoriah.Waterland@Sun.COM
31*9781SMoriah.Waterland@Sun.COM #include <stdio.h>
32*9781SMoriah.Waterland@Sun.COM #include <ctype.h>
33*9781SMoriah.Waterland@Sun.COM #include <string.h>
34*9781SMoriah.Waterland@Sun.COM #include <stdlib.h>
35*9781SMoriah.Waterland@Sun.COM #include <unistd.h>
36*9781SMoriah.Waterland@Sun.COM #include <sys/types.h>
37*9781SMoriah.Waterland@Sun.COM #include <sys/param.h>
38*9781SMoriah.Waterland@Sun.COM #include <sys/stat.h>
39*9781SMoriah.Waterland@Sun.COM #include <sys/statvfs.h>
40*9781SMoriah.Waterland@Sun.COM #include <limits.h>
41*9781SMoriah.Waterland@Sun.COM #include <locale.h>
42*9781SMoriah.Waterland@Sun.COM #include <libintl.h>
43*9781SMoriah.Waterland@Sun.COM #include <pkgstrct.h>
44*9781SMoriah.Waterland@Sun.COM #include "install.h"
45*9781SMoriah.Waterland@Sun.COM #include <pkglib.h>
46*9781SMoriah.Waterland@Sun.COM #include "libadm.h"
47*9781SMoriah.Waterland@Sun.COM #include "libinst.h"
48*9781SMoriah.Waterland@Sun.COM #include "pkginstall.h"
49*9781SMoriah.Waterland@Sun.COM
50*9781SMoriah.Waterland@Sun.COM extern struct cfextra **extlist;
51*9781SMoriah.Waterland@Sun.COM extern char pkgloc[];
52*9781SMoriah.Waterland@Sun.COM extern char instdir[];
53*9781SMoriah.Waterland@Sun.COM
54*9781SMoriah.Waterland@Sun.COM #define LSIZE 256
55*9781SMoriah.Waterland@Sun.COM #define LIM_BFREE 150LL
56*9781SMoriah.Waterland@Sun.COM #define LIM_FFREE 25LL
57*9781SMoriah.Waterland@Sun.COM
58*9781SMoriah.Waterland@Sun.COM #define WRN_STATVFS "WARNING: unable to stat filesystem mounted on <%s>"
59*9781SMoriah.Waterland@Sun.COM
60*9781SMoriah.Waterland@Sun.COM #define WRN_NOBLKS "The %s filesystem has %llu free blocks. The current " \
61*9781SMoriah.Waterland@Sun.COM "installation requires %llu blocks, which includes a " \
62*9781SMoriah.Waterland@Sun.COM "required %llu block buffer for open " \
63*9781SMoriah.Waterland@Sun.COM "deleted files. %llu more blocks are needed."
64*9781SMoriah.Waterland@Sun.COM
65*9781SMoriah.Waterland@Sun.COM #define WRN_NOFILES "The %s filesystem has %llu free file nodes. The " \
66*9781SMoriah.Waterland@Sun.COM "current installation requires %llu file nodes, " \
67*9781SMoriah.Waterland@Sun.COM "which includes a required %llu file node buffer " \
68*9781SMoriah.Waterland@Sun.COM "for temporary files. %llu more file nodes " \
69*9781SMoriah.Waterland@Sun.COM "are needed."
70*9781SMoriah.Waterland@Sun.COM
71*9781SMoriah.Waterland@Sun.COM #define TYPE_BLCK 0
72*9781SMoriah.Waterland@Sun.COM #define TYPE_NODE 1
73*9781SMoriah.Waterland@Sun.COM static void warn(int type, char *name, fsblkcnt_t need, fsblkcnt_t avail,
74*9781SMoriah.Waterland@Sun.COM fsblkcnt_t limit);
75*9781SMoriah.Waterland@Sun.COM static int fsys_stat(int n);
76*9781SMoriah.Waterland@Sun.COM static int readmap(int *error);
77*9781SMoriah.Waterland@Sun.COM static int readspace(char *spacefile, int *error);
78*9781SMoriah.Waterland@Sun.COM
79*9781SMoriah.Waterland@Sun.COM int
dockspace(char * spacefile)80*9781SMoriah.Waterland@Sun.COM dockspace(char *spacefile)
81*9781SMoriah.Waterland@Sun.COM {
82*9781SMoriah.Waterland@Sun.COM struct fstable *fs_tab;
83*9781SMoriah.Waterland@Sun.COM int i, error;
84*9781SMoriah.Waterland@Sun.COM
85*9781SMoriah.Waterland@Sun.COM error = 0;
86*9781SMoriah.Waterland@Sun.COM
87*9781SMoriah.Waterland@Sun.COM /*
88*9781SMoriah.Waterland@Sun.COM * Also, vanilla SVr4 code used the output from popen()
89*9781SMoriah.Waterland@Sun.COM * on the "/etc/mount" command. However, we need to get more
90*9781SMoriah.Waterland@Sun.COM * information about mounted filesystems, so we use the C
91*9781SMoriah.Waterland@Sun.COM * interfaces to the mount table, which also happens to be
92*9781SMoriah.Waterland@Sun.COM * much faster than running another process. Since several
93*9781SMoriah.Waterland@Sun.COM * of the pkg commands need access to the mount table, this
94*9781SMoriah.Waterland@Sun.COM * code is now in libinst. However, mount table info is needed
95*9781SMoriah.Waterland@Sun.COM * at the time the base directory is determined, so the call
96*9781SMoriah.Waterland@Sun.COM * to get the mount table information is in main.c
97*9781SMoriah.Waterland@Sun.COM */
98*9781SMoriah.Waterland@Sun.COM
99*9781SMoriah.Waterland@Sun.COM if (readmap(&error) || readspace(spacefile, &error))
100*9781SMoriah.Waterland@Sun.COM return (-1);
101*9781SMoriah.Waterland@Sun.COM
102*9781SMoriah.Waterland@Sun.COM for (i = 0; fs_tab = get_fs_entry(i); ++i) {
103*9781SMoriah.Waterland@Sun.COM if ((!fs_tab->fused) && (!fs_tab->bused))
104*9781SMoriah.Waterland@Sun.COM continue; /* not used by us */
105*9781SMoriah.Waterland@Sun.COM
106*9781SMoriah.Waterland@Sun.COM if (fs_tab->bfree < (LIM_BFREE + fs_tab->bused)) {
107*9781SMoriah.Waterland@Sun.COM warn(TYPE_BLCK, fs_tab->name, fs_tab->bused,
108*9781SMoriah.Waterland@Sun.COM fs_tab->bfree, LIM_BFREE);
109*9781SMoriah.Waterland@Sun.COM error++;
110*9781SMoriah.Waterland@Sun.COM }
111*9781SMoriah.Waterland@Sun.COM
112*9781SMoriah.Waterland@Sun.COM /* bug id 1091292 */
113*9781SMoriah.Waterland@Sun.COM if ((long)fs_tab->ffree == -1L)
114*9781SMoriah.Waterland@Sun.COM continue;
115*9781SMoriah.Waterland@Sun.COM if (fs_tab->ffree < (LIM_FFREE + fs_tab->fused)) {
116*9781SMoriah.Waterland@Sun.COM warn(TYPE_NODE, fs_tab->name, fs_tab->fused,
117*9781SMoriah.Waterland@Sun.COM fs_tab->ffree, LIM_FFREE);
118*9781SMoriah.Waterland@Sun.COM error++;
119*9781SMoriah.Waterland@Sun.COM }
120*9781SMoriah.Waterland@Sun.COM }
121*9781SMoriah.Waterland@Sun.COM return (error);
122*9781SMoriah.Waterland@Sun.COM }
123*9781SMoriah.Waterland@Sun.COM
124*9781SMoriah.Waterland@Sun.COM static void
warn(int type,char * name,fsblkcnt_t need,fsblkcnt_t avail,fsblkcnt_t limit)125*9781SMoriah.Waterland@Sun.COM warn(int type, char *name, fsblkcnt_t need, fsblkcnt_t avail, fsblkcnt_t limit)
126*9781SMoriah.Waterland@Sun.COM {
127*9781SMoriah.Waterland@Sun.COM logerr(gettext("WARNING:"));
128*9781SMoriah.Waterland@Sun.COM if (type == TYPE_BLCK) {
129*9781SMoriah.Waterland@Sun.COM logerr(gettext(WRN_NOBLKS), name, avail, (need + limit), limit,
130*9781SMoriah.Waterland@Sun.COM (need + limit - avail));
131*9781SMoriah.Waterland@Sun.COM } else {
132*9781SMoriah.Waterland@Sun.COM logerr(gettext(WRN_NOFILES), name, avail, (need + limit), limit,
133*9781SMoriah.Waterland@Sun.COM (need + limit - avail));
134*9781SMoriah.Waterland@Sun.COM }
135*9781SMoriah.Waterland@Sun.COM }
136*9781SMoriah.Waterland@Sun.COM
137*9781SMoriah.Waterland@Sun.COM static int
fsys_stat(int n)138*9781SMoriah.Waterland@Sun.COM fsys_stat(int n)
139*9781SMoriah.Waterland@Sun.COM {
140*9781SMoriah.Waterland@Sun.COM struct statvfs64 svfsb;
141*9781SMoriah.Waterland@Sun.COM struct fstable *fs_tab;
142*9781SMoriah.Waterland@Sun.COM
143*9781SMoriah.Waterland@Sun.COM if (n == BADFSYS)
144*9781SMoriah.Waterland@Sun.COM return (1);
145*9781SMoriah.Waterland@Sun.COM
146*9781SMoriah.Waterland@Sun.COM fs_tab = get_fs_entry(n);
147*9781SMoriah.Waterland@Sun.COM
148*9781SMoriah.Waterland@Sun.COM /*
149*9781SMoriah.Waterland@Sun.COM * At this point, we know we need information
150*9781SMoriah.Waterland@Sun.COM * about a particular filesystem, so we can do the
151*9781SMoriah.Waterland@Sun.COM * statvfs() now. For performance reasons, we only want to
152*9781SMoriah.Waterland@Sun.COM * stat the filesystem once, at the first time we need to,
153*9781SMoriah.Waterland@Sun.COM * and so we can key on whether or not we have the
154*9781SMoriah.Waterland@Sun.COM * block size for that filesystem.
155*9781SMoriah.Waterland@Sun.COM */
156*9781SMoriah.Waterland@Sun.COM if (fs_tab->bsize != 0)
157*9781SMoriah.Waterland@Sun.COM return (0);
158*9781SMoriah.Waterland@Sun.COM
159*9781SMoriah.Waterland@Sun.COM if (statvfs64(fs_tab->name, &svfsb)) {
160*9781SMoriah.Waterland@Sun.COM logerr(gettext(WRN_STATVFS), fs_tab->name);
161*9781SMoriah.Waterland@Sun.COM return (1);
162*9781SMoriah.Waterland@Sun.COM }
163*9781SMoriah.Waterland@Sun.COM
164*9781SMoriah.Waterland@Sun.COM /*
165*9781SMoriah.Waterland@Sun.COM * statvfs returns number of fragment size blocks
166*9781SMoriah.Waterland@Sun.COM * so will change this to number of 512 byte blocks
167*9781SMoriah.Waterland@Sun.COM */
168*9781SMoriah.Waterland@Sun.COM fs_tab->bsize = svfsb.f_bsize;
169*9781SMoriah.Waterland@Sun.COM fs_tab->frsize = svfsb.f_frsize;
170*9781SMoriah.Waterland@Sun.COM fs_tab->bfree = ((svfsb.f_frsize > 0) ?
171*9781SMoriah.Waterland@Sun.COM howmany(svfsb.f_frsize, DEV_BSIZE) :
172*9781SMoriah.Waterland@Sun.COM howmany(svfsb.f_bsize, DEV_BSIZE)) * svfsb.f_bavail;
173*9781SMoriah.Waterland@Sun.COM fs_tab->ffree = (svfsb.f_favail > 0) ? svfsb.f_favail : svfsb.f_ffree;
174*9781SMoriah.Waterland@Sun.COM return (0);
175*9781SMoriah.Waterland@Sun.COM }
176*9781SMoriah.Waterland@Sun.COM
177*9781SMoriah.Waterland@Sun.COM /*
178*9781SMoriah.Waterland@Sun.COM * This function reads all of the package objects, maps them to their target
179*9781SMoriah.Waterland@Sun.COM * filesystems and adds up the amount of space used on each. Wherever you see
180*9781SMoriah.Waterland@Sun.COM * "fsys_value", that's the apparent filesystem which could be a temporary
181*9781SMoriah.Waterland@Sun.COM * loopback mount for the purpose of constructing the client filesystem. It
182*9781SMoriah.Waterland@Sun.COM * isn't necessarily the real target filesystem. Where you see "fsys_base"
183*9781SMoriah.Waterland@Sun.COM * that's the real filesystem to which fsys_value may just refer. If this is
184*9781SMoriah.Waterland@Sun.COM * installing to a standalone or a server, fsys_value will almost always be
185*9781SMoriah.Waterland@Sun.COM * the same as fsys_base.
186*9781SMoriah.Waterland@Sun.COM */
187*9781SMoriah.Waterland@Sun.COM static int
readmap(int * error)188*9781SMoriah.Waterland@Sun.COM readmap(int *error)
189*9781SMoriah.Waterland@Sun.COM {
190*9781SMoriah.Waterland@Sun.COM struct fstable *fs_tab;
191*9781SMoriah.Waterland@Sun.COM struct cfextra *ext;
192*9781SMoriah.Waterland@Sun.COM struct cfent *ept;
193*9781SMoriah.Waterland@Sun.COM struct stat statbuf;
194*9781SMoriah.Waterland@Sun.COM char tpath[PATH_MAX];
195*9781SMoriah.Waterland@Sun.COM fsblkcnt_t blk;
196*9781SMoriah.Waterland@Sun.COM int i, n;
197*9781SMoriah.Waterland@Sun.COM
198*9781SMoriah.Waterland@Sun.COM /*
199*9781SMoriah.Waterland@Sun.COM * Handle the installation files (ftype i) that are in the
200*9781SMoriah.Waterland@Sun.COM * pkgmap/eptlist.
201*9781SMoriah.Waterland@Sun.COM */
202*9781SMoriah.Waterland@Sun.COM for (i = 0; (ext = extlist[i]) != NULL; i++) {
203*9781SMoriah.Waterland@Sun.COM ept = &(ext->cf_ent);
204*9781SMoriah.Waterland@Sun.COM
205*9781SMoriah.Waterland@Sun.COM if (ept->ftype != 'i')
206*9781SMoriah.Waterland@Sun.COM continue;
207*9781SMoriah.Waterland@Sun.COM
208*9781SMoriah.Waterland@Sun.COM /*
209*9781SMoriah.Waterland@Sun.COM * These paths are treated differently from the others
210*9781SMoriah.Waterland@Sun.COM * since their full pathnames are not included in the
211*9781SMoriah.Waterland@Sun.COM * pkgmap.
212*9781SMoriah.Waterland@Sun.COM */
213*9781SMoriah.Waterland@Sun.COM if (strcmp(ept->path, "pkginfo") == 0)
214*9781SMoriah.Waterland@Sun.COM (void) sprintf(tpath, "%s/%s", pkgloc, ept->path);
215*9781SMoriah.Waterland@Sun.COM else
216*9781SMoriah.Waterland@Sun.COM (void) sprintf(tpath, "%s/install/%s", pkgloc,
217*9781SMoriah.Waterland@Sun.COM ept->path);
218*9781SMoriah.Waterland@Sun.COM
219*9781SMoriah.Waterland@Sun.COM /* If we haven't done an fsys() series, do one */
220*9781SMoriah.Waterland@Sun.COM if (ext->fsys_value == BADFSYS)
221*9781SMoriah.Waterland@Sun.COM ext->fsys_value = fsys(tpath);
222*9781SMoriah.Waterland@Sun.COM
223*9781SMoriah.Waterland@Sun.COM /*
224*9781SMoriah.Waterland@Sun.COM * Now check if this is a base or apparent filesystem. If
225*9781SMoriah.Waterland@Sun.COM * it's just apparent, get the resolved filesystem entry,
226*9781SMoriah.Waterland@Sun.COM * otherwise, base and value are the same.
227*9781SMoriah.Waterland@Sun.COM */
228*9781SMoriah.Waterland@Sun.COM if (use_srvr_map_n(ext->fsys_value))
229*9781SMoriah.Waterland@Sun.COM ext->fsys_base = resolved_fsys(tpath);
230*9781SMoriah.Waterland@Sun.COM else
231*9781SMoriah.Waterland@Sun.COM ext->fsys_base = ext->fsys_value;
232*9781SMoriah.Waterland@Sun.COM
233*9781SMoriah.Waterland@Sun.COM if (fsys_stat(ext->fsys_base)) {
234*9781SMoriah.Waterland@Sun.COM (*error)++;
235*9781SMoriah.Waterland@Sun.COM continue;
236*9781SMoriah.Waterland@Sun.COM }
237*9781SMoriah.Waterland@Sun.COM
238*9781SMoriah.Waterland@Sun.COM /*
239*9781SMoriah.Waterland@Sun.COM * Don't accumulate space requirements on read-only
240*9781SMoriah.Waterland@Sun.COM * remote filesystems.
241*9781SMoriah.Waterland@Sun.COM */
242*9781SMoriah.Waterland@Sun.COM if (is_remote_fs_n(ext->fsys_value) &&
243*9781SMoriah.Waterland@Sun.COM !is_fs_writeable_n(ext->fsys_value))
244*9781SMoriah.Waterland@Sun.COM continue;
245*9781SMoriah.Waterland@Sun.COM
246*9781SMoriah.Waterland@Sun.COM fs_tab = get_fs_entry(ext->fsys_base);
247*9781SMoriah.Waterland@Sun.COM
248*9781SMoriah.Waterland@Sun.COM fs_tab->fused++;
249*9781SMoriah.Waterland@Sun.COM if (ept->cinfo.size != BADCONT)
250*9781SMoriah.Waterland@Sun.COM blk = nblk(ept->cinfo.size,
251*9781SMoriah.Waterland@Sun.COM fs_tab->bsize,
252*9781SMoriah.Waterland@Sun.COM fs_tab->frsize);
253*9781SMoriah.Waterland@Sun.COM else
254*9781SMoriah.Waterland@Sun.COM blk = 0;
255*9781SMoriah.Waterland@Sun.COM fs_tab->bused += blk;
256*9781SMoriah.Waterland@Sun.COM }
257*9781SMoriah.Waterland@Sun.COM
258*9781SMoriah.Waterland@Sun.COM /*
259*9781SMoriah.Waterland@Sun.COM * Handle the other files in the eptlist.
260*9781SMoriah.Waterland@Sun.COM */
261*9781SMoriah.Waterland@Sun.COM for (i = 0; (ext = extlist[i]) != NULL; i++) {
262*9781SMoriah.Waterland@Sun.COM ept = &(extlist[i]->cf_ent);
263*9781SMoriah.Waterland@Sun.COM
264*9781SMoriah.Waterland@Sun.COM if (ept->ftype == 'i')
265*9781SMoriah.Waterland@Sun.COM continue;
266*9781SMoriah.Waterland@Sun.COM
267*9781SMoriah.Waterland@Sun.COM /*
268*9781SMoriah.Waterland@Sun.COM * Don't recalculate package objects that are already in the
269*9781SMoriah.Waterland@Sun.COM * table.
270*9781SMoriah.Waterland@Sun.COM */
271*9781SMoriah.Waterland@Sun.COM if (ext->mstat.preloaded)
272*9781SMoriah.Waterland@Sun.COM continue;
273*9781SMoriah.Waterland@Sun.COM
274*9781SMoriah.Waterland@Sun.COM /*
275*9781SMoriah.Waterland@Sun.COM * Don't accumulate space requirements on read-only
276*9781SMoriah.Waterland@Sun.COM * remote filesystems.
277*9781SMoriah.Waterland@Sun.COM */
278*9781SMoriah.Waterland@Sun.COM if (is_remote_fs(ept->path, &(ext->fsys_value)) &&
279*9781SMoriah.Waterland@Sun.COM !is_fs_writeable(ept->path, &(ext->fsys_value)))
280*9781SMoriah.Waterland@Sun.COM continue;
281*9781SMoriah.Waterland@Sun.COM
282*9781SMoriah.Waterland@Sun.COM /*
283*9781SMoriah.Waterland@Sun.COM * Now check if this is a base or apparent filesystem. If
284*9781SMoriah.Waterland@Sun.COM * it's just apparent, get the resolved filesystem entry,
285*9781SMoriah.Waterland@Sun.COM * otherwise, base and value are the same.
286*9781SMoriah.Waterland@Sun.COM */
287*9781SMoriah.Waterland@Sun.COM if (use_srvr_map_n(ext->fsys_value))
288*9781SMoriah.Waterland@Sun.COM ext->fsys_base = resolved_fsys(tpath);
289*9781SMoriah.Waterland@Sun.COM else
290*9781SMoriah.Waterland@Sun.COM ext->fsys_base = ext->fsys_value;
291*9781SMoriah.Waterland@Sun.COM
292*9781SMoriah.Waterland@Sun.COM /* At this point we know we have a good fsys_base. */
293*9781SMoriah.Waterland@Sun.COM if (fsys_stat(ext->fsys_base)) {
294*9781SMoriah.Waterland@Sun.COM (*error)++;
295*9781SMoriah.Waterland@Sun.COM continue;
296*9781SMoriah.Waterland@Sun.COM }
297*9781SMoriah.Waterland@Sun.COM
298*9781SMoriah.Waterland@Sun.COM /*
299*9781SMoriah.Waterland@Sun.COM * We have to stat this path based upon it's real location.
300*9781SMoriah.Waterland@Sun.COM * If this is a server-remap, ept->path isn't the real
301*9781SMoriah.Waterland@Sun.COM * location.
302*9781SMoriah.Waterland@Sun.COM */
303*9781SMoriah.Waterland@Sun.COM if (use_srvr_map_n(ext->fsys_value))
304*9781SMoriah.Waterland@Sun.COM strcpy(tpath, server_map(ept->path, ext->fsys_value));
305*9781SMoriah.Waterland@Sun.COM else
306*9781SMoriah.Waterland@Sun.COM strcpy(tpath, ept->path);
307*9781SMoriah.Waterland@Sun.COM
308*9781SMoriah.Waterland@Sun.COM fs_tab = get_fs_entry(ext->fsys_base);
309*9781SMoriah.Waterland@Sun.COM if (stat(tpath, &statbuf)) {
310*9781SMoriah.Waterland@Sun.COM /* path cannot be accessed */
311*9781SMoriah.Waterland@Sun.COM fs_tab->fused++;
312*9781SMoriah.Waterland@Sun.COM if (strchr("dxs", ept->ftype))
313*9781SMoriah.Waterland@Sun.COM blk =
314*9781SMoriah.Waterland@Sun.COM nblk(fs_tab->bsize,
315*9781SMoriah.Waterland@Sun.COM fs_tab->bsize,
316*9781SMoriah.Waterland@Sun.COM fs_tab->frsize);
317*9781SMoriah.Waterland@Sun.COM else if (ept->cinfo.size != BADCONT)
318*9781SMoriah.Waterland@Sun.COM blk = nblk(ept->cinfo.size,
319*9781SMoriah.Waterland@Sun.COM fs_tab->bsize,
320*9781SMoriah.Waterland@Sun.COM fs_tab->frsize);
321*9781SMoriah.Waterland@Sun.COM else
322*9781SMoriah.Waterland@Sun.COM blk = 0;
323*9781SMoriah.Waterland@Sun.COM } else {
324*9781SMoriah.Waterland@Sun.COM /* path already exists */
325*9781SMoriah.Waterland@Sun.COM if (strchr("dxs", ept->ftype))
326*9781SMoriah.Waterland@Sun.COM blk = 0;
327*9781SMoriah.Waterland@Sun.COM else if (ept->cinfo.size != BADCONT) {
328*9781SMoriah.Waterland@Sun.COM fsblkcnt_t new_size, old_size;
329*9781SMoriah.Waterland@Sun.COM new_size = nblk(ept->cinfo.size,
330*9781SMoriah.Waterland@Sun.COM fs_tab->bsize,
331*9781SMoriah.Waterland@Sun.COM fs_tab->frsize);
332*9781SMoriah.Waterland@Sun.COM old_size = nblk(statbuf.st_size,
333*9781SMoriah.Waterland@Sun.COM fs_tab->bsize,
334*9781SMoriah.Waterland@Sun.COM fs_tab->frsize);
335*9781SMoriah.Waterland@Sun.COM /*
336*9781SMoriah.Waterland@Sun.COM * negative blocks show room freed, but since
337*9781SMoriah.Waterland@Sun.COM * order of installation is uncertain show
338*9781SMoriah.Waterland@Sun.COM * 0 blocks usage
339*9781SMoriah.Waterland@Sun.COM */
340*9781SMoriah.Waterland@Sun.COM if (new_size < old_size)
341*9781SMoriah.Waterland@Sun.COM blk = 0;
342*9781SMoriah.Waterland@Sun.COM else
343*9781SMoriah.Waterland@Sun.COM blk = new_size - old_size;
344*9781SMoriah.Waterland@Sun.COM } else
345*9781SMoriah.Waterland@Sun.COM blk = 0;
346*9781SMoriah.Waterland@Sun.COM }
347*9781SMoriah.Waterland@Sun.COM fs_tab->bused += blk;
348*9781SMoriah.Waterland@Sun.COM }
349*9781SMoriah.Waterland@Sun.COM return (0);
350*9781SMoriah.Waterland@Sun.COM }
351*9781SMoriah.Waterland@Sun.COM
352*9781SMoriah.Waterland@Sun.COM static int
readspace(char * spacefile,int * error)353*9781SMoriah.Waterland@Sun.COM readspace(char *spacefile, int *error)
354*9781SMoriah.Waterland@Sun.COM {
355*9781SMoriah.Waterland@Sun.COM FILE *fp;
356*9781SMoriah.Waterland@Sun.COM char line[LSIZE];
357*9781SMoriah.Waterland@Sun.COM long blocks, nodes;
358*9781SMoriah.Waterland@Sun.COM int n;
359*9781SMoriah.Waterland@Sun.COM
360*9781SMoriah.Waterland@Sun.COM if (spacefile == NULL)
361*9781SMoriah.Waterland@Sun.COM return (0);
362*9781SMoriah.Waterland@Sun.COM
363*9781SMoriah.Waterland@Sun.COM if ((fp = fopen(spacefile, "r")) == NULL) {
364*9781SMoriah.Waterland@Sun.COM progerr(gettext("unable to open spacefile %s"), spacefile);
365*9781SMoriah.Waterland@Sun.COM return (-1);
366*9781SMoriah.Waterland@Sun.COM }
367*9781SMoriah.Waterland@Sun.COM
368*9781SMoriah.Waterland@Sun.COM while (fgets(line, LSIZE, fp)) {
369*9781SMoriah.Waterland@Sun.COM struct fstable *fs_tab;
370*9781SMoriah.Waterland@Sun.COM char *pt, path[PATH_MAX];
371*9781SMoriah.Waterland@Sun.COM
372*9781SMoriah.Waterland@Sun.COM blocks = nodes = 0;
373*9781SMoriah.Waterland@Sun.COM for (pt = line; isspace(*pt); /* void */)
374*9781SMoriah.Waterland@Sun.COM pt++;
375*9781SMoriah.Waterland@Sun.COM if (*pt == '#' || *pt == '\0')
376*9781SMoriah.Waterland@Sun.COM continue;
377*9781SMoriah.Waterland@Sun.COM
378*9781SMoriah.Waterland@Sun.COM (void) sscanf(line, "%s %ld %ld", path, &blocks, &nodes);
379*9781SMoriah.Waterland@Sun.COM mappath(2, path);
380*9781SMoriah.Waterland@Sun.COM basepath(path, get_basedir(), get_inst_root());
381*9781SMoriah.Waterland@Sun.COM canonize(path);
382*9781SMoriah.Waterland@Sun.COM
383*9781SMoriah.Waterland@Sun.COM n = resolved_fsys(path);
384*9781SMoriah.Waterland@Sun.COM if (fsys_stat(n)) {
385*9781SMoriah.Waterland@Sun.COM (*error)++;
386*9781SMoriah.Waterland@Sun.COM continue;
387*9781SMoriah.Waterland@Sun.COM }
388*9781SMoriah.Waterland@Sun.COM
389*9781SMoriah.Waterland@Sun.COM /*
390*9781SMoriah.Waterland@Sun.COM * Don't accumulate space requirements on read-only
391*9781SMoriah.Waterland@Sun.COM * remote filesystems. NOTE: For some reason, this
392*9781SMoriah.Waterland@Sun.COM * used to check for !remote && read only. If this
393*9781SMoriah.Waterland@Sun.COM * blows up later, then maybe that was correct -- JST
394*9781SMoriah.Waterland@Sun.COM */
395*9781SMoriah.Waterland@Sun.COM if (is_remote_fs_n(n) && !is_fs_writeable_n(n))
396*9781SMoriah.Waterland@Sun.COM continue;
397*9781SMoriah.Waterland@Sun.COM
398*9781SMoriah.Waterland@Sun.COM fs_tab = get_fs_entry(n);
399*9781SMoriah.Waterland@Sun.COM
400*9781SMoriah.Waterland@Sun.COM fs_tab->bused += blocks;
401*9781SMoriah.Waterland@Sun.COM fs_tab->fused += nodes;
402*9781SMoriah.Waterland@Sun.COM }
403*9781SMoriah.Waterland@Sun.COM (void) fclose(fp);
404*9781SMoriah.Waterland@Sun.COM return (0);
405*9781SMoriah.Waterland@Sun.COM }
406