kern.geom.debugflags=16 does NOT allow me to write to device

jhell jhell at dataix.net
Fri Apr 23 13:12:56 UTC 2010


On 04/23/2010 04:59, Andrey V. Elsukov wrote:
> On 23.04.2010 12:23, Jeremy Chadwick wrote:
>> Supposedly we're supposed to use gpart(8) now, but I haven't figured out
>> how to use it in the same way as bsdlabel.
> 
> It's easy.
> 
> # gpart create -s mbr md0
> md0 created
> # gpart add -t freebsd md0
> md0s1 added
> # gpart create -s bsd md0s1
> md0s1 created
> # gpart add -t freebsd-ufs -s 50m md0s1
> md0s1a added
> # gpart add -t freebsd-swap md0s1
> md0s1b added
> # gpart bootcode -b /boot/boot md0s1
> md0s1 has bootcode
> # gpart bootcode -b /boot/mbr md0
> md0 has bootcode
> # gpart set -a active -i 1 md0
> md0s1 has active set
> 
> 

As a curious question. I seem to remember a thread that discussed the
need to specify -b & -s to to "add". I recall this being fixed in more
recent versions i.e. >= 8.X. Does anyone know if these changes can be
MFC'd to stable/7 ?

Attached is a diff I just generated "stable/7/sbin/geom/class/part ->
stable/8/sbin/geom/class/part" as of recent commit r207113.

Thanks

-- 

 jhell
-------------- next part --------------
Index: geom_part.c
===================================================================
--- geom_part.c	(.../7/sbin/geom/class/part)	(revision 207113)
+++ geom_part.c	(.../8/sbin/geom/class/part)	(revision 207113)
@@ -55,6 +55,7 @@
 uint32_t PUBSYM(lib_version) = G_LIB_VERSION;
 uint32_t PUBSYM(version) = 0;
 
+static char autofill[] = "*";
 static char optional[] = "";
 static char flags[] = "C";
 
@@ -68,10 +69,10 @@
 
 struct g_command PUBSYM(class_commands)[] = {
 	{ "add", 0, gpart_issue, {
-		{ 'b', "start", NULL, G_TYPE_STRING },
-		{ 's', "size", NULL, G_TYPE_STRING },
+		{ 'b', "start", autofill, G_TYPE_ASCLBA },
+		{ 's', "size", autofill, G_TYPE_ASCLBA },
 		{ 't', "type", NULL, G_TYPE_STRING },
-		{ 'i', index_param, optional, G_TYPE_STRING },
+		{ 'i', index_param, optional, G_TYPE_ASCNUM },
 		{ 'l', "label", optional, G_TYPE_STRING },
 		{ 'f', "flags", flags, G_TYPE_STRING },
 		G_OPT_SENTINEL },
@@ -80,7 +81,7 @@
 	{ "bootcode", 0, gpart_bootcode, {
 		{ 'b', bootcode_param, optional, G_TYPE_STRING },
 		{ 'p', partcode_param, optional, G_TYPE_STRING },
-		{ 'i', index_param, optional, G_TYPE_STRING },
+		{ 'i', index_param, optional, G_TYPE_ASCNUM },
 		{ 'f', "flags", flags, G_TYPE_STRING },
 		G_OPT_SENTINEL },
 	  "geom", NULL
@@ -88,13 +89,13 @@
 	{ "commit", 0, gpart_issue, G_NULL_OPTS, "geom", NULL },
 	{ "create", 0, gpart_issue, {
 		{ 's', "scheme", NULL, G_TYPE_STRING },
-		{ 'n', "entries", optional, G_TYPE_STRING },
+		{ 'n', "entries", optional, G_TYPE_ASCNUM },
 		{ 'f', "flags", flags, G_TYPE_STRING },
 		G_OPT_SENTINEL },
 	  "provider", NULL
 	},
 	{ "delete", 0, gpart_issue, {
-		{ 'i', index_param, NULL, G_TYPE_STRING },
+		{ 'i', index_param, NULL, G_TYPE_ASCNUM },
 		{ 'f', "flags", flags, G_TYPE_STRING },
 		G_OPT_SENTINEL },
 	  "geom", NULL
@@ -104,7 +105,7 @@
 		G_OPT_SENTINEL },
 	  "geom", NULL },
 	{ "modify", 0, gpart_issue, {
-		{ 'i', index_param, NULL, G_TYPE_STRING },
+		{ 'i', index_param, NULL, G_TYPE_ASCNUM },
 		{ 'l', "label", optional, G_TYPE_STRING },
 		{ 't', "type", optional, G_TYPE_STRING },
 		{ 'f', "flags", flags, G_TYPE_STRING },
@@ -113,7 +114,7 @@
 	},
 	{ "set", 0, gpart_issue, {
 		{ 'a', "attrib", NULL, G_TYPE_STRING },
-		{ 'i', index_param, NULL, G_TYPE_STRING },
+		{ 'i', index_param, NULL, G_TYPE_ASCNUM },
 		{ 'f', "flags", flags, G_TYPE_STRING },
 		G_OPT_SENTINEL },
 	  "geom", NULL
@@ -127,7 +128,7 @@
 	{ "undo", 0, gpart_issue, G_NULL_OPTS, "geom", NULL },
 	{ "unset", 0, gpart_issue, {
 		{ 'a', "attrib", NULL, G_TYPE_STRING },
-		{ 'i', index_param, NULL, G_TYPE_STRING },
+		{ 'i', index_param, NULL, G_TYPE_ASCNUM },
 		{ 'f', "flags", flags, G_TYPE_STRING },
 		G_OPT_SENTINEL },
 	  "geom", NULL
@@ -240,6 +241,131 @@
 	return (buf);
 }
 
+static int
+gpart_autofill(struct gctl_req *req)
+{
+	struct gmesh mesh;
+	struct gclass *cp;
+	struct ggeom *gp;
+	struct gprovider *pp;
+	unsigned long long first, last;
+	unsigned long long size, start;
+	unsigned long long lba, len, grade;
+	const char *s;
+	char *val;
+	int error, has_size, has_start;
+
+	s = gctl_get_ascii(req, "verb");
+	if (strcmp(s, "add") != 0)
+		return (0);
+
+	s = gctl_get_ascii(req, "size");
+	has_size = (*s == '*') ? 0 : 1;
+	size = (has_size) ? (unsigned long long)atoll(s) : 0ULL;
+
+	s = gctl_get_ascii(req, "start");
+	has_start = (*s == '*') ? 0 : 1;
+	start = (has_start) ? (unsigned long long)atoll(s) : ~0ULL;
+
+	/* No autofill necessary. */
+	if (has_size && has_start)
+		return (0);
+
+	error = geom_gettree(&mesh);
+	if (error)
+		return (error);
+	s = gctl_get_ascii(req, "class");
+	if (s == NULL)
+		abort();
+	cp = find_class(&mesh, s);
+	if (cp == NULL)
+		errx(EXIT_FAILURE, "Class %s not found.", s);
+	s = gctl_get_ascii(req, "geom");
+	if (s == NULL)
+		abort();
+	gp = find_geom(cp, s);
+	if (gp == NULL)
+		errx(EXIT_FAILURE, "No such geom: %s.", s);
+	first = atoll(find_geomcfg(gp, "first"));
+	last = atoll(find_geomcfg(gp, "last"));
+	grade = ~0ULL;
+	while ((pp = find_provider(gp, first)) != NULL) {
+		s = find_provcfg(pp, "start");
+		if (s == NULL) {
+			s = find_provcfg(pp, "offset");
+			lba = atoll(s) / pp->lg_sectorsize;
+		} else
+			lba = atoll(s);
+
+		if (first < lba) {
+			/* Free space [first, lba> */
+			len = lba - first;
+			if (has_size) {
+				if (len >= size && len - size < grade) {
+					start = first;
+					grade = len - size;
+				}
+			} else if (has_start) {
+				if (start >= first && start < lba) {
+					size = lba - start;
+					grade = start - first;
+				}
+			} else {
+				if (grade == ~0ULL || len > size) {
+					start = first;
+					size = len;
+					grade = 0;
+				}
+			}
+		}
+
+		s = find_provcfg(pp, "end");
+		if (s == NULL) {
+			s = find_provcfg(pp, "length");
+			first = lba + atoll(s) / pp->lg_sectorsize;
+		} else
+			first = atoll(s) + 1;
+	}
+	if (first <= last) {
+		/* Free space [first-last] */
+		len = last - first + 1;
+		if (has_size) {
+			if (len >= size && len - size < grade) {
+				start = first;
+				grade = len - size;
+			}
+		} else if (has_start) {
+			if (start >= first && start <= last) {
+				size = last - start + 1;
+				grade = start - first;
+			}
+		} else {
+			if (grade == ~0ULL || len > size) {
+				start = first;
+				size = len;
+				grade = 0;
+			}
+		}
+	}
+
+	if (grade == ~0ULL)
+		return (ENOSPC);
+
+	if (!has_size) {
+		asprintf(&val, "%llu", size);
+		if (val == NULL)
+			return (ENOMEM);
+		gctl_change_param(req, "size", -1, val);
+	}
+	if (!has_start) {
+		asprintf(&val, "%llu", start);
+		if (val == NULL)
+			return (ENOMEM);
+		gctl_change_param(req, "start", -1, val);
+	}
+	return (0);
+}
+
 static void
 gpart_show_geom(struct ggeom *gp, const char *element)
 {
@@ -420,6 +546,8 @@
 		errx(EXIT_FAILURE, "Class %s not found.", s);
 	}
 	s = gctl_get_ascii(req, "geom");
+	if (s == NULL)
+		abort();
 	gp = find_geom(classp, s);
 	if (gp == NULL)
 		errx(EXIT_FAILURE, "No such geom: %s.", s);
@@ -531,6 +659,14 @@
 	const char *errstr;
 	int error, status;
 
+	/* autofill parameters (if applicable). */
+	error = gpart_autofill(req);
+	if (error) {
+		warnc(error, "autofill");
+		status = EXIT_FAILURE;
+		goto done;
+	}
+
 	bzero(buf, sizeof(buf));
 	gctl_rw_param(req, "output", sizeof(buf), buf);
 	errstr = gctl_issue(req);

Property changes on: .
___________________________________________________________________
Deleted: svn:mergeinfo
   Reverse-merged /head/sbin/geom/class/part:r172506-173080,173082-178817,178819-179854,183718,184070,185038,185044,185046,185057,185454,185495-185496,186843,187067,188017,188330,197274,200282,200290,201432,203505



More information about the freebsd-fs mailing list