summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReza Sabdar <Reza.Sabdar@Sun.COM>2010-05-08 13:27:30 -0400
committerReza Sabdar <Reza.Sabdar@Sun.COM>2010-05-08 13:27:30 -0400
commit5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2 (patch)
treee498da6478fb2c02f44c0b4299ee804cf70d0ee6
parentfcbfa62b65cede474ae89b4667e84130611d0ba7 (diff)
downloadillumos-joyent-5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2.tar.gz
6940623 ndmp should back up block/character devices
6947357 ndmp should use deferred snapshot destroy
-rw-r--r--usr/src/cmd/ndmpd/tlm/tlm_backup_reader.c54
-rw-r--r--usr/src/cmd/ndmpd/tlm/tlm_lib.c4
-rw-r--r--usr/src/cmd/ndmpd/tlm/tlm_restore_writer.c69
3 files changed, 96 insertions, 31 deletions
diff --git a/usr/src/cmd/ndmpd/tlm/tlm_backup_reader.c b/usr/src/cmd/ndmpd/tlm/tlm_backup_reader.c
index 4e279bc068..c677572015 100644
--- a/usr/src/cmd/ndmpd/tlm/tlm_backup_reader.c
+++ b/usr/src/cmd/ndmpd/tlm/tlm_backup_reader.c
@@ -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 @@ static int output_xattr_header(char *fname,
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 @@ output_file_header(char *name, char *link,
} 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 @@ tlm_output_xattr(char *dir, char *name, char *chkdir,
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 @@ tlm_output_file(char *dir, char *name, char *chkdir,
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);
diff --git a/usr/src/cmd/ndmpd/tlm/tlm_lib.c b/usr/src/cmd/ndmpd/tlm/tlm_lib.c
index b4704dfa61..14801cb75e 100644
--- a/usr/src/cmd/ndmpd/tlm/tlm_lib.c
+++ b/usr/src/cmd/ndmpd/tlm/tlm_lib.c
@@ -1251,9 +1251,9 @@ chkpnt_backup_successful(char *volname, char *jname, boolean_t recursive,
}
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) {
diff --git a/usr/src/cmd/ndmpd/tlm/tlm_restore_writer.c b/usr/src/cmd/ndmpd/tlm/tlm_restore_writer.c
index 966354f27f..9dd11fff33 100644
--- a/usr/src/cmd/ndmpd/tlm/tlm_restore_writer.c
+++ b/usr/src/cmd/ndmpd/tlm/tlm_restore_writer.c
@@ -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 @@ static int create_sym_link(char *dst,
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 @@ tar_getdir(tlm_commands_t *commands,
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 @@ create_hard_link(char *name_old, char *name_new,
/*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 @@ create_sym_link(char *dst, char *target, tlm_acls_t *acls,
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_sym_link(char *dst, char *target, tlm_acls_t *acls,
}
/*
- * 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);
}
/*