int load_kld(const char *kldname) { if (path_check(kldname) == 0) { return kldload(kldname); } return (-1); }
static int path_check(ARCHD *arcn, int level) { char buf[MAXPATHLEN]; char *p; if ((p = strrchr(arcn->name, '/')) == NULL) return 0; *p = '\0'; if (realpath(arcn->name, buf) == NULL) { int error; error = path_check(arcn, level + 1); *p = '/'; if (error == 0) return 0; if (level == 0) syswarn(1, 0, "Cannot resolve `%s'", arcn->name); return -1; } if (strncmp(buf, cwdpath, cwdpathlen) != 0) { *p = '/'; syswarn(1, 0, "Attempt to write file `%s' that resolves into " "`%s/%s' outside current working directory `%s' ignored", arcn->name, buf, p + 1, cwdpath); return -1; } *p = '/'; return 0; }
// Encodes instance metadata (contained in ncInstance struct) in XML // and writes it to file instance->xmlFilePath (/path/to/instance/instance.xml) // That file gets processed through tools/libvirt.xsl (/etc/eucalyptus/libvirt.xsl) // to produce /path/to/instance/libvirt.xml file that is passed to libvirt create. int gen_instance_xml (const ncInstance * instance) { INIT(); int ret = 1; pthread_mutex_lock (&xml_mutex); xmlDocPtr doc = xmlNewDoc (BAD_CAST "1.0"); xmlNodePtr instanceNode = xmlNewNode (NULL, BAD_CAST "instance"); xmlDocSetRootElement (doc, instanceNode); { // hypervisor-related specs xmlNodePtr hypervisor = xmlNewChild (instanceNode, NULL, BAD_CAST "hypervisor", NULL); _ATTRIBUTE(hypervisor, "type", instance->hypervisorType); _ATTRIBUTE(hypervisor, "capability", hypervsorCapabilityTypeNames[instance->hypervisorCapability]); char bitness[4]; snprintf(bitness, 4,"%d", instance->hypervisorBitness); _ATTRIBUTE(hypervisor, "bitness", bitness); } { // backing specification (TODO: maybe expand this with device maps or whatnot?) xmlNodePtr backing = xmlNewChild (instanceNode, NULL, BAD_CAST "backing", NULL); xmlNodePtr root = xmlNewChild (backing, NULL, BAD_CAST "root", NULL); assert (instance->params.root); _ATTRIBUTE(root, "type", ncResourceTypeName[instance->params.root->type]); } _ELEMENT(instanceNode, "name", instance->instanceId); _ELEMENT(instanceNode, "uuid", instance->uuid); _ELEMENT(instanceNode, "reservation", instance->reservationId); _ELEMENT(instanceNode, "user", instance->userId); _ELEMENT(instanceNode, "dnsName", instance->dnsName); _ELEMENT(instanceNode, "privateDnsName", instance->privateDnsName); _ELEMENT(instanceNode, "instancePath", instance->instancePath); if (instance->params.kernel) { char * path = instance->params.kernel->backingPath; if (path_check (path, "kernel")) goto free; // sanity check _ELEMENT(instanceNode, "kernel", path); } if (instance->params.ramdisk) { char * path = instance->params.ramdisk->backingPath; if (path_check (path, "ramdisk")) goto free; // sanity check _ELEMENT(instanceNode, "ramdisk", path); } _ELEMENT(instanceNode, "consoleLogPath", instance->consoleFilePath); _ELEMENT(instanceNode, "userData", instance->userData); _ELEMENT(instanceNode, "launchIndex", instance->launchIndex); char cores_s [10]; snprintf (cores_s, sizeof (cores_s), "%d", instance->params.cores); _ELEMENT(instanceNode, "cores", cores_s); char memory_s [10]; snprintf (memory_s, sizeof (memory_s), "%d", instance->params.mem * 1024); _ELEMENT(instanceNode, "memoryKB", memory_s); { // SSH-key related xmlNodePtr key = _NODE(instanceNode, "key"); _ATTRIBUTE(key, "isKeyInjected", _BOOL(instance->do_inject_key)); _ATTRIBUTE(key, "sshKey", instance->keyName); } { // OS-related specs xmlNodePtr os = _NODE(instanceNode, "os"); _ATTRIBUTE(os, "platform", instance->platform); _ATTRIBUTE(os, "virtioRoot", _BOOL(config_use_virtio_root)); _ATTRIBUTE(os, "virtioDisk", _BOOL(config_use_virtio_disk)); _ATTRIBUTE(os, "virtioNetwork", _BOOL(config_use_virtio_net)); } { // disks specification xmlNodePtr disks = _NODE(instanceNode, "disks"); // the first disk should be the root disk (at least for Windows) for (int root=1; root>=0; root--){ for (int i=0; i<EUCA_MAX_VBRS && i<instance->params.virtualBootRecordLen; i++) { const virtualBootRecord * vbr = &(instance->params.virtualBootRecord[i]); // skip empty entries, if any if (vbr==NULL) continue; // do EMI on the first iteration of the outer loop if (root && vbr->type != NC_RESOURCE_IMAGE) continue; // ignore EMI on the second iteration of the outer loop if (!root && vbr->type == NC_RESOURCE_IMAGE) continue; // skip anything without a device on the guest, e.g., kernel and ramdisk if (!strcmp ("none", vbr->guestDeviceName)) continue; // for Linux instances on Xen, partitions can be used directly, so disks can be skipped unless booting from EBS if (strstr (instance->platform, "linux") && strstr (instance->hypervisorType, "xen")) { if (vbr->partitionNumber == 0 && vbr->type == NC_RESOURCE_IMAGE) { continue; } } else { // on all other os + hypervisor combinations, disks are used, so partitions must be skipped if (vbr->partitionNumber > 0) { continue; } } xmlNodePtr disk = _ELEMENT(disks, "diskPath", vbr->backingPath); _ATTRIBUTE(disk, "targetDeviceType", libvirtDevTypeNames[vbr->guestDeviceType]); _ATTRIBUTE(disk, "targetDeviceName", vbr->guestDeviceName); char devstr[SMALL_CHAR_BUFFER_SIZE]; snprintf(devstr, SMALL_CHAR_BUFFER_SIZE, "%s", vbr->guestDeviceName); if (config_use_virtio_root) { devstr[0] = 'v'; _ATTRIBUTE(disk, "targetDeviceNameVirtio", devstr); _ATTRIBUTE(disk, "targetDeviceBusVirtio", "virtio"); } _ATTRIBUTE(disk, "targetDeviceBus", libvirtBusTypeNames[vbr->guestDeviceBus]); _ATTRIBUTE(disk, "sourceType", libvirtSourceTypeNames[vbr->backingType]); if (root) { xmlNodePtr rootNode = _ELEMENT(disks, "root", NULL); _ATTRIBUTE(rootNode, "device", devstr); char root_uuid[64] = ""; if (get_blkid (vbr->backingPath, root_uuid, sizeof(root_uuid)) == 0) { assert (strlen (root_uuid)); _ATTRIBUTE(rootNode, "uuid", root_uuid); } } } if (strlen (instance->floppyFilePath)) { _ELEMENT(disks, "floppyPath", instance->floppyFilePath); } } } if (instance->params.nicType!=NIC_TYPE_NONE) { // NIC specification xmlNodePtr nics = _NODE(instanceNode, "nics"); xmlNodePtr nic = _NODE(nics, "nic"); _ATTRIBUTE(nic, "bridgeDeviceName", instance->params.guestNicDeviceName); _ATTRIBUTE(nic, "mac", instance->ncnet.privateMac); } ret = write_xml_file (doc, instance->instanceId, instance->xmlFilePath, "instance"); free: xmlFreeDoc(doc); pthread_mutex_unlock (&xml_mutex); return ret; }
int extract(void) { ARCHD *arcn; int res; off_t cnt; struct stat sb; int fd; time_t now; arcn = &archd; /* * figure out archive type; pass any format specific options to the * archive option processing routine; call the format init routine; * start up the directory modification time and access mode database */ if ((get_arc() < 0) || ((*frmt->options)() < 0) || ((*frmt->st_rd)() < 0) || (dir_start() < 0)) return 1; now = time((time_t *)NULL); #if !HAVE_NBTOOL_CONFIG_H if (do_chroot) (void)fdochroot(cwdfd); #endif /* * When we are doing interactive rename, we store the mapping of names * so we can fix up hard links files later in the archive. */ if (iflag && (name_start() < 0)) return 1; /* * step through each entry on the archive until the format read routine * says it is done */ while (next_head(arcn) == 0) { int write_to_hard_link = 0; if (arcn->type == PAX_GLL || arcn->type == PAX_GLF) { /* * we need to read, to get the real filename */ if (!(*frmt->rd_data)(arcn, -arcn->type, &cnt)) (void)rd_skip(cnt + arcn->pad); continue; } /* * check for pattern, and user specified options match. When * all the patterns are matched we are done */ if ((res = pat_match(arcn)) < 0) break; if ((res > 0) || (sel_chk(arcn) != 0)) { /* * file is not selected. skip past any file * data and padding and go back for the next * archive member */ (void)rd_skip(arcn->skip + arcn->pad); continue; } if (kflag && (lstat(arcn->name, &sb) == 0)) { (void)rd_skip(arcn->skip + arcn->pad); continue; } /* * with -u or -D only extract when the archive member is newer * than the file with the same name in the file system (no * test of being the same type is required). * NOTE: this test is done BEFORE name modifications as * specified by pax. this operation can be confusing to the * user who might expect the test to be done on an existing * file AFTER the name mod. In honesty the pax spec is probably * flawed in this respect. ignore this for GNU long links. */ if ((uflag || Dflag) && ((lstat(arcn->name, &sb) == 0))) { if (uflag && Dflag) { if ((arcn->sb.st_mtime <= sb.st_mtime) && (arcn->sb.st_ctime <= sb.st_ctime)) { (void)rd_skip(arcn->skip + arcn->pad); continue; } } else if (Dflag) { if (arcn->sb.st_ctime <= sb.st_ctime) { (void)rd_skip(arcn->skip + arcn->pad); continue; } } else if (arcn->sb.st_mtime <= sb.st_mtime) { (void)rd_skip(arcn->skip + arcn->pad); continue; } } /* * this archive member is now been selected. modify the name. */ if ((pat_sel(arcn) < 0) || ((res = mod_name(arcn, RENM)) < 0)) break; if (res > 0) { /* * a bad name mod, skip and purge name from link table */ purg_lnk(arcn); (void)rd_skip(arcn->skip + arcn->pad); continue; } if (arcn->name[0] == '/' && !check_Aflag()) { memmove(arcn->name, arcn->name + 1, strlen(arcn->name)); } /* * Non standard -Y and -Z flag. When the existing file is * same age or newer skip; ignore this for GNU long links. */ if ((Yflag || Zflag) && ((lstat(arcn->name, &sb) == 0))) { if (Yflag && Zflag) { if ((arcn->sb.st_mtime <= sb.st_mtime) && (arcn->sb.st_ctime <= sb.st_ctime)) { (void)rd_skip(arcn->skip + arcn->pad); continue; } } else if (Yflag) { if (arcn->sb.st_ctime <= sb.st_ctime) { (void)rd_skip(arcn->skip + arcn->pad); continue; } } else if (arcn->sb.st_mtime <= sb.st_mtime) { (void)rd_skip(arcn->skip + arcn->pad); continue; } } if (vflag) { if (vflag > 1) ls_list(arcn, now, listf); else { (void)safe_print(arcn->name, listf); vfpart = 1; } } /* * if required, chdir around. */ if ((arcn->pat != NULL) && (arcn->pat->chdname != NULL) && !to_stdout) dochdir(arcn->pat->chdname); if (secure && path_check(arcn, 0) != 0) { (void)rd_skip(arcn->skip + arcn->pad); continue; } /* * all ok, extract this member based on type */ if ((arcn->type != PAX_REG) && (arcn->type != PAX_CTG)) { /* * process archive members that are not regular files. * throw out padding and any data that might follow the * header (as determined by the format). */ if ((arcn->type == PAX_HLK) || (arcn->type == PAX_HRG)) res = lnk_creat(arcn, &write_to_hard_link); else res = node_creat(arcn); if (!write_to_hard_link) { (void)rd_skip(arcn->skip + arcn->pad); if (res < 0) purg_lnk(arcn); if (vflag && vfpart) { (void)putc('\n', listf); vfpart = 0; } continue; } } if (to_stdout) fd = STDOUT_FILENO; else { /* * We have a file with data here. If we cannot create * it, skip over the data and purge the name from hard * link table. */ if ((fd = file_creat(arcn, write_to_hard_link)) < 0) { (void)fflush(listf); (void)rd_skip(arcn->skip + arcn->pad); purg_lnk(arcn); continue; } } /* * extract the file from the archive and skip over padding and * any unprocessed data */ res = (*frmt->rd_data)(arcn, fd, &cnt); if (!to_stdout) file_close(arcn, fd); if (vflag && vfpart) { (void)putc('\n', listf); vfpart = 0; } if (!res) (void)rd_skip(cnt + arcn->pad); /* * if required, chdir around. */ if ((arcn->pat != NULL) && (arcn->pat->chdname != NULL)) fdochdir(cwdfd); } /* * all done, restore directory modes and times as required; make sure * all patterns supplied by the user were matched; block off signals * to avoid chance for multiple entry into the cleanup code. */ (void)(*frmt->end_rd)(); (void)sigprocmask(SIG_BLOCK, &s_mask, (sigset_t *)NULL); ar_close(); proc_dir(); pat_chk(); return 0; }
int main(int argc, char** argv) { int c; int errors; int fileid; int verbose; int quiet; int check_loaded; errors = 0; verbose = 0; quiet = 0; check_loaded = 0; while ((c = getopt(argc, argv, "nqv")) != -1) { switch (c) { case 'q': quiet = 1; verbose = 0; break; case 'v': verbose = 1; quiet = 0; break; case 'n': check_loaded = 1; break; default: usage(); } } argc -= optind; argv += optind; if (argc == 0) usage(); while (argc-- != 0) { if (path_check(argv[0], quiet) == 0) { fileid = kldload(argv[0]); if (fileid < 0) { if (check_loaded != 0 && errno == EEXIST) { if (verbose) printf("%s is already " "loaded\n", argv[0]); } else { switch (errno) { case EEXIST: warnx("can't load %s: module " "already loaded or " "in kernel", argv[0]); break; case ENOEXEC: warnx("an error occurred while " "loading the module. " "Please check dmesg(8) for " "more details."); break; default: warn("can't load %s", argv[0]); break; } errors++; } } else { if (verbose) printf("Loaded %s, id=%d\n", argv[0], fileid); } } else { errors++; } argv++; } return (errors ? 1 : 0); }