From mboxrd@z Thu Jan 1 00:00:00 1970 From: jbrassow@sourceware.org Date: 26 Jun 2006 20:10:54 -0000 Subject: [Cluster-devel] cluster/cmirror-kernel/src dm-clog.c Message-ID: <20060626201054.10518.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit CVSROOT: /cvs/cluster Module name: cluster Changes by: jbrassow at sourceware.org 2006-06-26 20:10:53 Modified files: cmirror-kernel/src: dm-clog.c Log message: - filling out client side logging implementation (patches sent previously) Work remaining: 1) client (kernel) side netlink implementation 2) server implementation Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cmirror-kernel/src/dm-clog.c.diff?cvsroot=cluster&r1=1.1&r2=1.2 --- cluster/cmirror-kernel/src/dm-clog.c 2006/06/21 01:41:43 1.1 +++ cluster/cmirror-kernel/src/dm-clog.c 2006/06/26 20:10:51 1.2 @@ -120,7 +120,9 @@ * * argv contains: * [[no]sync] "block_on_error" - *--------------------------------------------------------------*/ + * + * Returns: 0 on success, -XXX on failure + */ static int cluster_disk_ctr(struct dirty_log *log, struct dm_target *ti, unsigned int argc, char **argv) { @@ -137,29 +139,71 @@ return cluster_ctr(log, ti, argc, argv, 1); } +/* + * cluster_dtr + * @log + */ static void cluster_dtr(struct dirty_log *log) { + int r; struct log_c *lc = (struct log_c *)log->context; - /* FIXME: Send shutdown to server */ + r = dm_clog_consult_server(lc->uuid, DM_CLOG_DTR, + NULL, 0, + NULL, NULL); + + /* FIXME: What do we do on failure? */ kfree(lc); return; } +/* + * cluster_presuspend + * @log + */ static int cluster_presuspend(struct dirty_log *log) { - return -ENOSYS; + int r; + struct log_c *lc = (struct log_c *)log->context; + + r = dm_clog_consult_server(lc->uuid, DM_CLOG_PRESUSPEND, + NULL, 0, + NULL, NULL); + + return (r > 0) ? -r : r; } +/* + * cluster_postsuspend + * @log + */ static int cluster_postsuspend(struct dirty_log *log) { - return -ENOSYS; + int r; + struct log_c *lc = (struct log_c *)log->context; + + r = dm_clog_consult_server(lc->uuid, DM_CLOG_POSTSUSPEND, + NULL, 0, + NULL, NULL); + + return (r > 0) ? -r : r; } +/* + * cluster_resume + * @log + */ static int cluster_resume(struct dirty_log *log) { - return -ENOSYS; + int r; + struct log_c *lc = (struct log_c *)log->context; + + r = dm_clog_consult_server(lc->uuid, DM_CLOG_RESUME, + NULL, 0, + NULL, NULL); + + return (r > 0) ? -r : r; } /* @@ -177,14 +221,55 @@ return lc->region_size; } +/* + * cluster_is_clean + * @log + * @region + * + * Check whether a region is clean. If there is any sort of + * failure when consulting the server, we return not clean. + * + * Returns: 1 if clean, 0 otherwise + */ static int cluster_is_clean(struct dirty_log *log, region_t region) { - return 0; /* not clean for now */ + int r; + int is_clean; + int rdata_size; + struct log_c *lc = (struct log_c *)log->context; + + rdata_size = sizeof(is_clean); + r = dm_clog_consult_server(lc->uuid, DM_CLOG_IS_CLEAN, + (char *)®ion, sizeof(region), + (char *)&is_clean, &rdata_size); + + return (r) ? 0 : is_clean; } +/* + * cluster_is_remote_recovering + * @log + * @region + * + * Check whether a region is being resync'ed on a remote node. + * If there is any sort of failure when consulting the server, + * we assume that the region is being remotely recovered. + * + * Returns: 1 if remote recovering, 0 otherwise + */ static int cluster_is_remote_recovering(struct dirty_log *log, region_t region) { - return 1; /* yes for now */ + int r; + int is_recovering; + int rdata_size; + struct log_c *lc = (struct log_c *)log->context; + + rdata_size = sizeof(is_recovering); + r = dm_clog_consult_server(lc->uuid, DM_CLOG_IS_REMOTE_RECOVERING, + (char *)®ion, sizeof(region), + (char *)&is_recovering, &rdata_size); + + return (r) ? 1 : is_recovering; } /* @@ -193,14 +278,28 @@ * @region * @can_block: if set, return immediately * - * Returns: 1 if in-sync, 0 if not-in-sync, < 0 on error + * Check if the region is in-sync. If there is any sort + * of failure when consulting the server, we assume that + * the region is not in sync. + * + * Returns: 1 if in-sync, 0 if not-in-sync, -EWOULDBLOCK */ static int cluster_in_sync(struct dirty_log *log, region_t region, int can_block) { + int r; + int in_sync; + int rdata_size; + struct log_c *lc = (struct log_c *)log->context; + if (!can_block) return -EWOULDBLOCK; - return 0; /* not in sync for now */ + rdata_size = sizeof(in_sync); + r = dm_clog_consult_server(lc->uuid, DM_CLOG_IN_SYNC, + (char *)®ion, sizeof(region), + (char *)&in_sync, &rdata_size); + + return (r) ? 0 : in_sync; } /* @@ -245,7 +344,7 @@ r = dm_clog_consult_server(lc->uuid, fe->type, (char *)&fe->region, sizeof(fe->region), - NULL, 0); + NULL, NULL); if (r) { r = (r > 0) ? -r : r; goto fail; @@ -253,7 +352,7 @@ } r = dm_clog_consult_server(lc->uuid, DM_CLOG_FLUSH, - NULL, 0, NULL, 0); + NULL, 0, NULL, NULL); if (r) r = (r > 0) ? -r : r; @@ -327,26 +426,115 @@ return; } +/* + * cluster_get_resync_work + * @log + * @region + * + * Get a region that needs recovery. It is valid to return + * an error for this function. + * + * Returns: 1 if region filled, 0 if no work, <0 on error + */ static int cluster_get_resync_work(struct dirty_log *log, region_t *region) { - return -ENOSYS; + int r; + int rdata_size; + struct log_c *lc = (struct log_c *)log->context; + struct { int i; region_t r; } pkg; + + rdata_size = sizeof(pkg); + r = dm_clog_consult_server(lc->uuid, DM_CLOG_GET_RESYNC_WORK, + NULL, 0, + &pkg, &rdata_size); + + r = (r > 0) ? -r : r; + + *region = pkg.r; + + return (r) ? r : pkg.i; } +/* + * cluster_set_region_sync + * @log + * @region + * @in_sync + * + * Set the sync status of a given region. This function + * must not fail. + */ static void cluster_set_region_sync(struct dirty_log *log, region_t region, int in_sync) { + int r; + struct log_c *lc = (struct log_c *)log->context; + struct { region_t r; int i; } pkg; + + pkg.r = region; + pkg.i = in_sync; + + r = dm_clog_consult_server(lc->uuid, DM_CLOG_SET_REGION_SYNC, + &pkg, sizeof(pkg), + NULL, NULL); + + /* FIXME: It would be nice to be able to report failures */ return; } +/* + * cluster_get_sync_count + * @log + * + * If there is any sort of failure when consulting the server, + * we assume that the sync count is zero. + * + * Returns: sync count on success, 0 on failure + */ static region_t cluster_get_sync_count(struct dirty_log *log) { - return 0; + int r; + int rdata_size; + region_t sync_count; + struct log_c *lc = (struct log_c *)log->context; + + rdata_size = sizeof(sync_count); + r = dm_clog_consult_server(lc->uuid, DM_CLOG_GET_SYNC_COUNT, + NULL, 0, + (char *)&sync_count, &rdata_size); + + return (r) ? 0 : sync_count; } +/* + * cluster_status + * @log + * @status_type + * @result + * @maxlen + * + * Returns: amount of space consumed + */ static int cluster_status(struct dirty_log *log, status_type_t status_type, char *result, unsigned int maxlen) { - return -ENOSYS; + int r; + unsigned int sz = maxlen; + struct log_c *lc = (struct log_c *)log->context; + + switch(status) { + case STATUSTYPE_INFO: + r = dm_clog_consult_server(lc->uuid, DM_CLOG_STATUS_INFO, + NULL, 0, + result, &sz); + break; + case STATUSTYPE_TABLE: + r = dm_clog_consult_server(lc->uuid, DM_CLOG_STATUS_INFO, + NULL, 0, + result, &sz); + break; + } + return (r) ? 0: sz; } status int cluster_get_failure_response(struct dirty_log *log)