static void test_ascii (guestfs_h *g, const struct filesystem *fs) { char **files; size_t count; /* Create various ASCII-named files. */ if (guestfs_touch (g, "/ABC") == -1) exit (EXIT_FAILURE); if (guestfs_touch (g, "/def") == -1) exit (EXIT_FAILURE); if (guestfs_touch (g, "/abc") == -1) exit (EXIT_FAILURE); /* Read list of files, check for case sensitivity. */ files = guestfs_ls (g, "/"); if (files == NULL) exit (EXIT_FAILURE); ignore_lost_and_found (files); count = guestfs___count_strings (files); if (fs->fs_case_insensitive) { /* case insensitive */ if (count != 2) error (EXIT_FAILURE, 0, "error: %s: %s is supposed to be case-insensitive, but %zu files " "(instead of 2) were returned", __func__, fs->fs_name, count); if (STRCASENEQ (files[0], "abc") || STRCASENEQ (files[1], "def")) error (EXIT_FAILURE, 0, "error: %s: %s returned unexpected filenames '%s' and '%s'", __func__, fs->fs_name, files[0], files[1]); } else { /* case sensitive */ if (count != 3) error (EXIT_FAILURE, 0, "error: %s: %s is supposed to be case-sensitive, but %zu files " "(instead of 3) were returned", __func__, fs->fs_name, count); if (STRNEQ (files[0], "ABC") == -1 || STRNEQ (files[1], "abc") == -1 || STRNEQ (files[2], "def") == -1) error (EXIT_FAILURE, 0, "error: %s: %s returned unexpected filenames '%s', '%s', '%s'", __func__, fs->fs_name, files[0], files[1], files[2]); if (guestfs_rm (g, "/abc") == -1) exit (EXIT_FAILURE); } if (guestfs_rm (g, "/ABC") == -1) exit (EXIT_FAILURE); if (guestfs_rm (g, "/def") == -1) exit (EXIT_FAILURE); }
/* Matches Windows registry HKLM\SYSYTEM\MountedDevices\DosDevices blob to * to libguestfs GPT partition device. For GPT disks, the blob is made of * "DMIO:ID:" prefix followed by the GPT partition GUID. */ static char * map_registry_disk_blob_gpt (guestfs_h *g, const void *blob) { CLEANUP_FREE_STRING_LIST char **parts = NULL; CLEANUP_FREE char *blob_guid = extract_guid_from_registry_blob (g, blob); size_t i; parts = guestfs_list_partitions (g); if (parts == NULL) return NULL; for (i = 0; parts[i] != NULL; ++i) { CLEANUP_FREE char *fs_guid = NULL; int partnum; CLEANUP_FREE char *device = NULL; CLEANUP_FREE char *type = NULL; partnum = guestfs_part_to_partnum (g, parts[i]); if (partnum == -1) continue; device = guestfs_part_to_dev (g, parts[i]); if (device == NULL) continue; type = guestfs_part_get_parttype (g, device); if (type == NULL) continue; if (STRCASENEQ (type, "gpt")) continue; /* get the GPT parition GUID from the partition block device */ fs_guid = guestfs_part_get_gpt_guid (g, device, partnum); if (fs_guid == NULL) continue; /* if both GUIDs match, we have found the mapping for our device */ if (STRCASEEQ (fs_guid, blob_guid)) return safe_strdup (g, parts[i]); } return NULL; }
int virNetDevVlanParse(xmlNodePtr node, xmlXPathContextPtr ctxt, virNetDevVlanPtr def) { int ret = -1; xmlNodePtr save = ctxt->node; char *trunk = NULL; char *nativeMode = NULL; xmlNodePtr *tagNodes = NULL; int nTags; size_t i; ctxt->node = node; nTags = virXPathNodeSet("./tag", ctxt, &tagNodes); if (nTags < 0) goto cleanup; if (nTags == 0) { virReportError(VIR_ERR_XML_ERROR, "%s", _("missing tag id - each <vlan> must have " "at least one <tag id='n'/> subelement")); goto cleanup; } if (VIR_ALLOC_N(def->tag, nTags) < 0) goto cleanup; def->nativeMode = 0; def->nativeTag = 0; for (i = 0; i < nTags; i++) { unsigned long id; ctxt->node = tagNodes[i]; if (virXPathULong("string(./@id)", ctxt, &id) < 0) { virReportError(VIR_ERR_XML_ERROR, "%s", _("missing or invalid vlan tag id attribute")); goto cleanup; } if (id > 4095) { virReportError(VIR_ERR_XML_ERROR, _("vlan tag id %lu too large (maximum 4095)"), id); goto cleanup; } if ((nativeMode = virXPathString("string(./@nativeMode)", ctxt))) { if (def->nativeMode != 0) { virReportError(VIR_ERR_XML_ERROR, "%s", _("duplicate native vlan setting")); goto cleanup; } if ((def->nativeMode = virNativeVlanModeTypeFromString(nativeMode)) <= 0) { virReportError(VIR_ERR_XML_ERROR, _("Invalid \"nativeMode='%s'\" " "in vlan <tag> element"), nativeMode); goto cleanup; } VIR_FREE(nativeMode); def->nativeTag = id; } def->tag[i] = id; } def->nTags = nTags; /* now that we know how many tags there are, look for an explicit * trunk setting. */ if (nTags > 1) def->trunk = true; ctxt->node = node; if ((trunk = virXPathString("string(./@trunk)", ctxt)) != NULL) { def->trunk = STRCASEEQ(trunk, "yes"); if (!def->trunk) { if (nTags > 1) { virReportError(VIR_ERR_XML_ERROR, _("invalid \"trunk='%s'\" in <vlan> - trunk='yes' " "is required for more than one vlan tag"), trunk); goto cleanup; } if (def->nativeMode != 0) { virReportError(VIR_ERR_XML_ERROR, "%s", _("invalid configuration in <vlan> - \"trunk='no'\" is " "not allowed with a native vlan id")); goto cleanup; } /* allow (but discard) "trunk='no' if there is a single tag */ if (STRCASENEQ(trunk, "no")) { virReportError(VIR_ERR_XML_ERROR, _("invalid \"trunk='%s'\" in <vlan> " "- must be yes or no"), trunk); goto cleanup; } } } ret = 0; cleanup: ctxt->node = save; VIR_FREE(tagNodes); VIR_FREE(trunk); VIR_FREE(nativeMode); if (ret < 0) virNetDevVlanClear(def); return ret; }
/** * virNumaGetPages: * @node: NUMA node id * @pages_size: list of pages supported on @node * @pages_avail: list of the pool sizes on @node * @pages_free: list of free pages on @node * @npages: the lists size * * For given NUMA node fetch info on pages. The size of pages * (e.g. 4K, 2M, 1G) is stored into @pages_size, the size of the * pool is then stored into @pages_avail and the number of free * pages in the pool is stored into @pages_free. * * If you're interested only in some lists, pass NULL to the * other ones. * * As a special case, if @node == -1, overall info is fetched * from the system. * * Returns 0 on success, -1 otherwise. */ int virNumaGetPages(int node, unsigned int **pages_size, unsigned int **pages_avail, unsigned int **pages_free, size_t *npages) { int ret = -1; char *path = NULL; DIR *dir = NULL; int direrr = 0; struct dirent *entry; unsigned int *tmp_size = NULL, *tmp_avail = NULL, *tmp_free = NULL; unsigned int ntmp = 0; size_t i; bool exchange; long system_page_size; unsigned long long huge_page_sum = 0; /* sysconf() returns page size in bytes, * but we are storing the page size in kibibytes. */ system_page_size = virGetSystemPageSizeKB(); /* Query huge pages at first. * On Linux systems, the huge pages pool cuts off the available memory and * is always shown as used memory. Here, however, we want to report * slightly different information. So we take the total memory on a node * and subtract memory taken by the huge pages. */ if (virNumaGetHugePageInfoPath(&path, node, 0, NULL) < 0) goto cleanup; if (!(dir = opendir(path))) { /* It's okay if the @path doesn't exist. Maybe we are running on * system without huge pages support where the path may not exist. */ if (errno != ENOENT) { virReportSystemError(errno, _("unable to open path: %s"), path); goto cleanup; } } while (dir && (direrr = virDirRead(dir, &entry, path)) > 0) { const char *page_name = entry->d_name; unsigned int page_size, page_avail = 0, page_free = 0; char *end; /* Just to give you a hint, we're dealing with this: * hugepages-2048kB/ or hugepages-1048576kB/ */ if (!STRPREFIX(entry->d_name, HUGEPAGES_PREFIX)) continue; page_name += strlen(HUGEPAGES_PREFIX); if (virStrToLong_ui(page_name, &end, 10, &page_size) < 0 || STRCASENEQ(end, "kB")) { virReportError(VIR_ERR_INTERNAL_ERROR, _("unable to parse %s"), entry->d_name); goto cleanup; } if (virNumaGetHugePageInfo(node, page_size, &page_avail, &page_free) < 0) goto cleanup; if (VIR_REALLOC_N(tmp_size, ntmp + 1) < 0 || VIR_REALLOC_N(tmp_avail, ntmp + 1) < 0 || VIR_REALLOC_N(tmp_free, ntmp + 1) < 0) goto cleanup; tmp_size[ntmp] = page_size; tmp_avail[ntmp] = page_avail; tmp_free[ntmp] = page_free; ntmp++; /* page_size is in kibibytes while we want huge_page_sum * in just bytes. */ huge_page_sum += 1024 * page_size * page_avail; } if (direrr < 0) goto cleanup; /* Now append the ordinary system pages */ if (VIR_REALLOC_N(tmp_size, ntmp + 1) < 0 || VIR_REALLOC_N(tmp_avail, ntmp + 1) < 0 || VIR_REALLOC_N(tmp_free, ntmp + 1) < 0) goto cleanup; if (virNumaGetPageInfo(node, system_page_size, huge_page_sum, &tmp_avail[ntmp], &tmp_free[ntmp]) < 0) goto cleanup; tmp_size[ntmp] = system_page_size; ntmp++; /* Just to produce nice output, sort the arrays by increasing page size */ do { exchange = false; for (i = 0; i < ntmp -1; i++) { if (tmp_size[i] > tmp_size[i + 1]) { exchange = true; SWAP(tmp_size[i], tmp_size[i + 1]); SWAP(tmp_avail[i], tmp_avail[i + 1]); SWAP(tmp_free[i], tmp_free[i + 1]); } } } while (exchange); if (pages_size) { *pages_size = tmp_size; tmp_size = NULL; } if (pages_avail) { *pages_avail = tmp_avail; tmp_avail = NULL; } if (pages_free) { *pages_free = tmp_free; tmp_free = NULL; } *npages = ntmp; ret = 0; cleanup: VIR_FREE(tmp_free); VIR_FREE(tmp_avail); VIR_FREE(tmp_size); if (dir) closedir(dir); VIR_FREE(path); return ret; }
static virDrvOpenStatus hypervConnectOpen(virConnectPtr conn, virConnectAuthPtr auth, unsigned int flags) { virDrvOpenStatus result = VIR_DRV_OPEN_ERROR; char *plus; hypervPrivate *priv = NULL; char *username = NULL; char *password = NULL; virBuffer query = VIR_BUFFER_INITIALIZER; Msvm_ComputerSystem *computerSystem = NULL; virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR); /* Decline if the URI is NULL or the scheme is NULL */ if (conn->uri == NULL || conn->uri->scheme == NULL) { return VIR_DRV_OPEN_DECLINED; } /* Decline if the scheme is not hyperv */ plus = strchr(conn->uri->scheme, '+'); if (plus == NULL) { if (STRCASENEQ(conn->uri->scheme, "hyperv")) { return VIR_DRV_OPEN_DECLINED; } } else { if (plus - conn->uri->scheme != 6 || STRCASENEQLEN(conn->uri->scheme, "hyperv", 6)) { return VIR_DRV_OPEN_DECLINED; } virReportError(VIR_ERR_INVALID_ARG, _("Transport '%s' in URI scheme is not supported, try again " "without the transport part"), plus + 1); return VIR_DRV_OPEN_ERROR; } /* Require server part */ if (conn->uri->server == NULL) { virReportError(VIR_ERR_INVALID_ARG, "%s", _("URI is missing the server part")); return VIR_DRV_OPEN_ERROR; } /* Require auth */ if (auth == NULL || auth->cb == NULL) { virReportError(VIR_ERR_INVALID_ARG, "%s", _("Missing or invalid auth pointer")); return VIR_DRV_OPEN_ERROR; } /* Allocate per-connection private data */ if (VIR_ALLOC(priv) < 0) goto cleanup; if (hypervParseUri(&priv->parsedUri, conn->uri) < 0) { goto cleanup; } /* Set the port dependent on the transport protocol if no port is * specified. This allows us to rely on the port parameter being * correctly set when building URIs later on, without the need to * distinguish between the situations port == 0 and port != 0 */ if (conn->uri->port == 0) { if (STRCASEEQ(priv->parsedUri->transport, "https")) { conn->uri->port = 5986; } else { conn->uri->port = 5985; } } /* Request credentials */ if (conn->uri->user != NULL) { if (VIR_STRDUP(username, conn->uri->user) < 0) goto cleanup; } else { username = virAuthGetUsername(conn, auth, "hyperv", "administrator", conn->uri->server); if (username == NULL) { virReportError(VIR_ERR_AUTH_FAILED, "%s", _("Username request failed")); goto cleanup; } } password = virAuthGetPassword(conn, auth, "hyperv", username, conn->uri->server); if (password == NULL) { virReportError(VIR_ERR_AUTH_FAILED, "%s", _("Password request failed")); goto cleanup; } /* Initialize the openwsman connection */ priv->client = wsmc_create(conn->uri->server, conn->uri->port, "/wsman", priv->parsedUri->transport, username, password); if (priv->client == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not create openwsman client")); goto cleanup; } if (wsmc_transport_init(priv->client, NULL) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not initialize openwsman transport")); goto cleanup; } /* FIXME: Currently only basic authentication is supported */ wsman_transport_set_auth_method(priv->client, "basic"); /* Check if the connection can be established and if the server has the * Hyper-V role installed. If the call to hypervGetMsvmComputerSystemList * succeeds than the connection has been established. If the returned list * is empty than the server isn't a Hyper-V server. */ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT); virBufferAddLit(&query, "where "); virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_PHYSICAL); if (hypervGetMsvmComputerSystemList(priv, &query, &computerSystem) < 0) { goto cleanup; } if (computerSystem == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("%s is not a Hyper-V server"), conn->uri->server); goto cleanup; } conn->privateData = priv; priv = NULL; result = VIR_DRV_OPEN_SUCCESS; cleanup: hypervFreePrivate(&priv); VIR_FREE(username); VIR_FREE(password); hypervFreeObject(priv, (hypervObject *)computerSystem); return result; }
static virDrvOpenStatus hypervConnectOpen(virConnectPtr conn, virConnectAuthPtr auth, virConfPtr conf ATTRIBUTE_UNUSED, unsigned int flags) { virDrvOpenStatus result = VIR_DRV_OPEN_ERROR; char *plus; hypervPrivate *priv = NULL; char *username = NULL; char *password = NULL; virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR); /* Decline if the URI is NULL or the scheme is NULL */ if (conn->uri == NULL || conn->uri->scheme == NULL) return VIR_DRV_OPEN_DECLINED; /* Decline if the scheme is not hyperv */ plus = strchr(conn->uri->scheme, '+'); if (plus == NULL) { if (STRCASENEQ(conn->uri->scheme, "hyperv")) return VIR_DRV_OPEN_DECLINED; } else { if (plus - conn->uri->scheme != 6 || STRCASENEQLEN(conn->uri->scheme, "hyperv", 6)) { return VIR_DRV_OPEN_DECLINED; } virReportError(VIR_ERR_INVALID_ARG, _("Transport '%s' in URI scheme is not supported, try again " "without the transport part"), plus + 1); return VIR_DRV_OPEN_ERROR; } /* Require server part */ if (conn->uri->server == NULL) { virReportError(VIR_ERR_INVALID_ARG, "%s", _("URI is missing the server part")); return VIR_DRV_OPEN_ERROR; } /* Require auth */ if (auth == NULL || auth->cb == NULL) { virReportError(VIR_ERR_INVALID_ARG, "%s", _("Missing or invalid auth pointer")); return VIR_DRV_OPEN_ERROR; } /* Allocate per-connection private data */ if (VIR_ALLOC(priv) < 0) goto cleanup; if (hypervParseUri(&priv->parsedUri, conn->uri) < 0) goto cleanup; /* Set the port dependent on the transport protocol if no port is * specified. This allows us to rely on the port parameter being * correctly set when building URIs later on, without the need to * distinguish between the situations port == 0 and port != 0 */ if (conn->uri->port == 0) { if (STRCASEEQ(priv->parsedUri->transport, "https")) { conn->uri->port = 5986; } else { conn->uri->port = 5985; } } /* Request credentials */ if (conn->uri->user != NULL) { if (VIR_STRDUP(username, conn->uri->user) < 0) goto cleanup; } else { username = virAuthGetUsername(conn, auth, "hyperv", "administrator", conn->uri->server); if (username == NULL) { virReportError(VIR_ERR_AUTH_FAILED, "%s", _("Username request failed")); goto cleanup; } } password = virAuthGetPassword(conn, auth, "hyperv", username, conn->uri->server); if (password == NULL) { virReportError(VIR_ERR_AUTH_FAILED, "%s", _("Password request failed")); goto cleanup; } if (hypervInitConnection(conn, priv, username, password) < 0) goto cleanup; conn->privateData = priv; priv = NULL; result = VIR_DRV_OPEN_SUCCESS; cleanup: hypervFreePrivate(&priv); VIR_FREE(username); VIR_FREE(password); return result; }