changeset 12353:9b7835aa98d4

6940623 ndmp should back up block/character devices 6947357 ndmp should use deferred snapshot destroy
author Reza Sabdar <Reza.Sabdar@Sun.COM>
date Sat, 08 May 2010 13:27:30 -0400
parents 7e55397422a9
children 6693c22bc83a
files usr/src/cmd/ndmpd/tlm/tlm_backup_reader.c usr/src/cmd/ndmpd/tlm/tlm_lib.c usr/src/cmd/ndmpd/tlm/tlm_restore_writer.c
diffstat 3 files changed, 96 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/ndmpd/tlm/tlm_backup_reader.c	Fri May 07 17:54:23 2010 -0700
+++ b/usr/src/cmd/ndmpd/tlm/tlm_backup_reader.c	Sat May 08 13:27:30 2010 -0400
@@ -1,6 +1,5 @@
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
@@ -46,6 +45,7 @@
 #include <archives.h>
 #include <tlm.h>
 #include <sys/fs/zfs.h>
+#include <sys/mkdev.h>
 #include <libzfs.h>
 #include <libcmdutils.h>
 #include <pwd.h>
@@ -74,6 +74,8 @@
 extern  libzfs_handle_t *zlibh;
 extern	mutex_t zlib_mtx;
 
+#define	S_ISPECIAL(a)	(S_ISLNK(a) || S_ISFIFO(a) || S_ISBLK(a) || \
+	S_ISCHR(a))
 
 /*
  * output_mem
@@ -497,19 +499,39 @@
 	} else {
 		(void) strlcpy(tar_hdr->th_linkname, link, TLM_NAME_SIZE);
 	}
-	if (S_ISDIR(attr->st_mode)) {
+	switch (attr->st_mode & S_IFMT) {
+	case S_IFDIR:
 		tar_hdr->th_linkflag = LF_DIR;
-	} else if (S_ISFIFO(attr->st_mode)) {
+		break;
+	case S_IFIFO:
 		tar_hdr->th_linkflag = LF_FIFO;
-	} else if (attr->st_nlink > 1) {
-		/* mark file with hardlink LF_LINK */
-		tar_hdr->th_linkflag = LF_LINK;
-		(void) snprintf(tar_hdr->th_shared.th_hlink_ino,
-		    sizeof (tar_hdr->th_shared.th_hlink_ino),
-		    "%011llo ", attr->st_ino);
-	} else {
-		tar_hdr->th_linkflag = *link == 0 ? LF_NORMAL : LF_SYMLINK;
-		NDMP_LOG(LOG_DEBUG, "linkflag: '%c'", tar_hdr->th_linkflag);
+		break;
+	case S_IFBLK:
+	case S_IFCHR:
+		if (S_ISBLK(attr->st_mode))
+			tar_hdr->th_linkflag = LF_BLK;
+		else
+			tar_hdr->th_linkflag = LF_CHR;
+		(void) snprintf(tar_hdr->th_shared.th_dev.th_devmajor,
+		    sizeof (tar_hdr->th_shared.th_dev.th_devmajor), "%06o ",
+		    major(attr->st_rdev));
+		(void) snprintf(tar_hdr->th_shared.th_dev.th_devminor,
+		    sizeof (tar_hdr->th_shared.th_dev.th_devminor), "%06o ",
+		    minor(attr->st_rdev));
+		break;
+	default:
+		if (attr->st_nlink > 1) {
+			/* mark file with hardlink LF_LINK */
+			tar_hdr->th_linkflag = LF_LINK;
+			(void) snprintf(tar_hdr->th_shared.th_hlink_ino,
+			    sizeof (tar_hdr->th_shared.th_hlink_ino),
+			    "%011llo ", attr->st_ino);
+		} else {
+			tar_hdr->th_linkflag = *link == 0 ? LF_NORMAL :
+			    LF_SYMLINK;
+			NDMP_LOG(LOG_DEBUG, "linkflag: '%c'",
+			    tar_hdr->th_linkflag);
+		}
 	}
 	(void) snprintf(tar_hdr->th_size, sizeof (tar_hdr->th_size), "%011o ",
 	    (long)attr->st_size);
@@ -628,8 +650,7 @@
 	char *fnamep;
 	int rv = 0;
 
-	if (S_ISLNK(tlm_acls->acl_attr.st_mode) ||
-	    S_ISFIFO(tlm_acls->acl_attr.st_mode)) {
+	if (S_ISPECIAL(tlm_acls->acl_attr.st_mode)) {
 		return (TLM_NO_SOURCE_FILE);
 	}
 
@@ -866,8 +887,7 @@
 	pos = tlm_get_data_offset(local_commands);
 	NDMP_LOG(LOG_DEBUG, "pos: %10lld  [%s]", pos, name);
 
-	if (S_ISLNK(tlm_acls->acl_attr.st_mode) ||
-	    S_ISFIFO(tlm_acls->acl_attr.st_mode)) {
+	if (S_ISPECIAL(tlm_acls->acl_attr.st_mode)) {
 		if (S_ISLNK(tlm_acls->acl_attr.st_mode)) {
 			file_size = tlm_readlink(fullname, snapname, linkname,
 			    TLM_MAX_PATH_NAME-1);
--- a/usr/src/cmd/ndmpd/tlm/tlm_lib.c	Fri May 07 17:54:23 2010 -0700
+++ b/usr/src/cmd/ndmpd/tlm/tlm_lib.c	Sat May 08 13:27:30 2010 -0400
@@ -1251,9 +1251,9 @@
 	}
 
 	if (recursive) {
-		err = zfs_destroy_snaps(zhp, jname, B_FALSE);
+		err = zfs_destroy_snaps(zhp, jname, B_TRUE);
 	} else {
-		err = zfs_destroy(zhp, B_FALSE);
+		err = zfs_destroy(zhp, B_TRUE);
 	}
 
 	if (err) {
--- a/usr/src/cmd/ndmpd/tlm/tlm_restore_writer.c	Fri May 07 17:54:23 2010 -0700
+++ b/usr/src/cmd/ndmpd/tlm/tlm_restore_writer.c	Sat May 08 13:27:30 2010 -0400
@@ -1,6 +1,5 @@
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
@@ -44,6 +43,7 @@
 #include <time.h>
 #include <sys/types.h>
 #include <sys/acl.h>
+#include <sys/mkdev.h>
 #include <utime.h>
 #include <unistd.h>
 #include <pthread.h>
@@ -100,8 +100,12 @@
     char *target,
     tlm_acls_t *,
     tlm_job_stats_t *);
-static int create_fifo(char *name,
-    tlm_acls_t *);
+static int create_special(char,
+    char *name,
+    tlm_acls_t *,
+    int,
+    int,
+    tlm_job_stats_t *);
 static long load_acl_info(int lib,
     int	drv,
     long size,
@@ -861,13 +865,20 @@
 			longlink[0] = 0;
 			break;
 		case LF_FIFO:
+		case LF_BLK:
+		case LF_CHR:
 			file_name = *longname == 0 ? thname_buf :
 			    longname;
 			if (is_file_wanted(file_name, sels, exls, flags,
 			    &mchtype, &pos)) {
 				nmp = rs_new_name(rnp, name, pos, file_name);
 				if (nmp) {
-					erc = create_fifo(nmp, acls);
+					erc = create_special(
+					    tar_hdr->th_linkflag, nmp, acls,
+					    oct_atoi(tar_hdr->th_shared.
+					    th_dev.th_devmajor),
+					    oct_atoi(tar_hdr->th_shared.
+					    th_dev.th_devminor), job_stats);
 					if (erc == 0 &&
 					    PM_EXACT_OR_CHILD(mchtype))
 						(void) tlm_entry_restored(
@@ -1858,7 +1869,7 @@
 /*ARGSUSED*/
 static int
 create_sym_link(char *dst, char *target, tlm_acls_t *acls,
-    tlm_job_stats_t *job_satats)
+    tlm_job_stats_t *job_stats)
 {
 	int erc;
 	struct stat64 *st;
@@ -1869,7 +1880,7 @@
 	st = &acls->acl_attr;
 	erc = symlink(target, dst);
 	if (erc) {
-		job_satats->js_errors++;
+		job_stats->js_errors++;
 		NDMP_LOG(LOG_DEBUG, "error %d (errno %d) softlink [%s] to [%s]",
 		    erc, errno, dst, target);
 	} else {
@@ -1881,14 +1892,48 @@
 }
 
 /*
- * create a new FIFO
+ * create a new FIFO, char/block device special files
  */
 static int
-create_fifo(char *name, tlm_acls_t *acls)
+create_special(char flag, char *name, tlm_acls_t *acls, int major, int minor,
+    tlm_job_stats_t *job_stats)
 {
-	(void) mknod(name, 0777 + S_IFIFO, 0);
-	set_acl(name, acls);
-	return (0);
+	dev_t dev;
+	mode_t mode;
+	int erc;
+
+	switch (flag) {
+	case LF_CHR:
+		mode = S_IFCHR;
+		dev = makedev(major, minor);
+		break;
+	case LF_BLK:
+		mode = S_IFBLK;
+		dev = makedev(major, minor);
+		break;
+	case LF_FIFO:
+		mode = S_IFIFO;
+		dev = 0;
+		break;
+	default:
+		NDMP_LOG(LOG_ERR, "unsupported flag %d", flag);
+		return (-1);
+	}
+
+	/* Remove the old entry first */
+	if (rmdir(name) < 0) {
+		if (errno == ENOTDIR)
+			(void) unlink(name);
+	}
+	erc = mknod(name, 0777 | mode, dev);
+	if (erc) {
+		job_stats->js_errors++;
+		NDMP_LOG(LOG_DEBUG, "error %d (errno %d) mknod [%s] major"
+		    " %d minor %d", erc, errno, name, major, minor);
+	} else {
+		set_acl(name, acls);
+	}
+	return (erc);
 }
 
 /*