[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(®ion_desc->r_name);
+ if (region_desc->r_device_name)
+ ocfs2_free(®ion_desc->r_device_name);
- ret = ocfs2_open(dev,
- OCFS2_FLAG_RO | OCFS2_FLAG_HEARTBEAT_DEV_OK,
- 0, 0, &fs);
- if (ret)
+ ocfs2_free(®ion_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),
+ ®ion_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