xref: /illumos-gate/usr/src/cmd/backup/dump/partial.c (revision e0dfa398)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate  * Copyright (c) 1998,2001 by Sun Microsystems, Inc.
247c478bd9Sstevel@tonic-gate  * All rights reserved.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #include "dump.h"
287c478bd9Sstevel@tonic-gate #include <ftw.h>
297c478bd9Sstevel@tonic-gate #include <ulimit.h>
307c478bd9Sstevel@tonic-gate 
31*e0dfa398SToomas Soome dev_t partial_dev;
327c478bd9Sstevel@tonic-gate static int partial;
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate static dev_t devfromopts(struct mntent *);
357c478bd9Sstevel@tonic-gate static int lf_mark_root(dev_t, char *);
367c478bd9Sstevel@tonic-gate static int lf_ftw_mark(const char *, const struct stat64 *, int);
377c478bd9Sstevel@tonic-gate static void markino(ino_t);
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate void
partial_check(void)407c478bd9Sstevel@tonic-gate partial_check(void)
417c478bd9Sstevel@tonic-gate {
427c478bd9Sstevel@tonic-gate 	struct mntent *mnt;
437c478bd9Sstevel@tonic-gate 	struct stat64 st;
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate 	if (stat64(disk, &st) < 0 ||
467c478bd9Sstevel@tonic-gate 	    (st.st_mode & S_IFMT) == S_IFCHR ||
477c478bd9Sstevel@tonic-gate 	    (st.st_mode & S_IFMT) == S_IFBLK)
487c478bd9Sstevel@tonic-gate 		return;
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate 	partial_dev = st.st_dev;
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate 	setmnttab();
537c478bd9Sstevel@tonic-gate 	while (mnt = getmnttab()) {
547c478bd9Sstevel@tonic-gate 		st.st_dev = devfromopts(mnt);
557c478bd9Sstevel@tonic-gate 		if (st.st_dev == NODEV &&
567c478bd9Sstevel@tonic-gate 		    stat64(mnt->mnt_dir, &st) < 0)
577c478bd9Sstevel@tonic-gate 			continue;
587c478bd9Sstevel@tonic-gate 		if (partial_dev == st.st_dev) {
597c478bd9Sstevel@tonic-gate 			if (disk_dynamic) {
607c478bd9Sstevel@tonic-gate 				/* LINTED: disk is not NULL */
617c478bd9Sstevel@tonic-gate 				free(disk);
627c478bd9Sstevel@tonic-gate 			}
637c478bd9Sstevel@tonic-gate 			disk = rawname(mnt->mnt_fsname);
647c478bd9Sstevel@tonic-gate 			disk_dynamic = (disk != mnt->mnt_fsname);
657c478bd9Sstevel@tonic-gate 
667c478bd9Sstevel@tonic-gate 			partial = 1;
677c478bd9Sstevel@tonic-gate 			incno = '0';
687c478bd9Sstevel@tonic-gate 			uflag = 0;
697c478bd9Sstevel@tonic-gate 			return;
707c478bd9Sstevel@tonic-gate 		}
717c478bd9Sstevel@tonic-gate 	}
727c478bd9Sstevel@tonic-gate 	msg(gettext("`%s' is not on a locally mounted filesystem\n"), disk);
737c478bd9Sstevel@tonic-gate 	dumpabort();
747c478bd9Sstevel@tonic-gate 	/*NOTREACHED*/
757c478bd9Sstevel@tonic-gate }
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate /*
787c478bd9Sstevel@tonic-gate  *  The device id for the mount should be available in
797c478bd9Sstevel@tonic-gate  *  the mount option string as "dev=%04x".  If it's there
807c478bd9Sstevel@tonic-gate  *  extract the device id and avoid having to stat.
817c478bd9Sstevel@tonic-gate  */
827c478bd9Sstevel@tonic-gate static dev_t
devfromopts(struct mntent * mnt)83*e0dfa398SToomas Soome devfromopts(struct mntent *mnt)
847c478bd9Sstevel@tonic-gate {
857c478bd9Sstevel@tonic-gate 	char *str;
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate 	str = hasmntopt(mnt, MNTINFO_DEV);
887c478bd9Sstevel@tonic-gate 	if (str != NULL && (str = strchr(str, '=')))
897c478bd9Sstevel@tonic-gate 		return ((dev_t)strtol(str + 1, (char **)NULL, 16));
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate 	return (NODEV);
927c478bd9Sstevel@tonic-gate }
937c478bd9Sstevel@tonic-gate 
947c478bd9Sstevel@tonic-gate int
partial_mark(int argc,char ** argv)95*e0dfa398SToomas Soome partial_mark(int argc, char **argv)
967c478bd9Sstevel@tonic-gate {
977c478bd9Sstevel@tonic-gate 	char *path;
987c478bd9Sstevel@tonic-gate 	struct stat64 st;
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate 	if (partial == 0)
1017c478bd9Sstevel@tonic-gate 		return (1);
1027c478bd9Sstevel@tonic-gate 
1037c478bd9Sstevel@tonic-gate 	while (--argc >= 0) {
1047c478bd9Sstevel@tonic-gate 		path = *argv++;
1057c478bd9Sstevel@tonic-gate 
1067c478bd9Sstevel@tonic-gate 		if (stat64(path, &st) < 0 ||
107*e0dfa398SToomas Soome 		    st.st_dev != partial_dev) {
1087c478bd9Sstevel@tonic-gate 			msg(gettext("`%s' is not on dump device `%s'\n"),
109*e0dfa398SToomas Soome 			    path, disk);
1107c478bd9Sstevel@tonic-gate 			dumpabort();
1117c478bd9Sstevel@tonic-gate 			/*NOTREACHED*/
1127c478bd9Sstevel@tonic-gate 		}
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate 		if (lf_mark_root(partial_dev, path)) {
1157c478bd9Sstevel@tonic-gate 			msg(gettext(
1167c478bd9Sstevel@tonic-gate 			    "Cannot find filesystem mount point for `%s'\n"),
1177c478bd9Sstevel@tonic-gate 			    path);
1187c478bd9Sstevel@tonic-gate 			dumpabort();
1197c478bd9Sstevel@tonic-gate 			/*NOTREACHED*/
1207c478bd9Sstevel@tonic-gate 		}
1217c478bd9Sstevel@tonic-gate 
1227c478bd9Sstevel@tonic-gate 		/* LINTED this ulimit will always be < INT_MAX */
1237c478bd9Sstevel@tonic-gate 		if (lf_lftw(path, lf_ftw_mark, (int)ulimit(UL_GDESLIM, 0) / 2)
1247c478bd9Sstevel@tonic-gate 		    < 0) {
1257c478bd9Sstevel@tonic-gate 			int saverr = errno;
1267c478bd9Sstevel@tonic-gate 			msg(gettext("Error in %s (%s)\n"),
127*e0dfa398SToomas Soome 			    "ftw", strerror(saverr));
1287c478bd9Sstevel@tonic-gate 			dumpabort();
1297c478bd9Sstevel@tonic-gate 			/*NOTREACHED*/
1307c478bd9Sstevel@tonic-gate 		}
1317c478bd9Sstevel@tonic-gate 	}
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate 	return (0);
1347c478bd9Sstevel@tonic-gate }
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate /* mark directories between target and root */
1377c478bd9Sstevel@tonic-gate static int
lf_mark_root(dev_t dev,char * path)138*e0dfa398SToomas Soome lf_mark_root(dev_t dev, char *path)
1397c478bd9Sstevel@tonic-gate {
1407c478bd9Sstevel@tonic-gate 	struct stat64 st;
1417c478bd9Sstevel@tonic-gate 	char dotdot[MAXPATHLEN + 16];
1427c478bd9Sstevel@tonic-gate 	char *slash;
1437c478bd9Sstevel@tonic-gate 
1447c478bd9Sstevel@tonic-gate 	if (strlen(path) > sizeof (dotdot))
1457c478bd9Sstevel@tonic-gate 		return (1);
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate 	(void) strcpy(dotdot, path);
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate 	if (stat64(dotdot, &st) < 0)
1507c478bd9Sstevel@tonic-gate 		return (1);
1517c478bd9Sstevel@tonic-gate 
1527c478bd9Sstevel@tonic-gate 	/* if target is a regular file, find directory */
1537c478bd9Sstevel@tonic-gate 	if ((st.st_mode & S_IFMT) != S_IFDIR)
1547c478bd9Sstevel@tonic-gate 		if (slash = strrchr(dotdot, '/'))
1557c478bd9Sstevel@tonic-gate 			/* "/file" -> "/" */
1567c478bd9Sstevel@tonic-gate 			if (slash == dotdot)
1577c478bd9Sstevel@tonic-gate 				slash[1] = 0;
1587c478bd9Sstevel@tonic-gate 			/* "dir/file" -> "dir" */
1597c478bd9Sstevel@tonic-gate 			else
1607c478bd9Sstevel@tonic-gate 				slash[0] = 0;
1617c478bd9Sstevel@tonic-gate 		else
1627c478bd9Sstevel@tonic-gate 			/* "file" -> "." */
1637c478bd9Sstevel@tonic-gate 			(void) strcpy(dotdot, ".");
1647c478bd9Sstevel@tonic-gate 
1657c478bd9Sstevel@tonic-gate 	/* keep marking parent until we hit mount point */
1667c478bd9Sstevel@tonic-gate 	do {
1677c478bd9Sstevel@tonic-gate 		if (stat64(dotdot, &st) < 0 ||
168*e0dfa398SToomas Soome 		    (st.st_mode & S_IFMT) != S_IFDIR ||
169*e0dfa398SToomas Soome 		    st.st_dev != dev)
1707c478bd9Sstevel@tonic-gate 			return (1);
1717c478bd9Sstevel@tonic-gate 		markino(st.st_ino);
1727c478bd9Sstevel@tonic-gate 		if (strlen(dotdot) > (sizeof (dotdot) - 4))
1737c478bd9Sstevel@tonic-gate 			return (1);
1747c478bd9Sstevel@tonic-gate 		(void) strcat(dotdot, "/..");
1757c478bd9Sstevel@tonic-gate 	} while (st.st_ino != 2);
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate 	return (0);
1787c478bd9Sstevel@tonic-gate }
1797c478bd9Sstevel@tonic-gate 
1807c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1817c478bd9Sstevel@tonic-gate static int
lf_ftw_mark(const char * name,const struct stat64 * st,int flag)182*e0dfa398SToomas Soome lf_ftw_mark(const char *name, const struct stat64 *st, int flag)
1837c478bd9Sstevel@tonic-gate {
1847c478bd9Sstevel@tonic-gate 	if (flag != FTW_NS) {
1857c478bd9Sstevel@tonic-gate 		/* LINTED ufs only uses the lower 32 bits */
1867c478bd9Sstevel@tonic-gate 		markino((ino_t)st->st_ino);
1877c478bd9Sstevel@tonic-gate 	}
1887c478bd9Sstevel@tonic-gate 	return (0);
1897c478bd9Sstevel@tonic-gate }
1907c478bd9Sstevel@tonic-gate 
1917c478bd9Sstevel@tonic-gate static void
markino(ino_t i)192*e0dfa398SToomas Soome markino(ino_t i)
1937c478bd9Sstevel@tonic-gate {
1947c478bd9Sstevel@tonic-gate 	struct dinode *dp;
1957c478bd9Sstevel@tonic-gate 
1967c478bd9Sstevel@tonic-gate 	dp = getino(ino = i);
1977c478bd9Sstevel@tonic-gate 	mark(dp);
1987c478bd9Sstevel@tonic-gate }
199