Subject: dkctl & DIOCKLABEL
To: None <tech-userlevel@netbsd.org>
From: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
List: tech-userlevel
Date: 06/23/2002 17:18:03
----Next_Part(Sun_Jun_23_17:18:03_2002_160)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

hi.

is there any userland tool that can be used to issue
a DIOCKLABEL ioctl?
if no, can i add a capability to do it to dkctl?
(diffs attached)

eg. mbrlabel on a read-only disk can be more useful with this.

---
YAMAMOTO Takashi<yamt@mwd.biglobe.ne.jp>

----Next_Part(Sun_Jun_23_17:18:03_2002_160)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="dkctl.diff"

Index: dkctl.8
===================================================================
RCS file: /cvs/cvsroot/basesrc/sbin/dkctl/dkctl.8,v
retrieving revision 1.2
diff -u -p -r1.2 dkctl.8
--- dkctl.8	2002/01/09 23:10:19	1.2
+++ dkctl.8	2002/06/23 08:05:01
@@ -88,6 +88,17 @@ write cache blocks to the media.  If
 is specified, the cache synchronization command will be issued even
 if the kernel does not believe that there are any dirty cache blocks
 in the disk's cache.
+.Pp
+.Nm keeplabel
+.Op Ar yes | no
+.Pp
+Specify to keep or drop the in-core disklabel on the last close of
+the disk device.
+(Keep if
+.Ar yes
+is specified, drop if
+.Ar no
+is specified.)
 .Sh SEE ALSO
 .Xr ioctl 2 ,
 .Xr sd 4 ,
Index: dkctl.c
===================================================================
RCS file: /cvs/cvsroot/basesrc/sbin/dkctl/dkctl.c,v
retrieving revision 1.1
diff -u -p -r1.1 dkctl.c
--- dkctl.c	2002/01/09 22:30:14	1.1
+++ dkctl.c	2002/06/23 08:05:01
@@ -51,6 +51,14 @@
 #include <unistd.h>
 #include <util.h>
 
+#define	YES	1
+#define	NO	0
+
+/* I don't think nl_langinfo is suitable in this case */
+#define	YES_STR	"yes"
+#define	NO_STR	"no"
+#define YESNO_ARG	YES_STR " | " NO_STR
+
 struct command {
 	const char *cmd_name;
 	const char *arg_names;
@@ -67,9 +75,12 @@ char	dvname_store[MAXPATHLEN];	/* for op
 const	char *cmdname;			/* command user issued */
 const	char *argnames;			/* helpstring; expected arguments */
 
+int yesno(const char *);
+
 void	disk_getcache(int, char *[]);
 void	disk_setcache(int, char *[]);
 void	disk_synccache(int, char *[]);
+void	disk_keeplabel(int, char *[]);
 
 struct command commands[] = {
 	{ "getcache",
@@ -87,6 +98,11 @@ struct command commands[] = {
 	  disk_synccache,
 	  O_RDWR },
 
+	{ "keeplabel",
+	  YESNO_ARG,
+	  disk_keeplabel,
+	  O_RDWR },
+
 	{ NULL,
 	  NULL,
 	  NULL,
@@ -224,4 +240,37 @@ disk_synccache(int argc, char *argv[])
 
 	if (ioctl(fd, DIOCCACHESYNC, &force) == -1)
 		err(1, "%s: sync cache", dvname);
+}
+
+void
+disk_keeplabel(int argc, char *argv[])
+{
+	int keep;
+	int yn;
+
+	if (argc != 1)
+		usage();
+
+	yn = yesno(argv[0]);
+	if (yn < 0)
+		usage();
+
+	keep = yn == YES;
+
+	if (ioctl(fd, DIOCKLABEL, &keep) == -1)
+		err(1, "%s: keep label", dvname);
+}
+
+/*
+ * return YES, NO or -1.
+ */
+int
+yesno(const char *p)
+{
+
+	if (!strcmp(p, YES_STR))
+		return YES;
+	if (!strcmp(p, NO_STR))
+		return NO;
+	return -1;
 }

----Next_Part(Sun_Jun_23_17:18:03_2002_160)----