#include <libcfs/util/list.h>
#include <libcfs/util/ioctl.h>
+#include <libcfs/util/string.h>
#include <linux/lustre/lustre_ioctl.h>
#include <linux/lustre/lustre_barrier_user.h>
struct list_head st_list;
/* Target node name. */
char *st_host;
+ char *st_fhost;
/* Where the pool is */
char *st_dir;
/* The target pool name on the target node. */
#define DZFS "%s zfs"
#define DIMPORT "%s zpool import -d %s %s > /dev/null 2>&1"
-#define PRSH(si, st) (si)->si_rsh, (st)->st_host
+#define PRSH(si, st, foreign) (si)->si_rsh, \
+ foreign ? (st)->st_fhost : (st)->st_host
#define PFSNAME(st) (st)->st_pool, (st)->st_filesystem
#define PSSNAME(si, st) PFSNAME(st), (si)->si_ssname
#define PSS_NEW(si, st) PFSNAME(st), (si)->si_new_ssname
{
char *label = NULL;
char *device = NULL;
- char *ignore = NULL;
char *ptr;
char *ptr1;
int len;
int rc;
rc = sscanf(buf, "%ms %ms %ms %ms",
- &st->st_host, &ignore, &label, &device);
+ &st->st_host, &st->st_fhost, &label, &device);
if (rc < 4) {
rc = -EINVAL;
goto out;
}
-
- free(ignore);
+ if (strcmp(st->st_fhost, "-") == 0)
+ st->st_fhost = NULL;
/* Format of device:
* [md|zfs:][pool_dir/]<pool>/<filesystem> */
if (*ptr == '/') {
ptr1 = strrchr(ptr, '/');
*ptr1 = '\0';
- len = strlen(ptr);
- st->st_dir = malloc(len + 1);
+ st->st_dir = strdup(ptr);
if (!st->st_dir) {
rc = -ENOMEM;
goto out;
}
-
- strncpy(st->st_dir, ptr, len);
- st->st_dir[len] = '\0';
ptr = ptr1 + 1;
}
- len = strlen(ptr);
- st->st_pool = malloc(len + 1);
+ st->st_pool = strdup(ptr);
if (!st->st_pool) {
rc = -ENOMEM;
goto out;
}
- strncpy(st->st_pool, ptr, len);
- st->st_pool[len] = '\0';
-
/* Format of label:
* fsname-<role><index> or <role><index> */
- ptr = strchr(label, '-');
+ ptr = strrchr(label, '-');
if (ptr) {
if (strncmp(si->si_fsname, label, ptr - label) != 0) {
/* This line is NOT for current filesystem .*/
if (is_ldev) {
rc = snapshot_load_conf_ldev(si, buf, st, &role);
} else {
- rc = sscanf(buf, "%ms %ms %ms %ms %ms %d",
- &st->st_host, &st->st_dir, &st->st_pool,
- &st->st_filesystem, &role, &st->st_index);
- if (rc < 6)
+ rc = sscanf(buf, "%ms %ms %ms %ms %ms %ms %d",
+ &st->st_host, &st->st_fhost, &st->st_dir,
+ &st->st_pool, &st->st_filesystem, &role,
+ &st->st_index);
+ if (rc < 7)
rc = -EINVAL;
+
+ if (strcmp(st->st_fhost, "-") == 0)
+ st->st_fhost = NULL;
}
if (rc < 0)
if (rc) {
if (st->st_host)
free(st->st_host);
+ if (st->st_fhost)
+ free(st->st_fhost);
if (st->st_dir)
free(st->st_dir);
if (st->st_pool)
struct snapshot_target *st;
while (!list_empty(&si->si_mdts_list)) {
- st = list_entry(si->si_mdts_list.next,
- struct snapshot_target, st_list);
+ st = list_first_entry(&si->si_mdts_list,
+ struct snapshot_target, st_list);
list_del(&st->st_list);
free(st->st_host);
+ free(st->st_fhost);
free(st->st_dir);
free(st->st_pool);
free(st->st_filesystem);
}
while (!list_empty(&si->si_osts_list)) {
- st = list_entry(si->si_osts_list.next,
- struct snapshot_target, st_list);
+ st = list_first_entry(&si->si_osts_list,
+ struct snapshot_target, st_list);
list_del(&st->st_list);
free(st->st_host);
+ free(st->st_fhost);
free(st->st_dir);
free(st->st_pool);
free(st->st_filesystem);
static int snapshot_handle_string_option(char **dst, const char *option,
const char *opt_name)
{
- int len;
-
if (*dst && *dst != snapshot_rsh_default) {
fprintf(stderr,
"%s option has been specified repeatedly.\n", opt_name);
return -EINVAL;
}
- len = strlen(option);
- *dst = malloc(len + 1);
+ *dst = strdup(option);
if (!*dst)
return -ENOMEM;
-
- strncpy(*dst, option, len);
- (*dst)[len] = '\0';
return 0;
}
rc = waitpid(st->st_pid, &st->st_status, 0);
if (rc < 0) {
SNAPSHOT_ADD_LOG(si, "Can't wait child (%d) operation "
- "on the target <%s:%x:%d>: %s\n",
- st->st_pid, st->st_host, st->st_role,
- st->st_index, strerror(errno));
+ "on the target <%s(%s):%x:%d>: %s\n",
+ st->st_pid, st->st_host,
+ st->st_fhost ? st->st_fhost : "none",
+ st->st_role, st->st_index,
+ strerror(errno));
count++;
if (*err == 0)
*err = rc;
}
} else if (WIFSIGNALED(st->st_status)) {
SNAPSHOT_ADD_LOG(si, "The child (%d) operation on the "
- "target <%s:%x:%d> was killed by "
+ "target <%s(%s):%x:%d> was killed by "
"signal %d\n",
- st->st_pid, st->st_host, st->st_role,
- st->st_index, WTERMSIG(st->st_status));
+ st->st_pid, st->st_host,
+ st->st_fhost ? st->st_fhost : "none",
+ st->st_role, st->st_index,
+ WTERMSIG(st->st_status));
count++;
if (*err == 0)
*err = -EINTR;
} else {
SNAPSHOT_ADD_LOG(si, "The child (%d) operation on the "
- "target <%s:%x:%d> failed for "
+ "target <%s(%s):%x:%d> failed for "
"unknown reason\n",
- st->st_pid, st->st_host, st->st_role,
- st->st_index);
+ st->st_pid, st->st_host,
+ st->st_fhost ? st->st_fhost : "none",
+ st->st_role, st->st_index);
count++;
if (*err == 0)
*err = -EFAULT;
static int mdt0_is_lustre_snapshot(struct snapshot_instance *si)
{
struct snapshot_target *st = si->si_mdt0;
- char buf[MAX_BUF_SIZE];
+ char buf[MAX_BUF_SIZE * 3];
FILE *fp;
int rc;
-
+ int foreign = 0;
+again:
memset(buf, 0, sizeof(buf));
snprintf(buf, sizeof(buf) - 1,
DRSH" '"DIMPORT"; "DZFS
- " get -H -o value lustre:magic "DSSNAME"'",
- PRSH(si, st), PIMPORT(st), PZFS(st), PSSNAME(si, st));
+ " get -H -o value lustre:magic "DSSNAME"' 2>/dev/null",
+ PRSH(si, st, foreign), PIMPORT(st), PZFS(st), PSSNAME(si, st));
+
fp = popen(buf, "r");
if (!fp) {
SNAPSHOT_ADD_LOG(si, "Popen fail to check snapshot "
}
if (snapshot_fgets(fp, buf, strlen(SNAPSHOT_MAGIC) + 1) == NULL) {
- rc = -EINVAL;
+ if (foreign || !st->st_fhost) {
+ rc = -EINVAL;
+ } else {
+ foreign = 1;
+ pclose(fp);
+ goto again;
+ }
} else if (strcmp(buf, SNAPSHOT_MAGIC) == 0) {
rc = 0;
} else {
FILE *fp;
char *ptr;
int rc = 0;
+ int foreign = 0;
+again:
memset(buf, 0, sizeof(buf));
snprintf(buf, sizeof(buf) - 1,
- DRSH" 'mount'",
- PRSH(si, st));
+ DRSH" 'mount' 2>/dev/null",
+ PRSH(si, st, foreign));
fp = popen(buf, "r");
if (!fp) {
SNAPSHOT_ADD_LOG(si, "Popen fail to check target mount: %s\n",
}
pclose(fp);
+ if (!rc && !foreign && st->st_fhost) {
+ foreign = 1;
+ goto again;
+ }
return rc;
}
char *fsname, int fslen)
{
struct snapshot_target *st = si->si_mdt0;
- char buf[MAX_BUF_SIZE];
+ char buf[MAX_BUF_SIZE * 3];
FILE *fp;
- int rc = 0;
-
+ int rc;
+ int foreign = 0;
+again:
+ rc = 0;
memset(buf, 0, sizeof(buf));
snprintf(buf, sizeof(buf) - 1,
DRSH" '"DIMPORT"; "DZFS
- " get -H -o value lustre:fsname "DSSNAME"'",
- PRSH(si, st), PIMPORT(st), PZFS(st), PSSNAME(si, st));
+ " get -H -o value lustre:fsname "DSSNAME"' 2>/dev/null",
+ PRSH(si, st, foreign), PIMPORT(st), PZFS(st),
+ PSSNAME(si, st));
fp = popen(buf, "r");
if (!fp) {
SNAPSHOT_ADD_LOG(si, "Popen fail to get fsname: %s\n",
rc = -EINVAL;
pclose(fp);
+
+ if (rc && !foreign && st->st_fhost) {
+ foreign = 1;
+ goto again;
+ }
return rc;
}
static int snapshot_get_mgsnode(struct snapshot_instance *si,
char *node, int size)
{
- char buf[MAX_BUF_SIZE];
+ char buf[MAX_BUF_SIZE * 2];
struct snapshot_target *st;
FILE *fp;
- int rc = 0;
+ int rc;
+ int foreign = 0;
- st = list_entry(si->si_osts_list.next, struct snapshot_target,
- st_list);
+ st = list_first_entry(&si->si_osts_list, struct snapshot_target,
+ st_list);
+again:
+ rc = 0;
memset(buf, 0, sizeof(buf));
snprintf(buf, sizeof(buf) - 1,
- DRSH" '"DZFS" get -H -o value lustre:mgsnode "DFSNAME"'",
- PRSH(si, st), PZFS(st), PFSNAME(st));
+ DRSH" '"DZFS" get -H -o value lustre:mgsnode "DFSNAME"'"
+ " 2>/dev/null", PRSH(si, st, foreign), PZFS(st),
+ PFSNAME(st));
fp = popen(buf, "r");
if (!fp) {
SNAPSHOT_ADD_LOG(si, "Popen fail to get mgsnode: %s\n",
rc = -EINVAL;
pclose(fp);
+
+ if (rc && !foreign && st->st_fhost) {
+ foreign = 1;
+ goto again;
+ }
+
return rc;
}
static int snapshot_exists_check(struct snapshot_instance *si,
struct snapshot_target *st)
{
- char buf[MAX_BUF_SIZE];
+ char buf[MAX_BUF_SIZE * 2];
FILE *fp;
int rc = 0;
-
+ int foreign = 0;
+again:
memset(buf, 0, sizeof(buf));
snprintf(buf, sizeof(buf) - 1,
- DRSH" '"DZFS" list "DSSNAME" 2>/dev/null'",
- PRSH(si, st), PZFS(st), PSSNAME(si, st));
+ DRSH" '"DZFS" list "DSSNAME"' 2>/dev/null",
+ PRSH(si, st, foreign), PZFS(st), PSSNAME(si, st));
fp = popen(buf, "r");
if (!fp) {
SNAPSHOT_ADD_LOG(si, "Popen fail to create check: %s\n",
rc = -EEXIST;
pclose(fp);
+
+ if (rc != -EEXIST && !foreign && st->st_fhost) {
+ foreign = 1;
+ goto again;
+ }
return rc;
}
struct snapshot_target *st,
char *cmd, int size)
{
- char buf[MAX_BUF_SIZE];
+ char buf[MAX_BUF_SIZE * 3];
FILE *fp;
int len = 0;
int rc = 0;
-
+ int foreign = 0;
+again:
memset(buf, 0, sizeof(buf));
snprintf(buf, sizeof(buf) - 1,
DRSH" \""DIMPORT"; "DZFS
" get all "DFSNAME" | grep lustre: | grep local$ | "
"awk '{ \\$1=\\\"\\\"; \\$NF=\\\"\\\"; print \\$0 }' | "
- "sed -e 's/^ //'\"",
- PRSH(si, st), PIMPORT(st), PZFS(st), PFSNAME(st));
+ "sed -e 's/^ //'\" 2>/dev/null",
+ PRSH(si, st, foreign), PIMPORT(st), PZFS(st), PFSNAME(st));
fp = popen(buf, "r");
if (!fp) {
SNAPSHOT_ADD_LOG(si, "Popen fail to list one: %s\n",
while (snapshot_fgets(fp, buf, MAX_BUF_SIZE) != NULL) {
char *ptr;
char *end;
-
+ foreign = 1;
if (strncmp(buf, "lustre:fsname",
strlen("lustre:fsname")) == 0)
continue;
if (end)
*end = '\0';
- rc = snprintf(cmd + len, size - len - 1,
- "-o %s=\"%s\" ", buf, ptr);
+ rc = scnprintf(cmd + len, size - len - 1,
+ "-o %s=\"%s\" ", buf, ptr);
if (rc <= 0)
return -EOVERFLOW;
}
pclose(fp);
+ if (!foreign && st->st_fhost) {
+ foreign = 1;
+ goto again;
+ }
return len;
}
if (pid < 0) {
SNAPSHOT_ADD_LOG(si, "Can't fork for create snapshot "
"(%s@%s <%s>) on the target "
- "(%s:%x:%d): %s\n",
+ "(%s(%s):%x:%d): %s\n",
fsname, si->si_ssname,
si->si_comment, st->st_host,
+ st->st_fhost ? st->st_fhost : "none",
st->st_role, st->st_index,
strerror(errno));
return pid;
if (pid == 0) {
char cmd[MAX_BUF_SIZE];
int len;
-
+ int foreign = 0;
+again:
memset(cmd, 0, sizeof(cmd));
- len = snprintf(cmd, sizeof(cmd) - 1,
- DRSH" '"DZFS" snapshot "
- "-o lustre:fsname=%s "
- "-o lustre:magic=%s "
- "-o lustre:ctime=%llu "
- "-o lustre:mtime=%llu ",
- PRSH(si, st), PZFS(st), fsname,
- SNAPSHOT_MAGIC, xtime, xtime);
+ len = scnprintf(cmd, sizeof(cmd) - 1,
+ DRSH" '"DZFS" snapshot "
+ "-o lustre:fsname=%s "
+ "-o lustre:magic=%s "
+ "-o lustre:ctime=%llu "
+ "-o lustre:mtime=%llu ",
+ PRSH(si, st, foreign), PZFS(st),
+ fsname, SNAPSHOT_MAGIC,
+ (unsigned long long)xtime,
+ (unsigned long long)xtime);
if (len <= 0)
exit(-EOVERFLOW);
if (si->si_comment) {
- rc = snprintf(cmd + len, sizeof(cmd) - len - 1,
- "-o lustre:comment=\"%s\" ",
- si->si_comment);
+ rc = scnprintf(cmd + len, sizeof(cmd) - len - 1,
+ "-o lustre:comment=\"%s\" ",
+ si->si_comment);
if (rc <= 0)
exit(-EOVERFLOW);
if (rc < 0) {
SNAPSHOT_ADD_LOG(si, "Can't filter property on "
"target (%s:%x:%d): rc = %d\n",
+ foreign ? st->st_fhost :
st->st_host, st->st_role,
st->st_index, rc);
-
exit(rc);
}
if (st->st_role & SR_OST)
rc = snprintf(cmd + len, sizeof(cmd) - len - 1,
"-o lustre:svname=%s-OST%04x "
- "-o lustre:mgsnode=%s "DSSNAME"'",
+ "-o lustre:mgsnode=%s "DSSNAME"'"
+ " 2>/dev/null",
fsname, st->st_index, mgsnode,
PSSNAME(si, st));
else if (!(st->st_role & SR_MGS) ||
si->si_mdt0 == si->si_mgs)
rc = snprintf(cmd + len, sizeof(cmd) - len - 1,
"-o lustre:svname=%s-MDT%04x "
- "-o lustre:mgsnode=%s "DSSNAME"'",
+ "-o lustre:mgsnode=%s "DSSNAME"'"
+ " 2>/dev/null",
fsname, st->st_index, mgsnode,
PSSNAME(si, st));
else
/* separated MGS */
rc = snprintf(cmd + len, sizeof(cmd) - len - 1,
- DSSNAME"'", PSSNAME(si, st));
+ DSSNAME"' 2>/dev/null",
+ PSSNAME(si, st));
if (rc <= 0)
exit(-EOVERFLOW);
rc = snapshot_exec(cmd);
- if (rc)
+ if (rc) {
SNAPSHOT_ADD_LOG(si, "Can't execute \"%s\" on "
"target (%s:%x:%d): rc = %d\n",
- cmd, st->st_host, st->st_role,
+ cmd, foreign ? st->st_fhost :
+ st->st_host, st->st_role,
st->st_index, rc);
+ if (!foreign && st->st_fhost) {
+ foreign = 1;
+ goto again;
+ }
+ }
exit(rc);
} /* end of child */
pid = fork();
if (pid < 0) {
SNAPSHOT_ADD_LOG(si, "Can't fork for check snapshot "
- "%s on the target (%s:%x:%d): %s\n",
+ "%s on the target (%s(%s):%x:%d): "
+ "%s\n",
si->si_ssname, st->st_host,
+ st->st_fhost ? st->st_fhost : "none",
st->st_role, st->st_index,
strerror(errno));
return pid;
pid = fork();
if (pid < 0) {
SNAPSHOT_ADD_LOG(si, "Can't fork for destroy snapshot "
- "%s on the target (%s:%x:%d): %s\n",
+ "%s on the target (%s(%s):%x:%d): "
+ "%s\n",
si->si_ssname, st->st_host,
+ st->st_fhost ? st->st_fhost : "none",
st->st_role, st->st_index,
strerror(errno));
return pid;
/* child */
if (pid == 0) {
- char cmd[MAX_BUF_SIZE];
-
+ char cmd[MAX_BUF_SIZE * 2];
+ int foreign = 0;
+again:
memset(cmd, 0, sizeof(cmd));
if (si->si_force)
snprintf(cmd, sizeof(cmd) - 1,
DRSH" 'umount -f "DSSNAME
" > /dev/null 2>&1; "DZFS
- " destroy -f "DSSNAME"'",
- PRSH(si, st), PSSNAME(si, st),
- PZFS(st), PSSNAME(si, st));
+ " destroy -f "DSSNAME"'"
+ " 2>/dev/null",
+ PRSH(si, st, foreign),
+ PSSNAME(si, st), PZFS(st),
+ PSSNAME(si, st));
else
snprintf(cmd, sizeof(cmd) - 1,
- DRSH" '"DZFS" destroy "DSSNAME"'",
- PRSH(si, st), PZFS(st),
+ DRSH" '"DZFS" destroy "DSSNAME"'"
+ " 2>/dev/null",
+ PRSH(si, st, foreign), PZFS(st),
PSSNAME(si, st));
rc = snapshot_exec(cmd);
- if (rc)
+ if (rc) {
SNAPSHOT_ADD_LOG(si, "Can't execute \"%s\" on "
"target (%s:%x:%d): rc = %d\n",
- cmd, st->st_host, st->st_role,
+ cmd, foreign ? st->st_fhost :
+ st->st_host, st->st_role,
st->st_index, rc);
+ if (!foreign && st->st_fhost) {
+ foreign = 1;
+ goto again;
+ }
+ }
exit(rc);
} /* end of child */
if (pid < 0) {
SNAPSHOT_ADD_LOG(si, "Can't fork for modify snapshot "
"(%s|%s, <%s>) on the target "
- "(%s:%x:%d): %s\n",
+ "(%s(%s):%x:%d): %s\n",
si->si_ssname, si->si_new_ssname,
si->si_comment, st->st_host,
+ st->st_fhost ? st->st_fhost : "none",
st->st_role, st->st_index,
strerror(errno));
return pid;
/* child */
if (pid == 0) {
- char cmd[MAX_BUF_SIZE];
-
+ char cmd[MAX_BUF_SIZE * 5];
+ int foreign = 0;
+again:
memset(cmd, 0, sizeof(cmd));
if (si->si_new_ssname && si->si_comment)
snprintf(cmd, sizeof(cmd) - 1,
DSSNAME" "DSSNAME" && "DZFS
" set lustre:comment=\"%s\" "DSSNAME
" && "DZFS
- " set lustre:mtime=%llu "DSSNAME"'",
- PRSH(si, st), PIMPORT(st), PZFS(st),
- PSSNAME(si, st), PSS_NEW(si, st),
- PZFS(st), si->si_comment,
- PSS_NEW(si, st), PZFS(st), xtime,
+ " set lustre:mtime=%llu "DSSNAME"'"
+ " 2>/dev/null",
+ PRSH(si, st, foreign), PIMPORT(st),
+ PZFS(st), PSSNAME(si, st),
+ PSS_NEW(si, st), PZFS(st),
+ si->si_comment, PSS_NEW(si, st),
+ PZFS(st), (unsigned long long)xtime,
PSS_NEW(si, st));
else if (si->si_new_ssname)
snprintf(cmd, sizeof(cmd) - 1,
DRSH" '"DIMPORT"; "DZFS
" rename "DSSNAME" "DSSNAME" && "DZFS
- " set lustre:mtime=%llu "DSSNAME"'",
- PRSH(si, st), PIMPORT(st), PZFS(st),
- PSSNAME(si, st), PSS_NEW(si, st),
- PZFS(st), xtime, PSS_NEW(si, st));
+ " set lustre:mtime=%llu "DSSNAME"'"
+ " 2>/dev/null",
+ PRSH(si, st, foreign), PIMPORT(st),
+ PZFS(st), PSSNAME(si, st),
+ PSS_NEW(si, st), PZFS(st),
+ (unsigned long long)xtime,
+ PSS_NEW(si, st));
else if (si->si_comment)
snprintf(cmd, sizeof(cmd) - 1,
DRSH" '"DIMPORT"; "DZFS
" set lustre:comment=\"%s\" "DSSNAME
- " && "DZFS
- " set lustre:mtime=%llu "DSSNAME"'",
- PRSH(si, st), PIMPORT(st), PZFS(st),
- si->si_comment, PSSNAME(si, st),
- PZFS(st), xtime, PSSNAME(si, st));
+ " && "DZFS " set lustre:mtime=%llu "
+ DSSNAME"' 2>/dev/null",
+ PRSH(si, st, foreign), PIMPORT(st),
+ PZFS(st), si->si_comment,
+ PSSNAME(si, st), PZFS(st),
+ (unsigned long long)xtime,
+ PSSNAME(si, st));
else
exit(-EINVAL);
rc = snapshot_exec(cmd);
- if (rc)
+ if (rc) {
SNAPSHOT_ADD_LOG(si, "Can't execute \"%s\" on "
"target (%s:%x:%d): rc = %d\n",
- cmd, st->st_host, st->st_role,
+ cmd, foreign ? st->st_fhost :
+ st->st_host, st->st_role,
st->st_index, rc);
+ if (!foreign && st->st_fhost) {
+ foreign = 1;
+ goto again;
+ }
+ }
exit(rc);
} /* end of child */
static int snapshot_list_one(struct snapshot_instance *si,
struct snapshot_target *st)
{
- char buf[MAX_BUF_SIZE];
+ char buf[MAX_BUF_SIZE * 3];
FILE *fp;
int rc;
+ int foreign = 0;
+again:
memset(buf, 0, sizeof(buf));
snprintf(buf, sizeof(buf) - 1,
DRSH" \""DIMPORT"; "DZFS
" get all "DSSNAME" | grep lustre: | grep local$ | "
"awk '{ \\$1=\\\"\\\"; \\$NF=\\\"\\\"; print \\$0 }' | "
- "sed -e 's/^ //'\"",
- PRSH(si, st), PIMPORT(st), PZFS(st), PSSNAME(si, st));
+ "sed -e 's/^ //'\" 2>/dev/null",
+ PRSH(si, st, foreign), PIMPORT(st), PZFS(st),
+ PSSNAME(si, st));
fp = popen(buf, "r");
if (!fp) {
SNAPSHOT_ADD_LOG(si, "Popen fail to list one: %s\n",
return -errno;
}
- if (si->si_detail) {
+ if (si->si_detail && !foreign) {
char name[8];
snapshot_role2name(name, st->st_role, st->st_index);
while (snapshot_fgets(fp, buf, MAX_BUF_SIZE) != NULL) {
__u64 xtime;
char *ptr;
+ foreign = 1;
if (strncmp(buf, "lustre:fsname",
strlen("lustre:fsname")) == 0) {
strlen("lustre:ctime")) == 0) {
ptr = snapshot_first_skip_blank(buf);
if (ptr) {
- sscanf(ptr, "%llu", &xtime);
+ xtime = (__u64)strtoull(ptr, NULL, 10);
printf("create_time: %s",
ctime((time_t *)&xtime));
}
strlen("lustre:mtime")) == 0) {
ptr = snapshot_first_skip_blank(buf);
if (ptr) {
- sscanf(ptr, "%llu", &xtime);
+ xtime = (__u64)strtoull(ptr, NULL, 10);
printf("modify_time: %s",
ctime((time_t *)&xtime));
}
}
pclose(fp);
+ if (!foreign && st->st_fhost) {
+ foreign = 1;
+ goto again;
+ }
rc = target_is_mounted(si, st, si->si_ssname);
if (rc < 0)
printf("status: unknown\n");
struct list_head list_sub_items;
struct list_sub_item *lsi;
- char buf[MAX_BUF_SIZE];
+ char buf[MAX_BUF_SIZE * 2];
FILE *fp;
int rc = 0;
+ int foreign = 0;
INIT_LIST_HEAD(&list_sub_items);
+again:
memset(buf, 0, sizeof(buf));
snprintf(buf, sizeof(buf) - 1,
DRSH" \""DZFS" get -H -r lustre:magic "DFSNAME
- " | grep %s | awk '{ print \\$1 }' | cut -d@ -f2\"",
- PRSH(si, st), PZFS(st), PFSNAME(st), SNAPSHOT_MAGIC);
+ " | grep %s | awk '{ print \\$1 }' | cut -d@ -f2\" "
+ " 2>/dev/null",
+ PRSH(si, st, foreign), PZFS(st), PFSNAME(st),
+ SNAPSHOT_MAGIC);
fp = popen(buf, "r");
if (!fp) {
SNAPSHOT_ADD_LOG(si, "Popen fail to list ssnames: %s\n",
while (snapshot_fgets(fp, buf, MAX_BUF_SIZE) != NULL) {
int len = strlen(buf);
+ foreign = 1;
lsi = malloc(len + 1 + sizeof(struct list_sub_item));
if (!lsi) {
break;
}
- strncpy(lsi->lsi_ssname, buf, len);
- lsi->lsi_ssname[len] = '\0';
+ memcpy(lsi->lsi_ssname, buf, len + 1);
list_add(&lsi->lsi_list, &list_sub_items);
}
pclose(fp);
+ if (!foreign && st->st_fhost) {
+ foreign = 1;
+ goto again;
+ }
while (!list_empty(&list_sub_items)) {
- lsi = list_entry(list_sub_items.next,
- struct list_sub_item, lsi_list);
+ lsi = list_first_entry(&list_sub_items,
+ struct list_sub_item, lsi_list);
list_del(&lsi->lsi_list);
if (!rc) {
si->si_ssname = lsi->lsi_ssname;
static int snapshot_mount_target(struct snapshot_instance *si,
struct snapshot_target *st, const char *optstr)
{
- char cmd[MAX_BUF_SIZE];
+ char cmd[MAX_BUF_SIZE * 2];
char name[8];
int rc;
+ int foreign = 0;
rc = target_is_mounted(si, st, si->si_ssname);
if (rc < 0)
if (rc > 0)
return -ESRCH;
- memset(cmd, 0, sizeof(cmd));
memset(name, 0, sizeof(name));
snapshot_role2name(name, st->st_role, st->st_index);
+again:
+ memset(cmd, 0, sizeof(cmd));
snprintf(cmd, sizeof(cmd) - 1,
DRSH" '"DIMPORT"; mkdir -p /mnt/%s_%s && mount -t lustre "
- "-o rdonly_dev%s "DSSNAME" /mnt/%s_%s'",
- PRSH(si, st), PIMPORT(st), si->si_ssname, name,
+ "-o rdonly_dev%s "DSSNAME" /mnt/%s_%s' 2>/dev/null",
+ PRSH(si, st, foreign), PIMPORT(st), si->si_ssname, name,
st != si->si_mdt0 ? "" : optstr, PSSNAME(si, st),
si->si_ssname, name);
rc = snapshot_exec(cmd);
- if (rc)
+ if (rc) {
SNAPSHOT_ADD_LOG(si, "Can't execute \"%s\" on the target "
- "(%s:%x:%d): rc = %d\n", cmd, st->st_host,
+ "(%s:%x:%d): rc = %d\n",
+ cmd, foreign ? st->st_fhost : st->st_host,
st->st_role, st->st_index, rc);
+ if (!foreign && st->st_fhost) {
+ foreign = 1;
+ goto again;
+ }
+ }
return rc;
}
pid = fork();
if (pid < 0) {
SNAPSHOT_ADD_LOG(si, "Can't fork for mount snapshot "
- "%s on target (%s:%x:%d): %s\n",
+ "%s on target (%s(%s):%x:%d): %s\n",
si->si_ssname, st->st_host,
+ st->st_fhost ? st->st_fhost : "none",
st->st_role, st->st_index,
strerror(errno));
return pid;
if (si->si_mgs == si->si_mdt0)
mdt0_mounted = true;
+ } else {
+ si->si_mgs->st_ignored = 1;
}
/* 2. Mount MDT0 if it is not combined with the MGS. */
si->si_mdt0->st_ignored = 0;
si->si_mdt0->st_pid = 0;
rc = snapshot_mount_target(si, si->si_mdt0, ",nomgs");
+ if (rc == -ESRCH) {
+ si->si_mdt0->st_ignored = 1;
+ rc = 0;
+ }
if (rc)
goto cleanup;
}
pid = fork();
if (pid < 0) {
SNAPSHOT_ADD_LOG(si, "Can't fork for umount snapshot "
- "%s on target (%s:%x:%d): %s\n",
+ "%s on target (%s(%s):%x:%d): %s\n",
si->si_ssname, st->st_host,
+ st->st_fhost ? st->st_fhost : "none",
st->st_role, st->st_index,
strerror(errno));
return pid;
/* child */
if (pid == 0) {
char cmd[MAX_BUF_SIZE];
+ int foreign = 0;
rc = target_is_mounted(si, st, si->si_ssname);
if (rc < 0)
if (!rc)
exit(-ESRCH);
-
+again:
memset(cmd, 0, sizeof(cmd));
snprintf(cmd, sizeof(cmd) - 1,
- DRSH" 'umount "DSSNAME"'",
- PRSH(si, st), PSSNAME(si, st));
+ DRSH" 'umount "DSSNAME"' 2>/dev/null",
+ PRSH(si, st, foreign), PSSNAME(si, st));
rc = snapshot_exec(cmd);
+ if (rc && !foreign && st->st_fhost) {
+ foreign = 1;
+ goto again;
+ }
exit(rc);
}