1*57718be8SEnji Cooper /* $NetBSD: getmntinfo.c,v 1.1 2012/03/17 16:33:11 jruoho Exp $ */ 2*57718be8SEnji Cooper /* 3*57718be8SEnji Cooper * Copyright (c) 2007 The NetBSD Foundation, Inc. 4*57718be8SEnji Cooper * All rights reserved. 5*57718be8SEnji Cooper * 6*57718be8SEnji Cooper * Redistribution and use in source and binary forms, with or without 7*57718be8SEnji Cooper * modification, are permitted provided that the following conditions 8*57718be8SEnji Cooper * are met: 9*57718be8SEnji Cooper * 1. Redistributions of source code must retain the above copyright 10*57718be8SEnji Cooper * notice, this list of conditions and the following disclaimer. 11*57718be8SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 12*57718be8SEnji Cooper * notice, this list of conditions and the following disclaimer in the 13*57718be8SEnji Cooper * documentation and/or other materials provided with the distribution. 14*57718be8SEnji Cooper * 15*57718be8SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16*57718be8SEnji Cooper * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17*57718be8SEnji Cooper * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18*57718be8SEnji Cooper * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19*57718be8SEnji Cooper * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20*57718be8SEnji Cooper * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21*57718be8SEnji Cooper * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22*57718be8SEnji Cooper * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23*57718be8SEnji Cooper * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24*57718be8SEnji Cooper * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25*57718be8SEnji Cooper * POSSIBILITY OF SUCH DAMAGE. 26*57718be8SEnji Cooper */ 27*57718be8SEnji Cooper 28*57718be8SEnji Cooper #include <sys/param.h> 29*57718be8SEnji Cooper #include <sys/ucred.h> 30*57718be8SEnji Cooper #include <sys/mount.h> 31*57718be8SEnji Cooper 32*57718be8SEnji Cooper #include <err.h> 33*57718be8SEnji Cooper #include <stdlib.h> 34*57718be8SEnji Cooper #include <string.h> 35*57718be8SEnji Cooper 36*57718be8SEnji Cooper #define KB * 1024 37*57718be8SEnji Cooper #define MB * 1024 KB 38*57718be8SEnji Cooper #define GB * 1024 MB 39*57718be8SEnji Cooper 40*57718be8SEnji Cooper static struct statvfs *getnewstatvfs(void); 41*57718be8SEnji Cooper static void other_variants(const struct statvfs *, const int *, int, 42*57718be8SEnji Cooper const int *, int); 43*57718be8SEnji Cooper static void setup_filer(void); 44*57718be8SEnji Cooper static void setup_ld0g(void); 45*57718be8SEnji Cooper static void setup_strpct(void); 46*57718be8SEnji Cooper 47*57718be8SEnji Cooper static struct statvfs *allstatvfs; 48*57718be8SEnji Cooper static int sftotal, sfused; 49*57718be8SEnji Cooper 50*57718be8SEnji Cooper struct statvfs * 51*57718be8SEnji Cooper getnewstatvfs(void) 52*57718be8SEnji Cooper { 53*57718be8SEnji Cooper 54*57718be8SEnji Cooper if (sftotal == sfused) { 55*57718be8SEnji Cooper sftotal = sftotal ? sftotal * 2 : 1; 56*57718be8SEnji Cooper allstatvfs = realloc(allstatvfs, 57*57718be8SEnji Cooper sftotal * sizeof(struct statvfs)); 58*57718be8SEnji Cooper if (allstatvfs == NULL) 59*57718be8SEnji Cooper err(EXIT_FAILURE, "realloc"); 60*57718be8SEnji Cooper } 61*57718be8SEnji Cooper 62*57718be8SEnji Cooper return (&allstatvfs[sfused++]); 63*57718be8SEnji Cooper } 64*57718be8SEnji Cooper 65*57718be8SEnji Cooper void 66*57718be8SEnji Cooper other_variants(const struct statvfs *tmpl, const int *minfree, int minfreecnt, 67*57718be8SEnji Cooper const int *consumed, int consumedcnt) 68*57718be8SEnji Cooper { 69*57718be8SEnji Cooper int64_t total, used; 70*57718be8SEnji Cooper struct statvfs *sf; 71*57718be8SEnji Cooper int i, j; 72*57718be8SEnji Cooper 73*57718be8SEnji Cooper for (i = 0; i < minfreecnt; i++) 74*57718be8SEnji Cooper for (j = 0; j < consumedcnt; j++) { 75*57718be8SEnji Cooper sf = getnewstatvfs(); 76*57718be8SEnji Cooper *sf = *tmpl; 77*57718be8SEnji Cooper total = (int64_t)(u_long)sf->f_blocks * sf->f_bsize; 78*57718be8SEnji Cooper used = total * consumed[j] / 100; 79*57718be8SEnji Cooper sf->f_bfree = (total - used) / sf->f_bsize; 80*57718be8SEnji Cooper sf->f_bavail = (total * (100 - minfree[i]) / 100 - 81*57718be8SEnji Cooper used) / (int)sf->f_bsize; 82*57718be8SEnji Cooper sf->f_bresvd = sf->f_bfree - sf->f_bavail; 83*57718be8SEnji Cooper } 84*57718be8SEnji Cooper } 85*57718be8SEnji Cooper 86*57718be8SEnji Cooper /* 87*57718be8SEnji Cooper * Parameter taken from: 88*57718be8SEnji Cooper * http://mail-index.NetBSD.org/tech-userlevel/2004/03/24/0001.html 89*57718be8SEnji Cooper */ 90*57718be8SEnji Cooper void 91*57718be8SEnji Cooper setup_filer(void) 92*57718be8SEnji Cooper { 93*57718be8SEnji Cooper static const struct statvfs tmpl = { 94*57718be8SEnji Cooper #define BSIZE 512 95*57718be8SEnji Cooper #define TOTAL 1147ULL GB 96*57718be8SEnji Cooper #define USED 132ULL MB 97*57718be8SEnji Cooper .f_bsize = BSIZE, 98*57718be8SEnji Cooper .f_frsize = BSIZE, 99*57718be8SEnji Cooper .f_blocks = TOTAL / BSIZE, 100*57718be8SEnji Cooper .f_bfree = (TOTAL - USED) / BSIZE, 101*57718be8SEnji Cooper .f_bavail = (TOTAL - USED) / BSIZE, 102*57718be8SEnji Cooper .f_bresvd = 0, 103*57718be8SEnji Cooper .f_mntfromname = "filer:/", 104*57718be8SEnji Cooper .f_mntonname = "/filer", 105*57718be8SEnji Cooper #undef USED 106*57718be8SEnji Cooper #undef TOTAL 107*57718be8SEnji Cooper #undef BSIZE 108*57718be8SEnji Cooper }; 109*57718be8SEnji Cooper static const int minfree[] = { 0, 5, 10, 15, }; 110*57718be8SEnji Cooper static const int consumed[] = { 0, 20, 60, 95, 100 }; 111*57718be8SEnji Cooper 112*57718be8SEnji Cooper *getnewstatvfs() = tmpl; 113*57718be8SEnji Cooper other_variants(&tmpl, minfree, sizeof(minfree) / sizeof(minfree[0]), 114*57718be8SEnji Cooper consumed, sizeof(consumed) / sizeof(consumed[0])); 115*57718be8SEnji Cooper } 116*57718be8SEnji Cooper 117*57718be8SEnji Cooper /* 118*57718be8SEnji Cooper * Parameter taken from: 119*57718be8SEnji Cooper * http://mail-index.NetBSD.org/current-users/2004/03/01/0038.html 120*57718be8SEnji Cooper */ 121*57718be8SEnji Cooper void 122*57718be8SEnji Cooper setup_ld0g(void) 123*57718be8SEnji Cooper { 124*57718be8SEnji Cooper static const struct statvfs tmpl = { 125*57718be8SEnji Cooper #define BSIZE 4096 /* Guess */ 126*57718be8SEnji Cooper #define TOTAL 1308726116ULL KB 127*57718be8SEnji Cooper #define USED 17901268ULL KB 128*57718be8SEnji Cooper #define AVAIL 1225388540ULL KB 129*57718be8SEnji Cooper .f_bsize = BSIZE, 130*57718be8SEnji Cooper .f_frsize = BSIZE, 131*57718be8SEnji Cooper .f_blocks = TOTAL / BSIZE, 132*57718be8SEnji Cooper .f_bfree = (TOTAL - USED) / BSIZE, 133*57718be8SEnji Cooper .f_bavail = AVAIL / BSIZE, 134*57718be8SEnji Cooper .f_bresvd = (TOTAL - USED) / BSIZE - AVAIL / BSIZE, 135*57718be8SEnji Cooper .f_mntfromname = "/dev/ld0g", 136*57718be8SEnji Cooper .f_mntonname = "/anon-root", 137*57718be8SEnji Cooper #undef AVAIL 138*57718be8SEnji Cooper #undef USED 139*57718be8SEnji Cooper #undef TOTAL 140*57718be8SEnji Cooper #undef BSIZE 141*57718be8SEnji Cooper }; 142*57718be8SEnji Cooper static const int minfree[] = { 0, 5, 10, 15, }; 143*57718be8SEnji Cooper static const int consumed[] = { 0, 20, 60, 95, 100 }; 144*57718be8SEnji Cooper 145*57718be8SEnji Cooper *getnewstatvfs() = tmpl; 146*57718be8SEnji Cooper other_variants(&tmpl, minfree, sizeof(minfree) / sizeof(minfree[0]), 147*57718be8SEnji Cooper consumed, sizeof(consumed) / sizeof(consumed[0])); 148*57718be8SEnji Cooper } 149*57718be8SEnji Cooper 150*57718be8SEnji Cooper /* 151*57718be8SEnji Cooper * Test of strpct() with huge number. 152*57718be8SEnji Cooper */ 153*57718be8SEnji Cooper void 154*57718be8SEnji Cooper setup_strpct(void) 155*57718be8SEnji Cooper { 156*57718be8SEnji Cooper static const struct statvfs tmpl = { 157*57718be8SEnji Cooper #define BSIZE 4096 /* Guess */ 158*57718be8SEnji Cooper #define TOTAL 0x4ffffffffULL KB 159*57718be8SEnji Cooper #define USED (TOTAL / 2) 160*57718be8SEnji Cooper #define AVAIL (TOTAL / 2) 161*57718be8SEnji Cooper .f_bsize = BSIZE, 162*57718be8SEnji Cooper .f_frsize = BSIZE, 163*57718be8SEnji Cooper .f_blocks = TOTAL / BSIZE, 164*57718be8SEnji Cooper .f_bfree = (TOTAL - USED) / BSIZE, 165*57718be8SEnji Cooper .f_bavail = AVAIL / BSIZE, 166*57718be8SEnji Cooper .f_bresvd = (TOTAL - USED) / BSIZE - AVAIL / BSIZE, 167*57718be8SEnji Cooper .f_mntfromname = "/dev/strpct", 168*57718be8SEnji Cooper .f_mntonname = "/strpct", 169*57718be8SEnji Cooper #undef AVAIL 170*57718be8SEnji Cooper #undef USED 171*57718be8SEnji Cooper #undef TOTAL 172*57718be8SEnji Cooper #undef BSIZE 173*57718be8SEnji Cooper }; 174*57718be8SEnji Cooper 175*57718be8SEnji Cooper *getnewstatvfs() = tmpl; 176*57718be8SEnji Cooper } 177*57718be8SEnji Cooper 178*57718be8SEnji Cooper /* 179*57718be8SEnji Cooper * Parameter taken from: 180*57718be8SEnji Cooper * http://www.netbsd.org/cgi-bin/query-pr-single.pl?number=23600 181*57718be8SEnji Cooper */ 182*57718be8SEnji Cooper static void 183*57718be8SEnji Cooper setup_pr23600(void) 184*57718be8SEnji Cooper { 185*57718be8SEnji Cooper static const struct statvfs tmpl = { 186*57718be8SEnji Cooper #define BSIZE 512 187*57718be8SEnji Cooper #define TOTAL 20971376ULL 188*57718be8SEnji Cooper #define USED 5719864ULL 189*57718be8SEnji Cooper #define AVAIL 15251512ULL 190*57718be8SEnji Cooper .f_bsize = BSIZE, 191*57718be8SEnji Cooper .f_frsize = BSIZE, 192*57718be8SEnji Cooper .f_blocks = TOTAL, 193*57718be8SEnji Cooper .f_bfree = TOTAL - USED, 194*57718be8SEnji Cooper .f_bavail = AVAIL, 195*57718be8SEnji Cooper .f_bresvd = TOTAL - USED - AVAIL, 196*57718be8SEnji Cooper .f_mntfromname = "/dev/wd0e", 197*57718be8SEnji Cooper .f_mntonname = "/mount/windows/C", 198*57718be8SEnji Cooper #undef AVAIL 199*57718be8SEnji Cooper #undef USED 200*57718be8SEnji Cooper #undef TOTAL 201*57718be8SEnji Cooper #undef BSIZE 202*57718be8SEnji Cooper }; 203*57718be8SEnji Cooper 204*57718be8SEnji Cooper *getnewstatvfs() = tmpl; 205*57718be8SEnji Cooper } 206*57718be8SEnji Cooper 207*57718be8SEnji Cooper int 208*57718be8SEnji Cooper getmntinfo(struct statvfs **mntbuf, int flags) 209*57718be8SEnji Cooper { 210*57718be8SEnji Cooper 211*57718be8SEnji Cooper setup_filer(); 212*57718be8SEnji Cooper setup_ld0g(); 213*57718be8SEnji Cooper setup_strpct(); 214*57718be8SEnji Cooper setup_pr23600(); 215*57718be8SEnji Cooper 216*57718be8SEnji Cooper *mntbuf = allstatvfs; 217*57718be8SEnji Cooper return (sfused); 218*57718be8SEnji Cooper } 219