Applied patch by Marco Minutoli:

Added a new command line utility "mkfs" which can initialize a given volume
with a file system by it's short name via the new Disk Device API.
Thanks!


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25491 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2008-05-14 15:48:41 +00:00
parent fe76020396
commit 7557d13189
6 changed files with 299 additions and 1 deletions

View File

@ -35,7 +35,7 @@ BEOS_BIN = "[" addattr alert arp base64 basename bc beep bootman bzip2 cal cat
ideinfo idestatus ifconfig <bin>install installsound iroster isvolume join
keymap kill less lessecho lesskey link listarea listattr listdev listimage
listport listres listsem ln locate logger login logname ls lsindex m4 make
makebootable md5sum merge mimeset mkdos mkdir mkfifo mkindex modifiers mount
makebootable md5sum merge mimeset mkdos mkdir mkfifo mkfs mkindex modifiers mount
mount_nfs mountvolume mv nc netstat nl nohup od open passwd paste patch
pathchk pc ping play playfile playsound playwav pr prio printenv printf ps
ptx pwd query quit readlink release renice rescan rlog rm rmattr rmindex

View File

@ -185,6 +185,7 @@ SubInclude HAIKU_TOP src bin make ;
SubInclude HAIKU_TOP src bin makebootable ;
#SubInclude HAIKU_TOP src bin makeudfimage ;
SubInclude HAIKU_TOP src bin mkdos ;
SubInclude HAIKU_TOP src bin mkfs ;
SubInclude HAIKU_TOP src bin multiuser ;
SubInclude HAIKU_TOP src bin patch ;
SubInclude HAIKU_TOP src bin pc ;

138
src/bin/mkfs/FsCreator.cpp Normal file
View File

@ -0,0 +1,138 @@
/*
* Copyright 2008 Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Marco Minutoli, mminutoli@gmail.com
*/
#include "FsCreator.h"
#include <iostream>
#include <DiskSystem.h>
FsCreator::FsCreator(const char* devPath, BString& type,
BString& volumeName, const char* fsOpt, bool verbose)
:
fType(type),
fDevicePath(devPath),
fVolumeName(volumeName),
fFsOptions(fsOpt),
fVerbose(verbose)
{
BDiskDeviceRoster roster;
status_t ret = roster.GetDeviceForPath(devPath, &fDevice);
if (ret != B_OK) {
std::cerr << "Error: Failed to get disk device for path "
<< devPath << ": " << strerror(ret);
}
}
bool
FsCreator::Run()
{
// check that the device is writable
if (fDevice.IsReadOnly()) {
std::cerr << "Error: Can't Inizialize the device. "
"It is read only.\n";
return false;
}
// check if the device is mounted
if (fDevice.IsMounted()) {
std::cerr << "Error: The device has to be unmounted before.\n";
return false;
}
BDiskSystem diskSystem;
BDiskDeviceRoster dDRoster;
bool found = false;
while (dDRoster.GetNextDiskSystem(&diskSystem) == B_OK) {
if (diskSystem.IsFileSystem() && diskSystem.SupportsInitializing()) {
if (diskSystem.ShortName() == fType) {
found = true;
break;
}
}
}
if (!found) {
std::cerr << "Error: " << fType.String()
<< " is an invalid or unsupported file system type.\n";
return false;
}
// prepare the device for modifications
status_t ret = fDevice.PrepareModifications();
if (ret != B_OK) {
std::cerr << "Error: A problem occurred preparing the device for the"
"modifications\n";
return false;
}
if (fVerbose)
std::cout << "Preparing for modifications...\n\n";
// validate parameters
BString name(fVolumeName);
if (fDevice.ValidateInitialize(diskSystem.PrettyName(),
&fVolumeName, fFsOptions) != B_OK) {
std::cerr << "Error: Parameters validation failed. "
"Check what you wrote\n";
std::cerr << ret;
return false;
}
if (fVerbose)
std::cout << "Parameters Validation...\n\n";
if (name != fVolumeName)
std::cout << "Volume name was adjusted to "
<< fVolumeName.String() << std::endl;
// Initialize the partition
ret = fDevice.Initialize(diskSystem.PrettyName(),
fVolumeName.String(), fFsOptions);
if (ret != B_OK) {
std::cerr << "Initialization failed: " << strerror(ret) << std::endl;
return false;
}
std::cout << "\nAre you sure you want to do this now?\n"
<< "\nALL YOUR DATA in " << fDevicePath.String()
<< " will be lost forever.\n";
BString reply;
do {
std::cout << "Continue? [yes|no]: ";
reply = _ReadLine();
if (reply == "")
reply = "no"; // silence is dissence
} while (reply != "yes" && reply != "no");
if (reply == "yes") {
ret = fDevice.CommitModifications();
if (ret == B_OK) {
if (fVerbose) {
std::cout << "Volume " << fDevice.ContentName()
<< " has been initialized successfully!\n";
}
} else {
std::cout << "Error: Initialization of " << fDevice.ContentName()
<< " failed: " << strerror(ret) << std::endl;
return false;
}
}
return true;
}
inline BString
FsCreator::_ReadLine()
{
char line[255];
cin.getline(line, sizeof(line), '\n');
return line;
}

34
src/bin/mkfs/FsCreator.h Normal file
View File

@ -0,0 +1,34 @@
/*
* Copyright 2008 Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Marco Minutoli, mminutoli@gmail.com
*/
#ifndef _FSCREATOR_H_
#define _FSCREATOR_H_
#include <String.h>
#include <DiskDevice.h>
#include <DiskDeviceRoster.h>
class FsCreator {
public:
FsCreator(const char* devPath, BString& type, BString& volumeName,
const char* fsOpt, bool verbose);
bool Run();
private:
inline BString _ReadLine();
BString fType;
BString fDevicePath;
BString& fVolumeName;
const char* fFsOptions;
BDiskDevice fDevice;
BPartition* fPartition;
const bool fVerbose;
};
#endif // _FSCREATOR_H_

9
src/bin/mkfs/Jamfile Normal file
View File

@ -0,0 +1,9 @@
SubDir HAIKU_TOP src bin mkfs ;
UsePrivateHeaders shared ;
UsePrivateHeaders storage ;
BinCommand mkfs :
main.cpp
FsCreator.cpp
: be $(TARGET_LIBSTDC++) ;

116
src/bin/mkfs/main.cpp Normal file
View File

@ -0,0 +1,116 @@
/*
* Copyright 2008 Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Marco Minutoli, mminutoli@gmail.com
*/
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <String.h>
#include <getopt.h>
#include "FsCreator.h"
extern "C" const char* __progname;
static const char* kProgramName = __progname;
static const char* kUsage =
"Usage: %s -t <fs> <options> <device> <volume name>\n"
"\n"
"Options:\n"
" -t, --type <fs> - set type of filesystem to create\n\n"
" -h, --help - print this help text\n"
" -o, --options <opt> - set fs specific options\n"
" -v, --verbose - set verbose output\n"
;
/*
* Print program help on the right stream
*/
inline void
print_help(bool out)
{
fprintf(out ? stdout : stderr, kUsage, kProgramName, kProgramName);
}
/*
* Print program help and exit
*/
inline void
print_help_exit(bool out)
{
print_help(out);
exit(out ? 0 : 1);
}
int
main(int argc, char* const* argv)
{
const struct option longOptions[] = {
{ "help", 0, NULL, 'h' },
{ "options", 0, NULL, 'o' },
{ "type", 1, NULL, 't' },
{ "verbose", 0, NULL, 'v' },
{ NULL, 0, NULL, 0 }
};
const char *shortOptions = "t:o:hv";
// parse argument list
int32 nextOption;
BString fsType;
BString fsOptions;
bool verbose = false;
nextOption = getopt_long(argc, argv, shortOptions, longOptions, NULL);
if (nextOption == 't')
fsType = optarg;
else
print_help_exit(nextOption == 'h' ? true : false);
do {
nextOption = getopt_long(argc, argv, shortOptions, longOptions, NULL);
switch (nextOption) {
case 't': // -t or --type again?
print_help_exit(false);
break;
case 'h': // -h or --help
print_help_exit(true);
break;
case 'v': // -v or --verbose
verbose = true;
break;
case 'o': // -o or --options
fsOptions << optarg;
break;
case '?': // invalid option
break;
case -1: // done with options
break;
default: // everything else
print_help(false);
abort();
}
} while (nextOption != -1);
// the device name should be the first non-option element
// right before the VolumeName
if (optind != argc - 2)
print_help_exit(false);
const char* devPath = argv[optind];
BString volName = argv[argc-1];
FsCreator* creator = new FsCreator(devPath, fsType, volName,
fsOptions.String(), verbose);
if (creator == NULL) {
std::cerr << "Error: FsCreator can't be allocated\n";
abort();
}
return creator->Run();
}