[DRBD-cvs] r1682 - trunk/user

svn at svn.drbd.org svn at svn.drbd.org
Wed Dec 15 20:48:33 CET 2004


Author: phil
Date: 2004-12-15 20:48:31 +0100 (Wed, 15 Dec 2004)
New Revision: 1682

Modified:
   trunk/user/drbdadm.h
   trunk/user/drbdadm_adjust.c
   trunk/user/drbdadm_main.c
   trunk/user/drbdmeta.c
   trunk/user/drbdsetup.c
   trunk/user/drbdtool_common.c
   trunk/user/drbdtool_common.h
Log:
* Moved a bit of code into drbdtool_common.c
* drbdadm_main no longer uses stat()
* dt_lock_open_drbd() should now be udev aware ==
  uses a sane heuristik to guess device major/minor numbers.
* use the major(), minor() and makedev() macros from 
  the include files.
* implemented outdate in drbdmeta
* drbdadm outdate now uses drbdsetup _AND_ drbdmeta


Modified: trunk/user/drbdadm.h
===================================================================
--- trunk/user/drbdadm.h	2004-12-15 15:43:51 UTC (rev 1681)
+++ trunk/user/drbdadm.h	2004-12-15 19:48:31 UTC (rev 1682)
@@ -16,9 +16,12 @@
   SLEEPS_SHORT         = 2+1,
   SLEEPS_LONG          = 4+1,
   SLEEPS_VERY_LONG     = 8+1,
+  SLEEPS_MASK          = 15,
 
   RETURN_PID           = 2,
   SLEEPS_FOREVER       = 4,
+
+  SUPRESS_STDERR       = 16,
 };
 
 /* for check_uniq(): Check for uniqueness of certain values...

Modified: trunk/user/drbdadm_adjust.c
===================================================================
--- trunk/user/drbdadm_adjust.c	2004-12-15 15:43:51 UTC (rev 1681)
+++ trunk/user/drbdadm_adjust.c	2004-12-15 19:48:31 UTC (rev 1682)
@@ -196,7 +196,7 @@
   int do_syncer=0;
 
   struct stat sb;
-  int major, minor;
+  int c_major, c_minor;
   int err = 10;
 
   argv[argc++]=drbdsetup;
@@ -222,8 +222,8 @@
     fprintf(stderr, "'%s' not a block device!\n", res->me->disk);
     goto out;
   }
-  rv=m_fscanf(in,"Lower device: %d:%d (%*[^)])\n",&major,&minor);
-  if( (rv!=2) || (((major<<8)|minor) != (int)sb.st_rdev)) do_attach=1;
+  rv=m_fscanf(in,"Lower device: %d:%d (%*[^)])\n",&c_major,&c_minor);
+  if( (rv!=2) || makedev(c_major,c_minor) != sb.st_rdev) do_attach=1;
 
   if (strcmp("internal", res->me->meta_disk)) {
     if (stat(res->me->meta_disk, &sb)) {
@@ -249,8 +249,8 @@
     }
   }
   if (rv == 2) {
-    sscanf(str1, "%d:%d", &major, &minor);
-    if ((rv != 2) || (((major << 8) | minor) != (int) sb.st_rdev))
+    sscanf(str1, "%d:%d", &c_major, &c_minor);
+    if ((rv != 2) || makedev(c_major,c_minor) != sb.st_rdev)
       do_attach = 1;
     rv = m_fscanf(in, "Meta index: %[0-9]\n", str1);
     if (rv == 1) {

Modified: trunk/user/drbdadm_main.c
===================================================================
--- trunk/user/drbdadm_main.c	2004-12-15 15:43:51 UTC (rev 1681)
+++ trunk/user/drbdadm_main.c	2004-12-15 19:48:31 UTC (rev 1682)
@@ -35,7 +35,6 @@
 #include <search.h>
 
 #include <sys/types.h>
-#include <sys/stat.h>
 #include <sys/wait.h>
 #include <sys/poll.h>
 #include <unistd.h>
@@ -96,6 +95,7 @@
 static int sh_md_idx(struct d_resource* ,const char* );
 static int admm_generic(struct d_resource* ,const char* );
 static int adm_khelper(struct d_resource* ,const char* );
+static int adm_generic_b(struct d_resource* ,const char* );
 
 char ss_buffer[255];
 struct utsname nodeinfo;
@@ -180,7 +180,7 @@
   { "secondary",         adm_generic_s,         1, 1 },
   { "invalidate",        adm_generic_l,         1, 1 },
   { "invalidate_remote", adm_generic_l,         1, 1 },
-  { "outdate",           adm_generic_s,         1, 1 },
+  { "outdate",           adm_generic_b,         1, 1 },
   { "resize",            adm_resize,            1, 1 },
   { "syncer",            adm_syncer,            1, 1 },
   { "adjust",            adm_adjust,            1, 1 },
@@ -393,12 +393,11 @@
 
 static void find_drbdcmd(char** cmd, char** pathes)
 {
-  struct stat buf;
   char **path;
 
   path=pathes;
   while(*path) {
-    if(stat(*path,&buf)==0) {
+    if(access(*path,X_OK)==0) {
       *cmd=*path;
       return;
     }
@@ -441,6 +440,7 @@
     exit(E_exec_error);
   }
   if(pid == 0) {
+    if(flags & SUPRESS_STDERR) fclose(stderr);
     execv(argv[0],argv);
     fprintf(stderr,"Can not exec\n");
     exit(E_exec_error);
@@ -450,7 +450,7 @@
     int timeout;
     sigaction(SIGALRM,&sa,&so);
     alarm_raised=0;
-    switch(flags) {
+    switch(flags & SLEEPS_MASK) {
     case SLEEPS_SHORT:     timeout = 5; break;
     case SLEEPS_LONG:      timeout = 120; break;
     case SLEEPS_VERY_LONG: timeout = 600; break;
@@ -486,7 +486,7 @@
   if( flags & SLEEPS_FINITE ) {
     alarm(0);
     sigaction(SIGALRM,&so,NULL);
-    if(rv >= 10) {
+    if(rv >= 10 && !(flags & SUPRESS_STDERR) ) {
       fprintf(stderr,"Command '");
       while(*argv) {
 	fprintf(stderr,"%s",*argv++);
@@ -610,6 +610,15 @@
   return adm_generic(res,cmd,SLEEPS_LONG);
 }
 
+static int adm_generic_b(struct d_resource* res,const char* cmd)
+{
+  int rv;
+  if( (rv=adm_generic(res,cmd,SLEEPS_SHORT|SUPRESS_STDERR)) ) {
+    rv = admm_generic(res,cmd);
+  }
+  return rv;
+}
+
 static char* get_opt_val(struct d_option*,const char*,char*);
 
 static int adm_khelper(struct d_resource* res ,const char* cmd)
@@ -708,27 +717,6 @@
   return rv;
 }
 
-int minor_of_res(struct d_resource *res)
-{
-  struct stat sb;
-
-  if(stat(res->me->device,&sb)) {
-    // On udev/devfs based system the device nodes does not
-    // exist before the module is loaded. Therefore assume that
-    // the number in the device name is the minor number.
-    char *c;
-
-    c=res->me->device;
-    while(*c) {
-      if(isdigit(*c)) return strtol(c,NULL,10);
-      c++;
-    }
-    return 0;
-  }
-
-  return minor(sb.st_rdev);
-}
-
 struct d_resource* res_by_minor(const char *id)
 {
   struct d_resource *res,*t;
@@ -738,7 +726,7 @@
   mm = m_strtoll(id+6,1);
 
   for_each_resource(res,t,config) {
-    if( mm == minor_of_res(res)) return res;
+    if( mm == dt_minor_of_dev(res->me->device)) return res;
   }
   return NULL;
 }
@@ -1277,7 +1265,7 @@
 
     highest_minor=0;
     for_each_resource(res,tmp,config) {
-      int m = minor_of_res(res);
+      int m = dt_minor_of_dev(res->me->device);
       if ( m > highest_minor ) highest_minor = m;
       nr_resources++;
     }

Modified: trunk/user/drbdmeta.c
===================================================================
--- trunk/user/drbdmeta.c	2004-12-15 15:43:51 UTC (rev 1681)
+++ trunk/user/drbdmeta.c	2004-12-15 19:48:31 UTC (rev 1682)
@@ -542,6 +542,7 @@
 int meta_dump_md(struct format *cfg, char **argv, int argc);
 int meta_create_md(struct format *cfg, char **argv, int argc);
 int meta_set_gc(struct format *cfg, char **argv, int argc);
+int meta_outdate_gc(struct format *cfg, char **argv, int argc);
 
 struct meta_cmd cmds[] = {
 	{"get-gc", 0, meta_get_gc, 1},
@@ -551,6 +552,7 @@
 	/* FIXME convert still missing.
 	 * implicit convert from v07 to v08 by create-md
 	 * see comments there */
+	{"outdate", 0, meta_outdate_gc, 1},
 	{"set-gc", ":::VAL:VAL:...", meta_set_gc, 0},
 };
 
@@ -1325,6 +1327,33 @@
 	return err;
 }
 
+int meta_outdate_gc(struct format *cfg, char **argv, int argc)
+{
+	int err;
+
+	if (argc > 0) {
+		fprintf(stderr, "Ignoring additional arguments\n");
+	}
+
+	if (cfg->ops->open(cfg))
+		return -1;
+
+	if ( !(cfg->md.gc[Flags] & MDF_Consistent) ) {
+		fprintf(stderr, "Device is inconsistent.\n");
+		exit(10);
+	}
+
+	cfg->md.gc[Flags] &= ~MDF_WasUpToDate;
+
+	err = cfg->ops->md_cpu_to_disk(cfg)
+		|| cfg->ops->close(cfg);
+	if (err)
+		fprintf(stderr, "update failed\n");
+
+	return err;
+}
+
+
 #if 0
 int meta_set_size(struct format *cfg, char **argv, int argc)
 {
@@ -1477,10 +1506,16 @@
 	cfg->drbd_dev_name = argv[1];
 	cfg->drbd_fd = dt_lock_open_drbd(cfg->drbd_dev_name, &cfg->lock_fd, 1);
 	if (cfg->drbd_fd > -1) {
-		/* avoid DRBD specific ioctls here...
+		/* Try to avoid DRBD specific ioctls here...
 		 * If the device is _not_ configured, block device ioctls
 		 * should fail. So if we _can_ determine whether it is readonly,
 		 * it is configured; and we better not touch its meta data.
+		 * 
+		 * Unfortunately this is not true... as soon as the
+		 * driver is loaded, this works, no regard wheter it
+		 * is configured or not.... probabely need to use
+		 * a drbd IOCTL... or look at /proc/drbd ...
+		 * uggly as well!
 		 */
 		int dummy_is_ro;
 		if (ioctl(cfg->drbd_fd, BLKROGET, &dummy_is_ro) == 0) {

Modified: trunk/user/drbdsetup.c
===================================================================
--- trunk/user/drbdsetup.c	2004-12-15 15:43:51 UTC (rev 1681)
+++ trunk/user/drbdsetup.c	2004-12-15 19:48:31 UTC (rev 1682)
@@ -28,6 +28,8 @@
 
  */
 
+#define _GNU_SOURCE
+
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/ioctl.h>
@@ -40,7 +42,6 @@
 #include <string.h>
 #include <linux/drbd.h>
 #include <linux/drbd_config.h>
-#define _GNU_SOURCE
 #include <getopt.h>
 #include <stdlib.h>
 #include <errno.h>
@@ -86,7 +87,7 @@
 
 
 // some globals
-char* basename = 0;
+char* cmdname = 0;
 
 struct drbd_cmd {
   const char* cmd;
@@ -339,7 +340,7 @@
 
   printf("\nUSAGE: %s device command arguments options\n\n"
 	 "Device is usually /dev/drbdX or /dev/drbd/X.\n"
-         "Commands, arguments and options are:\n",basename);
+         "Commands, arguments and options are:\n",cmdname);
 
 
   for (i = 0; i < ARRY_SIZE(commands); i++)
@@ -422,10 +423,10 @@
 	    }
 	  }
 	  fprintf(stderr,"%s: '%s' is an invalid on-io-error handler.\n",
-		  basename,optarg);
+		  cmdname,optarg);
 	  return 20;
 	case 1:	// non option argument. see getopt_long(3)
-	  fprintf(stderr,"%s: Unexpected nonoption argument '%s'\n",basename,optarg);
+	  fprintf(stderr,"%s: Unexpected nonoption argument '%s'\n",cmdname,optarg);
 	case '?':
 	  return 20;
 	}
@@ -499,10 +500,10 @@
 	    }
 	  }
 	  fprintf(stderr,"%s: '%s' is an invalid on-disconnect handler.\n",
-		  basename,optarg);
+		  cmdname,optarg);
 	  return 20;
 	case 1:	// non option argument. see getopt_long(3)
-	  fprintf(stderr,"%s: Unexpected nonoption argument '%s'\n",basename,optarg);
+	  fprintf(stderr,"%s: Unexpected nonoption argument '%s'\n",cmdname,optarg);
 	case '?':
 	  return 20;
 	}
@@ -744,7 +745,7 @@
 	      newstate |= TimeoutExpired;
 	      break;
 	    case 1:	// non option argument. see getopt_long(3)
-	      fprintf(stderr,"%s: Unexpected nonoption argument '%s'\n",basename,optarg);
+	      fprintf(stderr,"%s: Unexpected nonoption argument '%s'\n",cmdname,optarg);
 	    case '?':
 	      return 20;
 	    }
@@ -783,7 +784,7 @@
 	      flags |= TimeoutExpired;
 	      break;
 	    case 1:	// non option argument. see getopt_long(3)
-	      fprintf(stderr,"%s: Unexpected nonoption argument '%s'\n",basename,optarg);
+	      fprintf(stderr,"%s: Unexpected nonoption argument '%s'\n",cmdname,optarg);
 	    case '?':
 	      return 20;
 	    }
@@ -832,7 +833,7 @@
 			      DRBD_DEGR_WFC_TIMEOUT_MAX);
 	      break;
 	    case 1:	// non option argument. see getopt_long(3)
-	      fprintf(stderr,"%s: Unexpected nonoption argument '%s'\n",basename,optarg);
+	      fprintf(stderr,"%s: Unexpected nonoption argument '%s'\n",cmdname,optarg);
 	    case '?':
 	      return 20;
 	    }
@@ -913,7 +914,7 @@
 			      DRBD_AL_EXTENTS_MIN, DRBD_AL_EXTENTS_MAX);
 	      break;
 	    case 1:	// non option argument. see getopt_long(3)
-	      fprintf(stderr,"%s: Unexpected nonoption argument '%s'\n",basename,optarg);
+	      fprintf(stderr,"%s: Unexpected nonoption argument '%s'\n",cmdname,optarg);
 	    case '?':
 	      return 20;
 	    }
@@ -1089,7 +1090,7 @@
 			      DRBD_DISK_SIZE_SECT_MAX>>1 );
 	      break;
 	    case 1:	// non option argument. see getopt_long(3)
-	      fprintf(stderr,"%s: Unexpected nonoption argument '%s'\n",basename,optarg);
+	      fprintf(stderr,"%s: Unexpected nonoption argument '%s'\n",cmdname,optarg);
 	    case '?':
 	      return 20;
 	    }
@@ -1107,7 +1108,7 @@
   return 0;
 }
 
-const char* guess_dev_name(const char* dir,int major,int minor)
+const char* guess_dev_name(const char* dir,int g_major,int g_minor)
 {
   DIR* device_dir;
   struct dirent* dde;
@@ -1125,8 +1126,8 @@
 
       if(S_ISBLK(sb.st_mode))
 	{
-	  if (major == (int)(sb.st_rdev & 0xff00) >> 8 &&
-	      minor == (int)(sb.st_rdev & 0x00ff) )
+	  if (g_major == major(sb.st_rdev) &&
+	      g_minor == minor(sb.st_rdev) )
 	    {
 	      closedir(device_dir);
 	      return dev_name;
@@ -1157,7 +1158,7 @@
 	      return dev_name;
 	    }
 
-	  if(guess_dev_name(subdir,major,minor)) return dev_name;
+	  if(guess_dev_name(subdir,g_major,g_minor)) return dev_name;
 	}
     }
 
@@ -1324,10 +1325,10 @@
   int err;
   char **args;
 
-  if ( (basename = strrchr(argv[0],'/')) )
-      argv[0] = ++basename;
+  if ( (cmdname = strrchr(argv[0],'/')) )
+      argv[0] = ++cmdname;
   else
-      basename = argv[0];
+      cmdname = argv[0];
 
   /* == '-' catches -h, --help, and similar */
   if (argc > 1 && (!strcmp(argv[1],"help") || argv[1][0] == '-'))

Modified: trunk/user/drbdtool_common.c
===================================================================
--- trunk/user/drbdtool_common.c	2004-12-15 15:43:51 UTC (rev 1681)
+++ trunk/user/drbdtool_common.c	2004-12-15 19:48:31 UTC (rev 1682)
@@ -10,6 +10,8 @@
 #include <stdio.h>
 #include <getopt.h>
 #include <stdlib.h>
+#include <ctype.h>
+
 #include "drbdtool_common.h"
 
 char* ppsize(char* buf, size_t size) 
@@ -183,71 +185,94 @@
     return -1;
 }
 
+int dt_minor_of_dev(const char *device)
+{
+	struct stat sb;
+
+	if(stat(device,&sb)) {
+		// On udev/devfs based system the device nodes does not
+		// exist before the module is loaded. Therefore assume that
+		// the number in the device name is the minor number.
+		const char *c;
+
+		c=device;
+		while(*c) {
+			if(isdigit(*c)) return strtol(c,NULL,10);
+			c++;
+		}
+		return 0;
+	}
+
+	return minor(sb.st_rdev);
+}
+
+
 int dt_lock_open_drbd(const char* device, int *lock_fd, int open_may_fail)
 {
-  int drbd_fd, lfd, err;
-  struct stat drbd_stat;
-  char lfname[40];
+	int drbd_fd, lfd;
+	struct stat drbd_stat;
+	char lfname[40];
+	int dev_major,dev_minor;
 
-  drbd_fd=open(device,O_RDONLY);
-  if(drbd_fd==-1 && !open_may_fail)
-    {
-      PERROR("can not open %s", device);
-      exit(20);
-    }
+	drbd_fd=open(device,O_RDONLY);
+	if(drbd_fd==-1 && !open_may_fail) {
+		PERROR("can not open %s", device);
+		exit(20);
+	}
+	
+	dev_major = 147; //LANANA_DRBD_MAJOR;
 
-  err=stat(device, &drbd_stat);
-  if(err)
-    {
-      PERROR("fstat(%s) failed",device);
-    }
+	if( stat(device, &drbd_stat) ) {
 
-  if(!S_ISBLK(drbd_stat.st_mode))
-    {
-      fprintf(stderr, "%s is not a block device!\n", device);
-      exit(20);
-    }
+		if(!S_ISBLK(drbd_stat.st_mode)) {
+			fprintf(stderr, "%s is not a block device!\n", device);
+			exit(20);
+		}
 
-  /* FIXME maybe check the major number, too?
-   * you cannot be paranoid enough...
-   * either NBD [43], or DRBD [147] (enforce for v08)
-   */
+		dev_major = major(drbd_stat.st_rdev);
 
-  /* THINK.
-   * maybe we should also place a fcntl lock on the
-   * _physical_device_ we open later...
-   *
-   * This lock is to prevent a drbd minor from being configured
-   * by drbdsetup while drbdmeta is about to mess with its meta data.
-   *
-   * If you happen to mess with the meta data of one device,
-   * pretending it belongs to an other, you'll screw up completely.
-   *
-   * We should store something in the meta data to detect such abuses.
-   * Philipp, see my suggestion for "/var/lib/drbd/drbd-toc",
-   * or /etc/drbd/ for that matter ...
-   */
+		/* FIXME maybe check the major number, too?
+		 * you cannot be paranoid enough...
+		 * either NBD [43], or DRBD [147] (enforce for v08)
+		 */
+	}
 
-  /* NOTE that /var/lock/drbd-*-* may not be "secure",
-   * maybe we should rather use /var/lock/drbd/drbd-*-*,
-   * and make sure that /var/lock/drbd is drwx.-..-. root:root  ...
-   */
 
-  snprintf(lfname,39,"/var/lock/drbd-%d-%d",
-	   major(drbd_stat.st_rdev),minor(drbd_stat.st_rdev));
+	/* THINK.
+	 * maybe we should also place a fcntl lock on the
+	 * _physical_device_ we open later...
+	 *
+	 * This lock is to prevent a drbd minor from being configured
+	 * by drbdsetup while drbdmeta is about to mess with its meta data.
+	 *
+	 * If you happen to mess with the meta data of one device,
+	 * pretending it belongs to an other, you'll screw up completely.
+	 *
+	 * We should store something in the meta data to detect such abuses.
+	 * Philipp, see my suggestion for "/var/lib/drbd/drbd-toc",
+	 * or /etc/drbd/ for that matter ...
+	 */
 
-  lfd = get_fd_lockfile_timeout(lfname,1);
-  if (lfd < 0)
-	exit(20);
-  if (lock_fd) *lock_fd = lfd;
+	/* NOTE that /var/lock/drbd-*-* may not be "secure",
+	 * maybe we should rather use /var/lock/drbd/drbd-*-*,
+	 * and make sure that /var/lock/drbd is drwx.-..-. root:root  ...
+	 */
 
-  return drbd_fd;
+	dev_minor = dt_minor_of_dev(device);
+	snprintf(lfname,39,"/var/lock/drbd-%d-%d",dev_major,dev_minor);
+
+	lfd = get_fd_lockfile_timeout(lfname,1);
+	if (lfd < 0)
+		exit(20);
+	if (lock_fd) *lock_fd = lfd;
+
+	return drbd_fd;
 }
 
 int dt_close_drbd_unlock(int drbd_fd, int lock_fd)
 {
-  int err = 0;
-  if (drbd_fd >= 0) err = close(drbd_fd);
-  if (lock_fd >= 0) unlock_fd(lock_fd); /* ignore errors */
-  return err;
+	int err = 0;
+	if (drbd_fd >= 0) err = close(drbd_fd);
+	if (lock_fd >= 0) unlock_fd(lock_fd); /* ignore errors */
+	return err;
 }

Modified: trunk/user/drbdtool_common.h
===================================================================
--- trunk/user/drbdtool_common.h	2004-12-15 15:43:51 UTC (rev 1681)
+++ trunk/user/drbdtool_common.h	2004-12-15 19:48:31 UTC (rev 1682)
@@ -14,6 +14,7 @@
 extern int dt_lock_open_drbd(const char* device, int *lock_fd, int open_may_fail);
 extern int dt_close_drbd_unlock(int drbd_fd, int lock_fd);
 extern void dt_release_lockfile(int drbd_fd);
+int dt_minor_of_dev(const char *device);
 extern unsigned long long m_strtoll(const char* s,const char def_unit);
 const char* make_optstring(struct option *options, char startc);
 char* ppsize(char* buf, size_t size);



More information about the drbd-cvs mailing list