1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright (c) 1998,2001 by Sun Microsystems, Inc. 24*7c478bd9Sstevel@tonic-gate * All rights reserved. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include "dump.h" 30*7c478bd9Sstevel@tonic-gate #include <ftw.h> 31*7c478bd9Sstevel@tonic-gate #include <ulimit.h> 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate static int partial; 34*7c478bd9Sstevel@tonic-gate 35*7c478bd9Sstevel@tonic-gate #ifdef __STDC__ 36*7c478bd9Sstevel@tonic-gate static dev_t devfromopts(struct mntent *); 37*7c478bd9Sstevel@tonic-gate static int lf_mark_root(dev_t, char *); 38*7c478bd9Sstevel@tonic-gate static int lf_ftw_mark(const char *, const struct stat64 *, int); 39*7c478bd9Sstevel@tonic-gate static void markino(ino_t); 40*7c478bd9Sstevel@tonic-gate #else 41*7c478bd9Sstevel@tonic-gate static dev_t devfromopts(); 42*7c478bd9Sstevel@tonic-gate static int lf_mark_root(); 43*7c478bd9Sstevel@tonic-gate static int lf_ftw_mark(); 44*7c478bd9Sstevel@tonic-gate static void markino(); 45*7c478bd9Sstevel@tonic-gate #endif 46*7c478bd9Sstevel@tonic-gate 47*7c478bd9Sstevel@tonic-gate void 48*7c478bd9Sstevel@tonic-gate #ifdef __STDC__ 49*7c478bd9Sstevel@tonic-gate partial_check(void) 50*7c478bd9Sstevel@tonic-gate #else 51*7c478bd9Sstevel@tonic-gate partial_check() 52*7c478bd9Sstevel@tonic-gate #endif 53*7c478bd9Sstevel@tonic-gate { 54*7c478bd9Sstevel@tonic-gate struct mntent *mnt; 55*7c478bd9Sstevel@tonic-gate struct stat64 st; 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate if (stat64(disk, &st) < 0 || 58*7c478bd9Sstevel@tonic-gate (st.st_mode & S_IFMT) == S_IFCHR || 59*7c478bd9Sstevel@tonic-gate (st.st_mode & S_IFMT) == S_IFBLK) 60*7c478bd9Sstevel@tonic-gate return; 61*7c478bd9Sstevel@tonic-gate 62*7c478bd9Sstevel@tonic-gate partial_dev = st.st_dev; 63*7c478bd9Sstevel@tonic-gate 64*7c478bd9Sstevel@tonic-gate setmnttab(); 65*7c478bd9Sstevel@tonic-gate while (mnt = getmnttab()) { 66*7c478bd9Sstevel@tonic-gate st.st_dev = devfromopts(mnt); 67*7c478bd9Sstevel@tonic-gate if (st.st_dev == NODEV && 68*7c478bd9Sstevel@tonic-gate stat64(mnt->mnt_dir, &st) < 0) 69*7c478bd9Sstevel@tonic-gate continue; 70*7c478bd9Sstevel@tonic-gate if (partial_dev == st.st_dev) { 71*7c478bd9Sstevel@tonic-gate if (disk_dynamic) { 72*7c478bd9Sstevel@tonic-gate /* LINTED: disk is not NULL */ 73*7c478bd9Sstevel@tonic-gate free(disk); 74*7c478bd9Sstevel@tonic-gate } 75*7c478bd9Sstevel@tonic-gate disk = rawname(mnt->mnt_fsname); 76*7c478bd9Sstevel@tonic-gate disk_dynamic = (disk != mnt->mnt_fsname); 77*7c478bd9Sstevel@tonic-gate 78*7c478bd9Sstevel@tonic-gate partial = 1; 79*7c478bd9Sstevel@tonic-gate incno = '0'; 80*7c478bd9Sstevel@tonic-gate uflag = 0; 81*7c478bd9Sstevel@tonic-gate return; 82*7c478bd9Sstevel@tonic-gate } 83*7c478bd9Sstevel@tonic-gate } 84*7c478bd9Sstevel@tonic-gate msg(gettext("`%s' is not on a locally mounted filesystem\n"), disk); 85*7c478bd9Sstevel@tonic-gate dumpabort(); 86*7c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 87*7c478bd9Sstevel@tonic-gate } 88*7c478bd9Sstevel@tonic-gate 89*7c478bd9Sstevel@tonic-gate /* 90*7c478bd9Sstevel@tonic-gate * The device id for the mount should be available in 91*7c478bd9Sstevel@tonic-gate * the mount option string as "dev=%04x". If it's there 92*7c478bd9Sstevel@tonic-gate * extract the device id and avoid having to stat. 93*7c478bd9Sstevel@tonic-gate */ 94*7c478bd9Sstevel@tonic-gate static dev_t 95*7c478bd9Sstevel@tonic-gate devfromopts(mnt) 96*7c478bd9Sstevel@tonic-gate struct mntent *mnt; 97*7c478bd9Sstevel@tonic-gate { 98*7c478bd9Sstevel@tonic-gate char *str; 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate str = hasmntopt(mnt, MNTINFO_DEV); 101*7c478bd9Sstevel@tonic-gate if (str != NULL && (str = strchr(str, '='))) 102*7c478bd9Sstevel@tonic-gate return ((dev_t)strtol(str + 1, (char **)NULL, 16)); 103*7c478bd9Sstevel@tonic-gate 104*7c478bd9Sstevel@tonic-gate return (NODEV); 105*7c478bd9Sstevel@tonic-gate } 106*7c478bd9Sstevel@tonic-gate 107*7c478bd9Sstevel@tonic-gate int 108*7c478bd9Sstevel@tonic-gate partial_mark(argc, argv) 109*7c478bd9Sstevel@tonic-gate int argc; 110*7c478bd9Sstevel@tonic-gate char **argv; 111*7c478bd9Sstevel@tonic-gate { 112*7c478bd9Sstevel@tonic-gate char *path; 113*7c478bd9Sstevel@tonic-gate struct stat64 st; 114*7c478bd9Sstevel@tonic-gate 115*7c478bd9Sstevel@tonic-gate if (partial == 0) 116*7c478bd9Sstevel@tonic-gate return (1); 117*7c478bd9Sstevel@tonic-gate 118*7c478bd9Sstevel@tonic-gate while (--argc >= 0) { 119*7c478bd9Sstevel@tonic-gate path = *argv++; 120*7c478bd9Sstevel@tonic-gate 121*7c478bd9Sstevel@tonic-gate if (stat64(path, &st) < 0 || 122*7c478bd9Sstevel@tonic-gate st.st_dev != partial_dev) { 123*7c478bd9Sstevel@tonic-gate msg(gettext("`%s' is not on dump device `%s'\n"), 124*7c478bd9Sstevel@tonic-gate path, disk); 125*7c478bd9Sstevel@tonic-gate dumpabort(); 126*7c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 127*7c478bd9Sstevel@tonic-gate } 128*7c478bd9Sstevel@tonic-gate 129*7c478bd9Sstevel@tonic-gate if (lf_mark_root(partial_dev, path)) { 130*7c478bd9Sstevel@tonic-gate msg(gettext( 131*7c478bd9Sstevel@tonic-gate "Cannot find filesystem mount point for `%s'\n"), 132*7c478bd9Sstevel@tonic-gate path); 133*7c478bd9Sstevel@tonic-gate dumpabort(); 134*7c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 135*7c478bd9Sstevel@tonic-gate } 136*7c478bd9Sstevel@tonic-gate 137*7c478bd9Sstevel@tonic-gate /* LINTED this ulimit will always be < INT_MAX */ 138*7c478bd9Sstevel@tonic-gate if (lf_lftw(path, lf_ftw_mark, (int)ulimit(UL_GDESLIM, 0) / 2) 139*7c478bd9Sstevel@tonic-gate < 0) { 140*7c478bd9Sstevel@tonic-gate int saverr = errno; 141*7c478bd9Sstevel@tonic-gate msg(gettext("Error in %s (%s)\n"), 142*7c478bd9Sstevel@tonic-gate "ftw", strerror(saverr)); 143*7c478bd9Sstevel@tonic-gate dumpabort(); 144*7c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 145*7c478bd9Sstevel@tonic-gate } 146*7c478bd9Sstevel@tonic-gate } 147*7c478bd9Sstevel@tonic-gate 148*7c478bd9Sstevel@tonic-gate return (0); 149*7c478bd9Sstevel@tonic-gate } 150*7c478bd9Sstevel@tonic-gate 151*7c478bd9Sstevel@tonic-gate /* mark directories between target and root */ 152*7c478bd9Sstevel@tonic-gate static int 153*7c478bd9Sstevel@tonic-gate lf_mark_root(dev, path) 154*7c478bd9Sstevel@tonic-gate dev_t dev; 155*7c478bd9Sstevel@tonic-gate char *path; 156*7c478bd9Sstevel@tonic-gate { 157*7c478bd9Sstevel@tonic-gate struct stat64 st; 158*7c478bd9Sstevel@tonic-gate char dotdot[MAXPATHLEN + 16]; 159*7c478bd9Sstevel@tonic-gate char *slash; 160*7c478bd9Sstevel@tonic-gate 161*7c478bd9Sstevel@tonic-gate if (strlen(path) > sizeof (dotdot)) 162*7c478bd9Sstevel@tonic-gate return (1); 163*7c478bd9Sstevel@tonic-gate 164*7c478bd9Sstevel@tonic-gate (void) strcpy(dotdot, path); 165*7c478bd9Sstevel@tonic-gate 166*7c478bd9Sstevel@tonic-gate if (stat64(dotdot, &st) < 0) 167*7c478bd9Sstevel@tonic-gate return (1); 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate /* if target is a regular file, find directory */ 170*7c478bd9Sstevel@tonic-gate if ((st.st_mode & S_IFMT) != S_IFDIR) 171*7c478bd9Sstevel@tonic-gate if (slash = strrchr(dotdot, '/')) 172*7c478bd9Sstevel@tonic-gate /* "/file" -> "/" */ 173*7c478bd9Sstevel@tonic-gate if (slash == dotdot) 174*7c478bd9Sstevel@tonic-gate slash[1] = 0; 175*7c478bd9Sstevel@tonic-gate /* "dir/file" -> "dir" */ 176*7c478bd9Sstevel@tonic-gate else 177*7c478bd9Sstevel@tonic-gate slash[0] = 0; 178*7c478bd9Sstevel@tonic-gate else 179*7c478bd9Sstevel@tonic-gate /* "file" -> "." */ 180*7c478bd9Sstevel@tonic-gate (void) strcpy(dotdot, "."); 181*7c478bd9Sstevel@tonic-gate 182*7c478bd9Sstevel@tonic-gate /* keep marking parent until we hit mount point */ 183*7c478bd9Sstevel@tonic-gate do { 184*7c478bd9Sstevel@tonic-gate if (stat64(dotdot, &st) < 0 || 185*7c478bd9Sstevel@tonic-gate (st.st_mode & S_IFMT) != S_IFDIR || 186*7c478bd9Sstevel@tonic-gate st.st_dev != dev) 187*7c478bd9Sstevel@tonic-gate return (1); 188*7c478bd9Sstevel@tonic-gate markino(st.st_ino); 189*7c478bd9Sstevel@tonic-gate if (strlen(dotdot) > (sizeof (dotdot) - 4)) 190*7c478bd9Sstevel@tonic-gate return (1); 191*7c478bd9Sstevel@tonic-gate (void) strcat(dotdot, "/.."); 192*7c478bd9Sstevel@tonic-gate } while (st.st_ino != 2); 193*7c478bd9Sstevel@tonic-gate 194*7c478bd9Sstevel@tonic-gate return (0); 195*7c478bd9Sstevel@tonic-gate } 196*7c478bd9Sstevel@tonic-gate 197*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 198*7c478bd9Sstevel@tonic-gate static int 199*7c478bd9Sstevel@tonic-gate lf_ftw_mark(name, st, flag) 200*7c478bd9Sstevel@tonic-gate #ifdef __STDC__ 201*7c478bd9Sstevel@tonic-gate const char *name; 202*7c478bd9Sstevel@tonic-gate const struct stat64 *st; 203*7c478bd9Sstevel@tonic-gate #else 204*7c478bd9Sstevel@tonic-gate char *name; 205*7c478bd9Sstevel@tonic-gate struct stat64 *st; 206*7c478bd9Sstevel@tonic-gate #endif 207*7c478bd9Sstevel@tonic-gate int flag; 208*7c478bd9Sstevel@tonic-gate { 209*7c478bd9Sstevel@tonic-gate if (flag != FTW_NS) { 210*7c478bd9Sstevel@tonic-gate /* LINTED ufs only uses the lower 32 bits */ 211*7c478bd9Sstevel@tonic-gate markino((ino_t)st->st_ino); 212*7c478bd9Sstevel@tonic-gate } 213*7c478bd9Sstevel@tonic-gate return (0); 214*7c478bd9Sstevel@tonic-gate } 215*7c478bd9Sstevel@tonic-gate 216*7c478bd9Sstevel@tonic-gate static void 217*7c478bd9Sstevel@tonic-gate markino(i) 218*7c478bd9Sstevel@tonic-gate ino_t i; 219*7c478bd9Sstevel@tonic-gate { 220*7c478bd9Sstevel@tonic-gate struct dinode *dp; 221*7c478bd9Sstevel@tonic-gate 222*7c478bd9Sstevel@tonic-gate dp = getino(ino = i); 223*7c478bd9Sstevel@tonic-gate mark(dp); 224*7c478bd9Sstevel@tonic-gate } 225