17bd4e7b4SPoul-Henning Kamp /*- 2*eb8f8877SWarner Losh * SPDX-License-Identifier: BSD-3-Clause 35e53a4f9SPedro F. Giffuni * 47bd4e7b4SPoul-Henning Kamp * Copyright (c) 2003 Poul-Henning Kamp 57bd4e7b4SPoul-Henning Kamp * All rights reserved. 67f16b501SAlexander Motin * Copyright (c) 2022 Alexander Motin <mav@FreeBSD.org> 77bd4e7b4SPoul-Henning Kamp * 87bd4e7b4SPoul-Henning Kamp * Redistribution and use in source and binary forms, with or without 97bd4e7b4SPoul-Henning Kamp * modification, are permitted provided that the following conditions 107bd4e7b4SPoul-Henning Kamp * are met: 117bd4e7b4SPoul-Henning Kamp * 1. Redistributions of source code must retain the above copyright 127bd4e7b4SPoul-Henning Kamp * notice, this list of conditions and the following disclaimer. 137bd4e7b4SPoul-Henning Kamp * 2. Redistributions in binary form must reproduce the above copyright 147bd4e7b4SPoul-Henning Kamp * notice, this list of conditions and the following disclaimer in the 157bd4e7b4SPoul-Henning Kamp * documentation and/or other materials provided with the distribution. 167bd4e7b4SPoul-Henning Kamp * 3. The names of the authors may not be used to endorse or promote 177bd4e7b4SPoul-Henning Kamp * products derived from this software without specific prior written 187bd4e7b4SPoul-Henning Kamp * permission. 197bd4e7b4SPoul-Henning Kamp * 207bd4e7b4SPoul-Henning Kamp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 217bd4e7b4SPoul-Henning Kamp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 227bd4e7b4SPoul-Henning Kamp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 237bd4e7b4SPoul-Henning Kamp * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 247bd4e7b4SPoul-Henning Kamp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 257bd4e7b4SPoul-Henning Kamp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 267bd4e7b4SPoul-Henning Kamp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 277bd4e7b4SPoul-Henning Kamp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 287bd4e7b4SPoul-Henning Kamp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 297bd4e7b4SPoul-Henning Kamp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 307bd4e7b4SPoul-Henning Kamp * SUCH DAMAGE. 317bd4e7b4SPoul-Henning Kamp * 327bd4e7b4SPoul-Henning Kamp * $FreeBSD$ 337bd4e7b4SPoul-Henning Kamp */ 347bd4e7b4SPoul-Henning Kamp 357bd4e7b4SPoul-Henning Kamp #include <sys/types.h> 367bd4e7b4SPoul-Henning Kamp #include <sys/sysctl.h> 3739a8d9f3SBenno Rice #include <errno.h> 387bd4e7b4SPoul-Henning Kamp #include <stdlib.h> 397bd4e7b4SPoul-Henning Kamp #include <string.h> 407bd4e7b4SPoul-Henning Kamp #include "libgeom.h" 417bd4e7b4SPoul-Henning Kamp 4239a8d9f3SBenno Rice /* 4339a8d9f3SBenno Rice * Amount of extra space we allocate to try and anticipate the size of 4439a8d9f3SBenno Rice * confxml. 4539a8d9f3SBenno Rice */ 4639a8d9f3SBenno Rice #define GEOM_GETXML_SLACK 4096 4739a8d9f3SBenno Rice 4839a8d9f3SBenno Rice /* 4939a8d9f3SBenno Rice * Number of times to retry in the face of the size of confxml exceeding 5039a8d9f3SBenno Rice * that of our buffer. 5139a8d9f3SBenno Rice */ 5239a8d9f3SBenno Rice #define GEOM_GETXML_RETRIES 4 5339a8d9f3SBenno Rice 547f16b501SAlexander Motin /* 557f16b501SAlexander Motin * Size of confxml buffer to request via getxml control request. It is 567f16b501SAlexander Motin * expected to be sufficient for single geom and its parents. In case of 577f16b501SAlexander Motin * overflow fall back to requesting full confxml via sysctl interface. 587f16b501SAlexander Motin */ 597f16b501SAlexander Motin #define GEOM_GETXML_BUFFER 65536 607f16b501SAlexander Motin 617bd4e7b4SPoul-Henning Kamp char * 62e17aa6ffSEd Schouten geom_getxml(void) 637bd4e7b4SPoul-Henning Kamp { 647bd4e7b4SPoul-Henning Kamp char *p; 657b6942a1SUlf Lilleengen size_t l = 0; 667b6942a1SUlf Lilleengen int mib[3]; 677b6942a1SUlf Lilleengen size_t sizep; 6839a8d9f3SBenno Rice int retries; 697bd4e7b4SPoul-Henning Kamp 707b6942a1SUlf Lilleengen sizep = sizeof(mib) / sizeof(*mib); 717b6942a1SUlf Lilleengen if (sysctlnametomib("kern.geom.confxml", mib, &sizep) != 0) 727b6942a1SUlf Lilleengen return (NULL); 737b6942a1SUlf Lilleengen if (sysctl(mib, sizep, NULL, &l, NULL, 0) != 0) 747b6942a1SUlf Lilleengen return (NULL); 7539a8d9f3SBenno Rice l += GEOM_GETXML_SLACK; 7639a8d9f3SBenno Rice 7739a8d9f3SBenno Rice for (retries = 0; retries < GEOM_GETXML_RETRIES; retries++) { 787bd4e7b4SPoul-Henning Kamp p = malloc(l); 797b6942a1SUlf Lilleengen if (p == NULL) 807b6942a1SUlf Lilleengen return (NULL); 8139a8d9f3SBenno Rice if (sysctl(mib, sizep, p, &l, NULL, 0) == 0) 827b6942a1SUlf Lilleengen return (reallocf(p, strlen(p) + 1)); 8339a8d9f3SBenno Rice 8439a8d9f3SBenno Rice free(p); 8539a8d9f3SBenno Rice 8639a8d9f3SBenno Rice if (errno != ENOMEM) 8739a8d9f3SBenno Rice return (NULL); 8839a8d9f3SBenno Rice 8939a8d9f3SBenno Rice /* 9039a8d9f3SBenno Rice * Our buffer wasn't big enough. Make it bigger and 9139a8d9f3SBenno Rice * try again. 9239a8d9f3SBenno Rice */ 9339a8d9f3SBenno Rice l *= 2; 9439a8d9f3SBenno Rice } 9539a8d9f3SBenno Rice 9639a8d9f3SBenno Rice return (NULL); 977bd4e7b4SPoul-Henning Kamp } 987f16b501SAlexander Motin 997f16b501SAlexander Motin char * 1007f16b501SAlexander Motin geom_getxml_geom(const char *class, const char *geom, int parents) 1017f16b501SAlexander Motin { 1027f16b501SAlexander Motin struct gctl_req *r; 1037f16b501SAlexander Motin char *p; 1047f16b501SAlexander Motin const char *errstr; 1057f16b501SAlexander Motin int nargs = 0; 1067f16b501SAlexander Motin 1077f16b501SAlexander Motin p = malloc(GEOM_GETXML_BUFFER); 1087f16b501SAlexander Motin if (p == NULL) 1097f16b501SAlexander Motin return (NULL); 1107f16b501SAlexander Motin r = gctl_get_handle(); 1117f16b501SAlexander Motin gctl_ro_param(r, "class", -1, class); 1127f16b501SAlexander Motin gctl_ro_param(r, "verb", -1, "getxml"); 1137f16b501SAlexander Motin gctl_ro_param(r, "parents", sizeof(parents), &parents); 1147f16b501SAlexander Motin if (geom) { 1157f16b501SAlexander Motin gctl_ro_param(r, "arg0", -1, geom); 1167f16b501SAlexander Motin nargs = 1; 1177f16b501SAlexander Motin } 1187f16b501SAlexander Motin gctl_ro_param(r, "nargs", sizeof(nargs), &nargs); 1197f16b501SAlexander Motin p[0] = '\0'; 1207f16b501SAlexander Motin gctl_add_param(r, "output", GEOM_GETXML_BUFFER, p, 1217f16b501SAlexander Motin GCTL_PARAM_WR | GCTL_PARAM_ASCII); 1227f16b501SAlexander Motin errstr = gctl_issue(r); 1237f16b501SAlexander Motin if (errstr != NULL && errstr[0] != '\0') { 1247f16b501SAlexander Motin gctl_free(r); 1257f16b501SAlexander Motin free(p); 1267f16b501SAlexander Motin return (geom_getxml()); 1277f16b501SAlexander Motin } 1287f16b501SAlexander Motin gctl_free(r); 1297f16b501SAlexander Motin return (p); 1307f16b501SAlexander Motin } 131