DragonFly kernel List (threaded) for 2008-10
DragonFly BSD
DragonFly kernel List (threaded) for 2008-10
[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]

Re: Side-project feature request for 'hammer mirror-*' functions


From: Michael Neumann <mneumann@xxxxxxxx>
Date: Fri, 10 Oct 2008 17:54:37 +0200
Cc: Matthew Dillon <dillon@xxxxxxxxxxxxxxxxxxxx>

Michael Neumann wrote:
Matthew Dillon wrote:
    If someone has the time, this is a really simple feature request.
    Ok, yah, I could do it myself, but I'm going to offer it to others
    first and that might save me a little time :-)

It's simple. If you do a hammer mirror-copy or hammer mirror-stream
to a target HAMMER filesystem the code checks that the target is a PFS
slave with the same shared UUID as the master's UUID.


    I want a feature that asks the user whether he wants to create a
    conforming PFS on the target at that point, if the target directory
    does not exist, instead of exiting with an error.

i.e. this would take away all the effort of having to create a pfs-slave
and assign the correct UUID to it. It takes about 60 seconds and some
cutting and pasting to do that manually now... not long, but we can
make it ultra convenient.


You would simply run the command and it would ask if you wanted to create
a new PFS on the target instead of exiting. You would say 'yes', and
poof, new mirror slave target :-).

Appended is a first patch. I'm unsure if this is the correct way to do it, as the protocol is modified, and I think it's not easily possible to read "yes" or "no" from the keyboard in mirror-write (when run via ssh).

Funny, when I run mirror-copy several times I get a panic (screenshot appended). I don't think this can be related to my changes...

This appended patch is even easier.


Regards,

Michael

Index: cmd_mirror.c
===================================================================
RCS file: /home/dcvs/src/sbin/hammer/cmd_mirror.c,v
retrieving revision 1.15
diff -u -r1.15 cmd_mirror.c
--- cmd_mirror.c	9 Sep 2008 23:34:21 -0000	1.15
+++ cmd_mirror.c	10 Oct 2008 15:49:43 -0000
@@ -106,6 +106,11 @@
 	bwcount = 0;
 
 	/*
+	 * Send initial header for the purpose of determining shared-uuid.
+	 */
+	generate_mrec_header(fd, 1, pfs.pfs_id, NULL, NULL);
+
+	/*
 	 * In 2-way mode the target will send us a PFS info packet
 	 * first.  Use the target's current snapshot TID as our default
 	 * begin TID.
@@ -298,6 +303,33 @@
 	fprintf(stderr, "Mirror-read %s succeeded\n", filesystem);
 }
 
+static void
+create_pfs(const char *filesystem, uuid_t *s_uuid)
+{
+	fprintf(stderr, "PFS slave %s does not exist. Do you want" 
+			" to create id? (yes|no) ", filesystem);
+	fflush(stderr);
+	/* XXX: How to read from keyboard? */
+
+	u_int32_t status;
+	char *shared_uuid = NULL;
+	uuid_to_string(s_uuid, &shared_uuid, &status);
+
+	char *cmd = NULL;
+	asprintf(&cmd, "/sbin/hammer pfs-slave '%s' shared-uuid=%s 1>&2",
+		 filesystem, shared_uuid); 
+	free(shared_uuid);
+
+	if (cmd == NULL) {
+		fprintf(stderr, "Failed to alloc memory\n");
+		exit(1);
+	}
+	if (system(cmd) != 0) {
+		fprintf(stderr, "Failed to create PFS\n");
+	}
+	free(cmd);
+}
+
 /*
  * Pipe the mirroring data stream on stdin to the HAMMER VFS, adding
  * some additional packet types to negotiate TID ranges and to verify
@@ -334,6 +366,7 @@
 	struct hammer_ioc_synctid synctid;
 	union hammer_ioc_mrecord_any mrec_tmp;
 	hammer_ioc_mrecord_any_t mrec;
+	struct stat st;
 	int error;
 	int fd;
 	int n;
@@ -351,6 +384,40 @@
 	hammer_key_end_init(&mirror.key_end);
 	mirror.key_end = mirror.key_beg;
 
+	/*
+	 * Read initial packet
+	 */
+	mrec = read_mrecord(0, &error, &pickup);
+	if (mrec == NULL) {
+		if (error == 0)
+			fprintf(stderr, "validate_mrec_header: short read\n");
+		exit(1);
+	}
+	/*
+	 * Validate packet
+	 */
+	if (mrec->head.type == HAMMER_MREC_TYPE_TERM) {
+		return;
+	}
+	if (mrec->head.type != HAMMER_MREC_TYPE_PFSD) {
+		fprintf(stderr, "validate_mrec_header: did not get expected "
+				"PFSD record type\n");
+		exit(1);
+	}
+	if (mrec->head.rec_size != sizeof(mrec->pfs)) {
+		fprintf(stderr, "validate_mrec_header: unexpected payload "
+				"size\n");
+		exit(1);
+	}
+
+	/*
+	 * Create slave PFS if it doesn't yet exist
+	 */
+	if (lstat(filesystem, &st) != 0) {
+		create_pfs(filesystem, &mrec->pfs.pfsd.shared_uuid);
+	}
+	free(mrec); mrec = NULL;
+
 	fd = getpfs(&pfs, filesystem);
 
 	/*


[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]