Exemplo n.º 1
0
/*! Gets the boot device, scans all of its partitions, gets the
	boot partition, and mounts its file system.

	\param args The stage 2 arguments.
	\param _bootVolume On success set to the boot volume.
	\return \c B_OK on success, another error code otherwise.
*/
status_t
get_boot_file_system(stage2_args* args, BootVolume& _bootVolume)
{
	status_t error = platform_add_boot_device(args, &gBootDevices);
	if (error != B_OK)
		return error;

	NodeIterator iterator = gBootDevices.GetIterator();
	while (iterator.HasNext()) {
		Node *device = iterator.Next();

		error = add_partitions_for(device, false, true);
		if (error != B_OK)
			continue;

		NodeList bootPartitions;
		error = platform_get_boot_partitions(args, device, &gPartitions, &bootPartitions);
		if (error != B_OK)
			continue;

		NodeIterator partitionIterator = bootPartitions.GetIterator();
		while (partitionIterator.HasNext()) {
			Partition *partition = (Partition*)partitionIterator.Next();

			Directory *fileSystem;
			error = partition->Mount(&fileSystem, true);
			if (error != B_OK) {
				// this partition doesn't contain any known file system; we
				// don't need it anymore
				gPartitions.Remove(partition);
				delete partition;
				continue;
			}

			// init the BootVolume
			error = _bootVolume.SetTo(fileSystem);
			if (error != B_OK)
				continue;

			sBootDevice = device;
			return B_OK;
		}
	}

	return B_ERROR;
}
Exemplo n.º 2
0
status_t
platform_get_boot_partition(struct stage2_args *args, Node *device,
	NodeList *list, boot::Partition **_partition)
{
	NodeIterator iterator = list->GetIterator();
	boot::Partition *partition = NULL;
	while ((partition = (boot::Partition *)iterator.Next()) != NULL) {
		// ToDo: just take the first partition for now
		*_partition = partition;
		return B_OK;
	}

	return B_ENTRY_NOT_FOUND;
}
Exemplo n.º 3
0
Partition::~Partition()
{
	TRACE(("%p Partition::~Partition\n", this));

	// Tell the children that their parent is gone

	NodeIterator iterator = gPartitions.GetIterator();
	Partition *child;

	while ((child = (Partition *)iterator.Next()) != NULL) {
		if (child->Parent() == this)
			child->SetParent(NULL);
	}

	close(fFD);
}
Exemplo n.º 4
0
status_t
mount_file_systems(stage2_args *args)
{
	// mount other partitions on boot device (if any)
	NodeIterator iterator = gPartitions.GetIterator();

	Partition *partition = NULL;
	while ((partition = (Partition *)iterator.Next()) != NULL) {
		// don't scan known partitions again
		if (partition->IsFileSystem())
			continue;

		// remove the partition if it doesn't contain a (known) file system
		if (partition->Scan(true) != B_OK && !partition->IsFileSystem()) {
			gPartitions.Remove(partition);
			delete partition;
		}
	}

	// add all block devices the platform has for us

	status_t status = platform_add_block_devices(args, &gBootDevices);
	if (status < B_OK)
		return status;

	iterator = gBootDevices.GetIterator();
	Node *device = NULL, *last = NULL;
	while ((device = iterator.Next()) != NULL) {
		// don't scan former boot device again
		if (device == sBootDevice)
			continue;

		if (add_partitions_for(device, true) == B_OK) {
			// ToDo: we can't delete the object here, because it must
			//	be removed from the list before we know that it was
			//	deleted.

/*			// if the Release() deletes the object, we need to skip it
			if (device->Release() > 0) {
				list_remove_item(&gBootDevices, device);
				device = last;
			}
*/
(void)last;
		}
		last = device;
	}

	if (gPartitions.IsEmpty())
		return B_ENTRY_NOT_FOUND;

#if 0
	void *cookie;
	if (gRoot->Open(&cookie, O_RDONLY) == B_OK) {
		Directory *directory;
		while (gRoot->GetNextNode(cookie, (Node **)&directory) == B_OK) {
			char name[256];
			if (directory->GetName(name, sizeof(name)) == B_OK)
				printf(":: %s (%p)\n", name, directory);

			void *subCookie;
			if (directory->Open(&subCookie, O_RDONLY) == B_OK) {
				while (directory->GetNextEntry(subCookie, name, sizeof(name)) == B_OK) {
					printf("\t%s\n", name);
				}
				directory->Close(subCookie);
			}
		}
		gRoot->Close(cookie);
	}
#endif

	return B_OK;
}
Exemplo n.º 5
0
status_t
Partition::Scan(bool mountFileSystems, bool isBootDevice)
{
	// scan for partitions first (recursively all eventual children as well)

	TRACE(("%p Partition::Scan()\n", this));

	// if we were not booted from the real boot device, we won't scan
	// the device we were booted from (which is likely to be a slow
	// floppy or CD)
	if (isBootDevice && gKernelArgs.boot_volume.GetBool(
			BOOT_VOLUME_BOOTED_FROM_IMAGE, false)) {
		return B_ENTRY_NOT_FOUND;
	}

	const partition_module_info *bestModule = NULL;
	void *bestCookie = NULL;
	float bestPriority = -1;

	for (int32 i = 0; i < sNumPartitionModules; i++) {
		const partition_module_info *module = sPartitionModules[i];
		void *cookie = NULL;
		NodeOpener opener(this, O_RDONLY);

		TRACE(("check for partitioning_system: %s\n", module->pretty_name));

		float priority
			= module->identify_partition(opener.Descriptor(), this, &cookie);
		if (priority < 0.0)
			continue;

		TRACE(("  priority: %ld\n", (int32)(priority * 1000)));
		if (priority <= bestPriority) {
			// the disk system recognized the partition worse than the currently
			// best one
			module->free_identify_partition_cookie(this, cookie);
			continue;
		}

		// a new winner, replace the previous one
		if (bestModule)
			bestModule->free_identify_partition_cookie(this, bestCookie);
		bestModule = module;
		bestCookie = cookie;
		bestPriority = priority;
	}

	// find the best FS module
	const file_system_module_info *bestFSModule = NULL;
	float bestFSPriority = -1;
	for (int32 i = 0; i < sNumFileSystemModules; i++) {
		if (sFileSystemModules[i]->identify_file_system == NULL)
			continue;

		float priority = sFileSystemModules[i]->identify_file_system(this);
		if (priority <= 0)
			continue;

		if (priority > bestFSPriority) {
			bestFSModule = sFileSystemModules[i];
			bestFSPriority = priority;
		}
	}

	// now let the best matching disk system scan the partition
	if (bestModule && bestPriority >= bestFSPriority) {
		NodeOpener opener(this, O_RDONLY);
		status_t status = bestModule->scan_partition(opener.Descriptor(), this,
			bestCookie);
		bestModule->free_identify_partition_cookie(this, bestCookie);

		if (status != B_OK) {
			dprintf("Partitioning module `%s' recognized the partition, but "
				"failed to scan it\n", bestModule->pretty_name);
			return status;
		}

		fIsPartitioningSystem = true;

		content_type = bestModule->pretty_name;
		flags |= B_PARTITION_PARTITIONING_SYSTEM;

		// now that we've found something, check our children
		// out as well!

		NodeIterator iterator = fChildren.GetIterator();
		Partition *child = NULL;

		while ((child = (Partition *)iterator.Next()) != NULL) {
			TRACE(("%p Partition::Scan(): scan child %p (start = %Ld, size "
				"= %Ld, parent = %p)!\n", this, child, child->offset,
				child->size, child->Parent()));

			child->Scan(mountFileSystems);

			if (!mountFileSystems || child->IsFileSystem()) {
				// move the partitions containing file systems to the partition
				// list
				fChildren.Remove(child);
				gPartitions.Add(child);
			}
		}

		// remove all unused children (we keep only file systems)

		while ((child = (Partition *)fChildren.Head()) != NULL) {
			fChildren.Remove(child);
			delete child;
		}

		// remember the name of the module that identified us
		fModuleName = bestModule->module.name;

		return B_OK;
	}

	// scan for file systems

	if (mountFileSystems) {
		// TODO: Use the FS module we've got, if any. Requires to implement the
		// identify_file_system() hook in every FS.
		return Mount();
	}

	return B_ENTRY_NOT_FOUND;
}