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