From c00124df280431bb3f1fd26ef0f5c863365c6474 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 14 Sep 2004 06:55:15 +0000 Subject: [PATCH] Change -cp option to -ci ("copy in"). Add -co option ("copy out"). Add filesys_done() for closing up filesystem shop. Add -q option for powering off. --- src/filesys/filesys.c | 9 ++++++ src/filesys/filesys.h | 1 + src/filesys/fsutil.c | 74 +++++++++++++++++++++++++++++++++++-------- src/filesys/fsutil.h | 4 ++- src/threads/init.c | 42 +++++++++++++++++++++--- 5 files changed, 111 insertions(+), 19 deletions(-) diff --git a/src/filesys/filesys.c b/src/filesys/filesys.c index 8bd39e8..59212ca 100644 --- a/src/filesys/filesys.c +++ b/src/filesys/filesys.c @@ -131,6 +131,15 @@ filesys_init (bool format) PANIC ("can't open root dir file"); } +/* Shuts down the filesystem module, writing any unwritten data + to disk. + Currently there's nothing to do. You'll need to add code here + when you implement write-behind caching. */ +void +filesys_done (void) +{ +} + /* Creates a file named NAME with the given INITIAL_SIZE. Returns true if successful, false otherwise. Fails if a file named NAME already exists, diff --git a/src/filesys/filesys.h b/src/filesys/filesys.h index 0105101..9563fbb 100644 --- a/src/filesys/filesys.h +++ b/src/filesys/filesys.h @@ -12,6 +12,7 @@ extern struct disk *filesys_disk; extern struct file *free_map_file; void filesys_init (bool format); +void filesys_done (void); bool filesys_create (const char *name, off_t initial_size); struct file *filesys_open (const char *name); bool filesys_remove (const char *name); diff --git a/src/filesys/fsutil.c b/src/filesys/fsutil.c index 3876ee9..6336346 100644 --- a/src/filesys/fsutil.c +++ b/src/filesys/fsutil.c @@ -9,9 +9,12 @@ #include "threads/mmu.h" #include "threads/palloc.h" -/* Filename and file size to use for copy operations, - as "filename:size". */ -char *fsutil_copy_arg; +/* Destination filename and size for copy-in operations. */ +char *fsutil_copyin_file; +int fsutil_copyin_size; + +/* Source filename for copy-out operations. */ +char *fsutil_copyout_file; /* Name of a file print to print to console. */ char *fsutil_print_file; @@ -29,7 +32,7 @@ bool fsutil_dump_filesys; to a file named FILENAME in the filesystem. The file will be SIZE bytes in length. */ static void -copy (const char *filename, off_t size) +copy_in (const char *filename, off_t size) { struct disk *src; struct file *dst; @@ -68,22 +71,65 @@ copy (const char *filename, off_t size) file_close (dst); } +/* Copies FILENAME from the file system to the scratch disk. + The first four bytes of the first sector in the disk + receive the file's size in bytes as a little-endian integer. + The second and subsequent sectors receive the file's data. */ +static void +copy_out (const char *filename) +{ + void *buffer; + struct file *src; + struct disk *dst; + off_t size; + disk_sector_t sector; + + buffer = palloc_get (PAL_ASSERT | PAL_ZERO); + + /* Open source file. */ + src = filesys_open (filename); + if (src == NULL) + PANIC ("%s: open failed", filename); + size = file_length (src); + + /* Open target disk. */ + dst = disk_get (1, 0); + if (dst == NULL) + PANIC ("couldn't open target disk (hdc or hd1:0)"); + if (size + DISK_SECTOR_SIZE > (off_t) disk_size (dst) * DISK_SECTOR_SIZE) + PANIC ("target disk is too small for %lld-byte file", + (unsigned long long) size); + + /* Write size to sector 0. */ + *(uint32_t *) buffer = size; + disk_write (dst, 0, buffer); + + /* Do copy. */ + sector = 1; + while (size > 0) + { + int chunk_size = size > DISK_SECTOR_SIZE ? DISK_SECTOR_SIZE : size; + if (file_read (src, buffer, chunk_size) != chunk_size) + PANIC ("%s: read failed with %lld bytes unread", + filename, (unsigned long long) size); + disk_write (dst, sector++, buffer); + size -= chunk_size; + } + palloc_free (buffer); + + file_close (src); +} + /* Executes the filesystem operations described by the variables declared in fsutil.h. */ void fsutil_run (void) { - if (fsutil_copy_arg != NULL) - { - char *save; - char *filename = strtok_r (fsutil_copy_arg, ":", &save); - char *size = strtok_r (NULL, "", &save); - - if (filename == NULL || size == NULL) - PANIC ("bad format for -cp option; use -u for usage"); + if (fsutil_copyin_file != NULL) + copy_in (fsutil_copyin_file, fsutil_copyin_size); - copy (filename, atoi (size)); - } + if (fsutil_copyout_file != NULL) + copy_out (fsutil_copyout_file); if (fsutil_print_file != NULL) fsutil_print (fsutil_print_file); diff --git a/src/filesys/fsutil.h b/src/filesys/fsutil.h index 8962a8a..2d711e9 100644 --- a/src/filesys/fsutil.h +++ b/src/filesys/fsutil.h @@ -3,7 +3,9 @@ #include -extern char *fsutil_copy_arg; +extern char *fsutil_copyin_file; +extern int fsutil_copyin_size; +extern char *fsutil_copyout_file; extern char *fsutil_print_file; extern char *fsutil_remove_file; extern bool fsutil_list_files; diff --git a/src/threads/init.c b/src/threads/init.c index 129d797..203b79d 100644 --- a/src/threads/init.c +++ b/src/threads/init.c @@ -46,8 +46,12 @@ static bool format_filesys; static char *initial_program; #endif +/* Power off after running requested actions? */ +static bool power_off; + static void ram_init (void); static void argv_init (void); +static void do_power_off (void); int main (void) NO_RETURN; @@ -112,6 +116,9 @@ main (void) test (); #endif + if (power_off) + do_power_off (); + /* Terminate this thread. */ thread_exit (); } @@ -138,7 +145,7 @@ static void argv_init (void) { char *cmd_line, *pos; - char *argv[LOADER_CMD_LINE_LEN / 2 + 1]; + char *argv[LOADER_CMD_LINE_LEN / 2 + 2]; int argc = 0; int i; @@ -154,6 +161,7 @@ argv_init (void) pos = strchr (pos, '\0') + 1; } argv[argc] = ""; + argv[argc + 1] = ""; /* Parse the words. */ for (i = 0; i < argc; i++) @@ -161,6 +169,8 @@ argv_init (void) random_init (atoi (argv[++i])); else if (!strcmp (argv[i], "-d")) debug_enable (argv[++i]); + else if (!strcmp (argv[i], "-q")) + power_off = true; #ifdef USERPROG else if (!strcmp (argv[i], "-ex")) initial_program = argv[++i]; @@ -168,8 +178,13 @@ argv_init (void) #ifdef FILESYS else if (!strcmp (argv[i], "-f")) format_filesys = true; - else if (!strcmp (argv[i], "-cp")) - fsutil_copy_arg = argv[++i]; + else if (!strcmp (argv[i], "-ci")) + { + fsutil_copyin_file = argv[++i]; + fsutil_copyin_size = atoi (argv[++i]); + } + else if (!strcmp (argv[i], "-co")) + fsutil_copyout_file = argv[++i]; else if (!strcmp (argv[i], "-p")) fsutil_print_file = argv[++i]; else if (!strcmp (argv[i], "-r")) @@ -190,15 +205,34 @@ argv_init (void) #endif #ifdef FILESYS " -f Format the filesystem disk (hdb or hd0:1).\n" - " -cp FILENAME:SIZE Copy SIZE bytes from the scratch disk (hdc\n" + " -ci FILENAME SIZE Copy SIZE bytes from the scratch disk (hdc\n" " or hd1:0) into the filesystem as FILENAME\n" + " -co FILENAME Copy FILENAME to the scratch disk, with\n" + " size at start of sector 0 and data afterward\n" " -p FILENAME Print the contents of FILENAME\n" " -r FILENAME Delete FILENAME\n" " -ls List the files in the filesystem\n" " -D Dump complete filesystem contents\n" #endif + " -q Power off after doing requested actions.\n" ); } else PANIC ("unknown option `%s'", argv[i]); } + +void +do_power_off (void) +{ + const char s[] = "Shutdown"; + const char *p; + +#ifdef FILESYS + filesys_done (); +#endif + + printf ("Powering off...\n"); + for (p = s; *p != '\0'; p++) + outb (0x8900, *p); + for (;;); +} -- 2.30.2