[Ocfs2-tools-commits] jlbec commits r957 - trunk/ocfs2_hb_ctl

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Thu Jun 16 22:27:35 CDT 2005


Author: jlbec
Date: 2005-06-16 22:27:33 -0500 (Thu, 16 Jun 2005)
New Revision: 957

Modified:
   trunk/ocfs2_hb_ctl/ocfs2_hb_ctl.c
Log:

o Teach ocfs2_hb_ctl to start by uuid



Modified: trunk/ocfs2_hb_ctl/ocfs2_hb_ctl.c
===================================================================
--- trunk/ocfs2_hb_ctl/ocfs2_hb_ctl.c	2005-06-17 01:05:49 UTC (rev 956)
+++ trunk/ocfs2_hb_ctl/ocfs2_hb_ctl.c	2005-06-17 03:27:33 UTC (rev 957)
@@ -1,4 +1,6 @@
-/*
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
  * ocfs2_hb_ctl.c  Utility to start / stop heartbeat on demand
  *
  * Copyright (C) 2005 Oracle.  All rights reserved.
@@ -21,12 +23,47 @@
  * Authors: Mark Fasheh
  */
 
-#include "ocfs2_hb_ctl.h"
 
-#include "o2cb.h"
+#define _XOPEN_SOURCE 600  /* Triggers XOPEN2K in features.h */
+#define _LARGEFILE64_SOURCE
+#define _GNU_SOURCE /* Because libc really doesn't want us using O_DIRECT? */
+
+#include <sys/types.h>
+#include <inttypes.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/stat.h>
 #include <signal.h>
 
+#include <ocfs2.h>
+#include <ocfs2_fs.h>
+
+#include "o2cb.h"
+
+#define DEV_PREFIX      "/dev/"
+#define PROC_IDE_FORMAT "/proc/ide/%s/media"
+
+enum hb_ctl_action {
+	HB_ACTION_UNKNOWN,
+	HB_ACTION_USAGE,
+	HB_ACTION_START,
+	HB_ACTION_STOP,
+	HB_ACTION_REFINFO,
+};
+
+struct hb_ctl_options {
+	enum hb_ctl_action action;
+	char *dev_str;
+	char *uuid_str;
+};
+
+
 static char *progname = "ocfs2_hb_ctl";
+static struct o2cb_region_desc *region_desc = NULL;
 
 static void block_signals(int how)
 {
@@ -38,84 +75,241 @@
      sigprocmask(how, &sigs, NULL);
 }
 
-static errcode_t get_uuid(char *dev, char *uuid)
+static void free_desc(void)
 {
-	ocfs2_filesys *fs = NULL;
-	errcode_t ret;
+	if (region_desc) {
+		if (region_desc->r_name)
+			ocfs2_free(&region_desc->r_name);
+		if (region_desc->r_device_name)
+			ocfs2_free(&region_desc->r_device_name);
 
-	ret = ocfs2_open(dev,
-                         OCFS2_FLAG_RO | OCFS2_FLAG_HEARTBEAT_DEV_OK,
-                         0, 0, &fs);
-	if (ret)
+		ocfs2_free(&region_desc);
+		region_desc = NULL;
+	}
+}
+			   
+static errcode_t get_desc(const char *dev)
+{
+	errcode_t err = 0;
+	ocfs2_filesys *fs;
+
+	if (region_desc)
 		goto out;
 
-	strcpy(uuid, fs->uuid_str);
+	err = ocfs2_malloc0(sizeof(struct o2cb_region_desc),
+			    &region_desc);
+	if (err)
+		goto out;
 
+	err = ocfs2_open(dev,
+			 OCFS2_FLAG_RO | OCFS2_FLAG_HEARTBEAT_DEV_OK,
+			 0, 0, &fs);
+	if (err)
+		goto out;
+
+	err = ocfs2_fill_heartbeat_desc(fs, region_desc);
+	if (!err) {
+		region_desc->r_name = strdup(region_desc->r_name);
+		region_desc->r_device_name = strdup(region_desc->r_device_name);
+		if (!region_desc->r_name || !region_desc->r_device_name)
+			err = OCFS2_ET_NO_MEMORY;
+	} else {
+		region_desc->r_name = NULL;
+		region_desc->r_device_name = NULL;
+	}
+
 	ocfs2_close(fs);
 
 out:
+	if (err)
+		free_desc();
+
+	return err;
+}
+
+static errcode_t get_uuid(char *dev, char *uuid)
+{
+	errcode_t ret;
+
+	ret = get_desc(dev);
+	if (!ret) 
+		strcpy(uuid, region_desc->r_name);
+
 	return ret;
 }
 
-static errcode_t start_heartbeat(char *device)
+static errcode_t compare_dev(const char *dev,
+			     struct hb_ctl_options *hbo)
 {
 	errcode_t err;
-	ocfs2_filesys *fs = NULL;
-	struct o2cb_region_desc desc;
+	int len;
+	char *device;
 
-	err = ocfs2_open(device, OCFS2_FLAG_RO | OCFS2_FLAG_HEARTBEAT_DEV_OK,
-			 0, 0, &fs);
-	if (err)
-		goto bail;
+	if (region_desc) {
+		fprintf(stderr, "We have a descriptor already!\n");
+		free_desc();
+	}
+	
+	len = strlen(DEV_PREFIX) + strlen(dev) + 1;
+	device = malloc(sizeof(char) * len);
+	if (!device)
+		return OCFS2_ET_NO_MEMORY;
+	snprintf(device, len, DEV_PREFIX "%s", dev);
 
-	err = ocfs2_fill_heartbeat_desc(fs, &desc);
-	if (err)
-		goto bail;
+	/* Any problem with getting the descriptor is NOT FOUND */
+	err = OCFS2_ET_FILE_NOT_FOUND;
+	if (get_desc(device))
+		goto out;
 
-	err = o2cb_start_heartbeat_region_perm(NULL, &desc);
+	if (!strcmp(region_desc->r_name, hbo->uuid_str)) {
+		hbo->dev_str = device;
+		err = 0;
+	} else
+		free_desc();
 
-bail:
-	if (fs)
-		ocfs2_close(fs);
+out:
+	if (err && device)
+		free(device);
 
 	return err;
 }
 
-static errcode_t stop_heartbeat(const char *hbuuid)
+static int as_ide_disk(const char *dev_name)
 {
+    FILE *f;
+    int is_disk = 1;
+    size_t len;
+    char *proc_name;
+
+    len = strlen(PROC_IDE_FORMAT) + strlen(dev_name);
+    proc_name = (char *)malloc(sizeof(char) * len);
+    if (!proc_name)
+        return 0;
+
+    snprintf(proc_name, len, PROC_IDE_FORMAT, dev_name);
+    
+    /* If not ide, file won't exist */
+    f = fopen(proc_name, "r");
+    if (f)
+    {
+        if (fgets(proc_name, len, f))
+        {
+            /* IDE devices we don't want to probe */
+            if (!strncmp(proc_name, "cdrom", strlen("cdrom")) ||
+                !strncmp(proc_name, "tape", strlen("tape")))
+                is_disk = 0;
+        }
+        fclose(f);
+    }
+
+    free(proc_name);
+
+    return is_disk;
+}  /* as_ide_disk() */
+
+
+/* Um, wow, this is, like, one big hardcode */
+static errcode_t scan_devices(errcode_t (*func)(const char *,
+						struct hb_ctl_options *),
+			      struct hb_ctl_options *hbo)
+{
+	errcode_t err = 0;
+	int rc, major, minor;
+	FILE *f;
+	char *buffer, *name;
+
+	buffer = (char *)malloc(sizeof(char) * (PATH_MAX + 1));
+	if (!buffer)
+		return OCFS2_ET_NO_MEMORY;
+
+	name = (char *)malloc(sizeof(char) * (PATH_MAX + 1));
+	if (!name)
+	{
+		free(buffer);
+		return OCFS2_ET_NO_MEMORY;
+	}
+
+	f = fopen("/proc/partitions", "r");
+	if (!f)
+	{
+		rc = -errno;
+		goto out_free;
+	}
+
+	err = OCFS2_ET_FILE_NOT_FOUND;
+	while (1)
+	{
+		if ((fgets(buffer, PATH_MAX + 1, f)) == NULL)
+			break;
+
+		name[0] = '\0';
+		major = minor = 0;
+
+		/* FIXME: If this is bad, send patches */
+		if (sscanf(buffer, "%d %d %*d %99[^ \t\n]",
+			   &major, &minor, name) < 3)
+			continue;
+
+		if (*name && major)
+		{
+			if (!as_ide_disk(name))
+				continue;
+			
+			err = func(name, hbo);
+			if (!err || (err != OCFS2_ET_FILE_NOT_FOUND))
+				break;
+		}
+	}
+
+	fclose(f);
+
+out_free:
+	free(buffer);
+	free(name);
+
+	return err;
+}  /* scan_devices() */
+
+static errcode_t lookup_dev(struct hb_ctl_options *hbo)
+{
+	return scan_devices(compare_dev, hbo);
+}
+
+static errcode_t start_heartbeat(struct hb_ctl_options *hbo)
+{
+	errcode_t err = 0;
+
+	if (!hbo->dev_str)
+		err = lookup_dev(hbo);
+	if (!err) {
+		err = o2cb_start_heartbeat_region_perm(NULL,
+						       region_desc);
+	}
+
+	return err;
+}
+
+static errcode_t stop_heartbeat(struct hb_ctl_options *hbo)
+{
 	errcode_t err;
 
-	err = o2cb_stop_heartbeat_region_perm(NULL, hbuuid);
+	err = o2cb_stop_heartbeat_region_perm(NULL, hbo->uuid_str);
 
 	return err;
 }
 
-static errcode_t print_hb_ref_info(const char *hbuuid)
+static errcode_t print_hb_ref_info(struct hb_ctl_options *hbo)
 {
 	errcode_t err;
 	int num;
 
-	err = o2cb_num_region_refs(hbuuid, &num);
+	err = o2cb_num_region_refs(hbo->uuid_str, &num);
 	if (!err)
-		printf("%s: %d refs\n", hbuuid, num);
+		printf("%s: %d refs\n", hbo->uuid_str, num);
 
 	return err;
 }
 
-enum hb_ctl_action {
-	HB_ACTION_UNKNOWN,
-	HB_ACTION_USAGE,
-	HB_ACTION_START,
-	HB_ACTION_STOP,
-	HB_ACTION_REFINFO,
-};
-
-struct hb_ctl_options {
-	enum hb_ctl_action action;
-	char *dev_str;
-	char *uuid_str;
-};
-
 static int read_options(int argc, char **argv, struct hb_ctl_options *hbo)
 {
 	int c, ret;
@@ -171,8 +365,9 @@
 
 	switch (hbo->action) {
 	case HB_ACTION_START:
-		/* We can't start by uuid yet. */
-		if (hbo->uuid_str || !hbo->dev_str)
+		/* For start must specify exactly one of uuid or device. */
+		if ((hbo->uuid_str && hbo->dev_str) ||
+		    (!hbo->uuid_str && !hbo->dev_str))
 			ret = -EINVAL;
 		break;
 
@@ -207,6 +402,7 @@
 	FILE *output = err ? stderr : stdout;
 
 	fprintf(output, "Usage: %s -S -d <device>\n", progname);
+	fprintf(output, "       %s -S -u <uuid>\n", progname);
 	fprintf(output, "       %s -K -d <device>\n", progname);
 	fprintf(output, "       %s -K -u <uuid>\n", progname);
 	fprintf(output, "       %s -I -d <device>\n", progname);
@@ -272,7 +468,7 @@
 		break;
 
 	case HB_ACTION_START:
-		err = start_heartbeat(hbo.dev_str);
+		err = start_heartbeat(&hbo);
 		if (err) {
 			com_err(progname, err, "while starting heartbeat");
 			ret = -EINVAL;
@@ -280,7 +476,7 @@
 		break;
 
 	case HB_ACTION_STOP:
-		err = stop_heartbeat(hbo.uuid_str);
+		err = stop_heartbeat(&hbo);
 		if (err) {
 			com_err(progname, err, "while stopping heartbeat");
 			ret = -EINVAL;
@@ -288,7 +484,7 @@
 		break;
 
 	case HB_ACTION_REFINFO:
-		err = print_hb_ref_info(hbo.uuid_str);
+		err = print_hb_ref_info(&hbo);
 		if (err) {
 			com_err(progname, err, "while reading reference counts");
 			ret = -EINVAL;
@@ -301,5 +497,6 @@
 	block_signals(SIG_UNBLOCK);
 
 bail:
+	free_desc();
 	return ret ? 1 : 0;
 }



More information about the Ocfs2-tools-commits mailing list