master - gfs_controld: fix and implement remount
David Teigland
teigland@fedoraproject.org
Tue Sep 9 22:08:00 GMT 2008
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=71b12c2d7fb85304154a816b187450926a027d9b
Commit: 71b12c2d7fb85304154a816b187450926a027d9b
Parent: 7e1804f040eedb0899245fb71bb79395f5be86d3
Author: David Teigland <teigland@redhat.com>
AuthorDate: Tue Sep 9 15:47:56 2008 -0500
Committer: David Teigland <teigland@redhat.com>
CommitterDate: Tue Sep 9 15:47:56 2008 -0500
gfs_controld: fix and implement remount
Fixes problem with remount request mount.gfs was making; it wasn't
specifying the locktable, causing a segfault.
Implement the remount routines in the new cpg mode.
Signed-off-by: David Teigland <teigland@redhat.com>
---
gfs2/mount/util.c | 11 +++++-
group/gfs_controld/cpg-new.c | 37 +++++++++++++++++++++
group/gfs_controld/cpg-old.c | 37 +++------------------
group/gfs_controld/gfs_daemon.h | 5 ++-
group/gfs_controld/main.c | 68 +++++++++++++++++++++++++++-----------
5 files changed, 102 insertions(+), 56 deletions(-)
diff --git a/gfs2/mount/util.c b/gfs2/mount/util.c
index 48b0b39..404cbf1 100644
--- a/gfs2/mount/util.c
+++ b/gfs2/mount/util.c
@@ -514,8 +514,10 @@ int lock_dlm_remount(struct mount_options *mo, struct gen_sb *sb)
memset(&ma, 0, sizeof(ma));
- /* FIXME: how to check for spectator remounts, we want
- to disallow remount to/from spectator */
+ if (strstr(mo->extra, "spectator")) {
+ warn("spectator remounts not allowed");
+ return -1;
+ }
if (mo->flags & MS_RDONLY)
mode = "ro";
@@ -525,6 +527,11 @@ int lock_dlm_remount(struct mount_options *mo, struct gen_sb *sb)
strncpy(ma.dir, mo->dir, PATH_MAX);
strncpy(ma.type, fsname, PATH_MAX);
strncpy(ma.options, mode, PATH_MAX);
+ if (mo->locktable[0])
+ strncpy(ma.table, mo->locktable, PATH_MAX);
+ else
+ strncpy(ma.table, sb->locktable, PATH_MAX);
+
fd = gfsc_fs_connect();
if (fd < 0) {
diff --git a/group/gfs_controld/cpg-new.c b/group/gfs_controld/cpg-new.c
index cfe0cf6..fdc58ba 100644
--- a/group/gfs_controld/cpg-new.c
+++ b/group/gfs_controld/cpg-new.c
@@ -27,6 +27,7 @@ enum {
GFS_MSG_MOUNT_DONE = 2,
GFS_MSG_FIRST_RECOVERY_DONE = 3,
GFS_MSG_RECOVERY_RESULT = 4,
+ GFS_MSG_REMOUNT = 5,
};
/* gfs_header flags */
@@ -243,6 +244,8 @@ static char *msg_name(int type)
return "first_recovery_done";
case GFS_MSG_RECOVERY_RESULT:
return "recovery_result";
+ case GFS_MSG_REMOUNT:
+ return "remount";
default:
return "unknown";
}
@@ -1226,6 +1229,18 @@ static void send_recovery_result(struct mountgroup *mg, int jid, int result)
free(buf);
}
+void send_remount(struct mountgroup *mg, struct gfsc_mount_args *ma)
+{
+ struct gfs_header h;
+
+ memset(&h, 0, sizeof(h));
+
+ h.type = GFS_MSG_REMOUNT;
+ h.msgdata = strstr(ma->options, "ro") ? 1 : 0;
+
+ gfs_send_message(mg, (char *)&h, sizeof(h));
+}
+
static void save_message(struct mountgroup *mg, struct gfs_header *hd, int len)
{
struct change *cg;
@@ -1350,6 +1365,25 @@ static void receive_first_recovery_done(struct mountgroup *mg,
}
}
+static void receive_remount(struct mountgroup *mg, struct gfs_header *hd,
+ int len)
+{
+ struct node *node;
+
+ log_group(mg, "receive_remount from %d ro %d", hd->nodeid, hd->msgdata);
+
+ node = get_node_history(mg, hd->nodeid);
+ if (!node) {
+ log_error("receive_remount no nodeid %d", hd->nodeid);
+ return;
+ }
+
+ node->ro = hd->msgdata;
+
+ if (hd->nodeid == our_nodeid)
+ mg->ro = node->ro;
+}
+
/* start message from all nodes shows zero started_count */
static int all_nodes_new(struct mountgroup *mg)
@@ -2282,6 +2316,9 @@ static void deliver_cb(cpg_handle_t handle, struct cpg_name *group_name,
else
receive_recovery_result(mg, hd, len);
break;
+ case GFS_MSG_REMOUNT:
+ receive_remount(mg, hd, len);
+ break;
default:
log_error("unknown msg type %d", hd->type);
}
diff --git a/group/gfs_controld/cpg-old.c b/group/gfs_controld/cpg-old.c
index 56e4f08..517e222 100644
--- a/group/gfs_controld/cpg-old.c
+++ b/group/gfs_controld/cpg-old.c
@@ -611,11 +611,12 @@ static void receive_recovery_done(struct mountgroup *mg, char *buf, int len,
set_sysfs(mg, "block", 0);
}
-static void send_remount(struct mountgroup *mg, int ro)
+void send_remount_old(struct mountgroup *mg, struct gfsc_mount_args *ma)
{
struct gdlm_header *hd;
- int len;
char *buf;
+ int len;
+ int ro = strstr(ma->options, "ro") ? 1 : 0;
len = sizeof(struct gdlm_header) + MAX_OPTIONS_LEN;
@@ -631,7 +632,7 @@ static void send_remount(struct mountgroup *mg, int ro)
strcpy(buf+sizeof(struct gdlm_header), ro ? "ro" : "rw");
- log_group(mg, "send_remount len %d \"%s\"", len,
+ log_group(mg, "send_remount_old len %d \"%s\"", len,
buf+sizeof(struct gdlm_header));
send_group_message_old(mg, len, buf);
@@ -685,7 +686,7 @@ static void receive_remount(struct mountgroup *mg, char *buf, int len, int from)
mg->rw = memb->rw;
mg->ro = memb->readonly;
}
- client_reply_remount(mg, result);
+ client_reply_remount(mg, mg->remount_client, result);
}
log_group(mg, "receive_remount from %d rw=%d ro=%d opts=%x",
@@ -1702,34 +1703,6 @@ int process_recovery_uevent_old(char *table)
return 0;
}
-int remount_mountgroup_old(int ci, struct gfsc_mount_args *ma)
-{
- struct mountgroup *mg;
- char *name = strstr(ma->table, ":") + 1;
- int ro = 0, rw = 0;
-
- log_debug("remount: %s ci %d", name, ci);
-
- if (!strncmp(ma->options, "ro", 2))
- ro = 1;
- else
- rw = 1;
-
- mg = find_mg(name);
- if (!mg) {
- log_error("remount: %s not found", name);
- return -1;
- }
-
- /* no change */
- if ((mg->ro && ro) || (mg->rw && rw))
- return 1;
-
- mg->remount_client = ci;
- send_remount(mg, ro);
- return 0;
-}
-
void gfs_leave_mountgroup_old(char *name, int mnterr)
{
struct mountgroup *mg;
diff --git a/group/gfs_controld/gfs_daemon.h b/group/gfs_controld/gfs_daemon.h
index 3cda467..135574f 100644
--- a/group/gfs_controld/gfs_daemon.h
+++ b/group/gfs_controld/gfs_daemon.h
@@ -226,6 +226,7 @@ void process_mountgroups(void);
int gfs_join_mountgroup(struct mountgroup *mg);
void gfs_leave_mountgroup(char *name, int mnterr);
void gfs_mount_done(struct mountgroup *mg);
+void send_remount(struct mountgroup *mg, struct gfsc_mount_args *ma);
int set_mountgroup_info(struct mountgroup *mg, struct gfsc_mountgroup *out);
int set_node_info(struct mountgroup *mg, int nodeid, struct gfsc_node *node);
int set_mountgroups(int *count, struct gfsc_mountgroup **mgs_out);
@@ -243,7 +244,7 @@ void save_message_old(struct mountgroup *mg, char *buf, int len, int from,
void send_withdraw_old(struct mountgroup *mg);
int process_recovery_uevent_old(char *table);
void ping_kernel_mount_old(char *table);
-int remount_mountgroup_old(int ci, struct gfsc_mount_args *ma);
+void send_remount_old(struct mountgroup *mg, struct gfsc_mount_args *ma);
void send_mount_status_old(struct mountgroup *mg);
int do_stop(struct mountgroup *mg);
int do_finish(struct mountgroup *mg);
@@ -275,7 +276,7 @@ void client_back(int ci, int fd);
struct mountgroup *create_mg(char *name);
struct mountgroup *find_mg(char *name);
struct mountgroup *find_mg_id(uint32_t id);
-void client_reply_remount(struct mountgroup *mg, int result);
+void client_reply_remount(struct mountgroup *mg, int ci, int result);
void client_reply_join(int ci, struct gfsc_mount_args *ma, int result);
void client_reply_join_full(struct mountgroup *mg, int result);
void query_lock(void);
diff --git a/group/gfs_controld/main.c b/group/gfs_controld/main.c
index 5881961..ba456d5 100644
--- a/group/gfs_controld/main.c
+++ b/group/gfs_controld/main.c
@@ -567,19 +567,6 @@ static void query_mountgroup_nodes(int fd, char *name, int option, int max)
free(nodes);
}
-void client_reply_remount(struct mountgroup *mg, int result)
-{
- struct gfsc_mount_args *ma = &mg->mount_args;
-
- log_group(mg, "client_reply_remount ci %d result %d",
- mg->remount_client, result);
-
- do_reply(client[mg->remount_client].fd, GFSC_CMD_FS_REMOUNT,
- mg->name, result, ma, sizeof(struct gfsc_mount_args));
-
- mg->remount_client = 0;
-}
-
void client_reply_join(int ci, struct gfsc_mount_args *ma, int result)
{
char *name = strstr(ma->table, ":") + 1;
@@ -778,6 +765,53 @@ static void do_mount_done(char *table, int result)
gfs_mount_done(mg);
}
+void client_reply_remount(struct mountgroup *mg, int ci, int result)
+{
+ do_reply(client[ci].fd, GFSC_CMD_FS_REMOUNT, mg->name, result,
+ &mg->mount_args, sizeof(struct gfsc_mount_args));
+}
+
+/* mount.gfs creates a special ma->options string with only "ro" or "rw" */
+
+static void do_remount(int ci, struct gfsc_mount_args *ma)
+{
+ struct mountgroup *mg;
+ char *name = strstr(ma->table, ":") + 1;
+ int ro = 0, result = 0;
+
+ log_debug("remount: %s ci %d options %s", name, ci, ma->options);
+
+ mg = find_mg(name);
+ if (!mg) {
+ log_error("remount: %s not found", name);
+ result = -1;
+ goto out;
+ }
+
+ if (mg->spectator) {
+ log_error("remount of spectator not allowed");
+ result = -1;
+ goto out;
+ }
+
+ if (!strcmp(ma->options, "ro"))
+ ro = 1;
+
+ if ((mg->ro && ro) || (!mg->ro && !ro))
+ goto out;
+
+ if (group_mode == GROUP_LIBGROUP) {
+ /* the receive calls client_reply_remount */
+ mg->remount_client = ci;
+ send_remount_old(mg, ma);
+ return;
+ }
+
+ send_remount(mg, ma);
+ out:
+ client_reply_remount(mg, ci, result);
+}
+
void process_connection(int ci)
{
struct gfsc_header h;
@@ -847,13 +881,7 @@ void process_connection(int ci)
break;
case GFSC_CMD_FS_REMOUNT:
- if (group_mode == GROUP_LIBGROUP)
- remount_mountgroup_old(ci, ma);
-#if 0
- /* FIXME */
- else
- remount_mountgroup(ci, ma);
-#endif
+ do_remount(ci, ma);
break;
default:
More information about the Cluster-cvs
mailing list