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