联系方式

  • QQ:99515681
  • 邮箱:99515681@qq.com
  • 工作时间:8:00-23:00
  • 微信:codinghelp

您当前位置:首页 >> C/C++编程C/C++编程

日期:2020-02-29 10:00

CMPSC 311 - Introduction

to Systems Programming

Assignment #2 – The Lion Cloud Driver v1.0

Professor Patrick McDaniel

CMPSC 311 - Introduction to Systems Programming

Overview

• Idea you are to maintain the correct file

contents in a Cloud Based virtual storage

device.

• You will write code to communicate with a

devices over a a virtualized bus that will

store file-system data.

• 3 things to know

‣ How file I/O works

‣ How the LoinCloud bus works

‣ How to make the memory device stuff look

like files

LC Simulator (provided)

LC Filesystem Driver (your code)

LC

LC Storage Device

(device I/O bus)

Assignment Basics

• You are to write the file operation functions defined in the lcloud_filesys.c

‣ Translate then file operations into device IO operations

‣ Maintain, in the memory device, the file contents

• You must insert data, read data, and maintain a file handle and a file

allocation data.

• Your code: open, read, write, close, seek …

• Your code will be exercised by the simulator given to you (it will call your

functions and verify the data you are returning is correct).

Your driver

• LcFHandle lcopen( const char *path ); - This function will open a file

(named path, e.g.,) in the filesystem. If the file does not exist, it should be created and set

to zero length. If it does exist, it should be opened and its read/write postion should be

set to the first byte. Note that there are no subdirectories in the filesystem, just files (so

you can treat the path as a filename). The function should return a unique file handle

used for subsequent operations or -1 if a failure occurs.

• int lcclose( LcFHandle fh ); - This function closes the file referenced by the

file handle that was previously open. The function should fail (and return -1) if the file

handle is bad or the file was not previously open.

• int lcread( LcFHandle fh, char *buf, size_t len ); - This function

should read count bytes from the file referenced by the file handle at the current position.

Note that if there are not enough bytes left in the file, the function should read to the end

of the file and return the number of bytes read. If there are enough bytes to fulfill the

read, the function should return count. The function should fail (and return -1) if the file

handle is bad or the file was not previously open.

Your driver (cont.)

• int lcwrite( LcFHandle fh, char *buf, size_t len ); - The function

should write count bytes into the file referenced by the file handle. If the write goes

beyond the end of the file the size should be increased. The function should always return

the number of bytes written, e.g., count. The function should fail (and return -1) if the file

handle is bad or the file was not previously open.

• int lcseek( LcFHandle fh, size_t off ); - The function should set the

current position into the file to loc, where 0 is the first byte in the file. The function should

fail (and return -1) if the loc is beyond the end of the file, the file handle is bad or the file

was not previously open.

• int lcshutdown( void ); - - The function should shut down the system, including

powering off the devices and closing all files.

Maintaining file contents

len=0, pos=0

open(“file.txt”)

X X X X X

len=5, pos=5

write(“XXXXX”, 5)

X X X X X

len=5, pos=2

seek(2)

X X X X X

len=5, pos=5

read(4)

• Open prepares an empty file for reading (zero length)

• Write writes bytes into the file

• Seek seeks to a position in the file (end if pos > length)

• Read copies up to length number of bytes from the file

• Close deletes the contents

Lion Cloud Devices

• Each device has LC_DEVICE_NUMBER_SECTORS sectors and

LC_DEVICE_NUMBER_BLOCKS blocks. The blocks and sectors are zero indexed.

• A frame is memory block of LC_DEVICE_BLOCK_SIZE bytes.

• You can assume that there is only one device in the system.

LC

Sector 0

Block 0

Block 1

Block 2

Block b-1

Sector 1

Block 0

Block 1

Block 2

Block b-1

Sector s-1

Block 0

Block 1

Block 2

Block b-1

CART Opcode Execution

You communicate with devices through a set of registers

of different sizes that encode the opcode and arguments

for the operation. The “data” associated with the opcode

(where needed) is communicated through the fixed sized

transfer buffer (LC_DEVICE_BLOCK_SIZE).

LCloudRegisterFrame lcloud_io_bus( LCloudRegisterFrame frm, void *xfer );

B0 C0 C1 C2 D0 D1

4-bits 8-bits 8-bits 8-bits 16-bits 16-bits

B1

Most significant bit Least significant bit

Using the Lion Cloud Registers

• There are 7 registers: B0/B1 (4 bits), C0/C1/C2 (8 bits),

and D0/D1 (16 bits)

‣ B0 is always used to indicate who is the sender of the

message. It is always 0 when you are sending, 1 when it

is the devices responding.

‣ B1 always contains a return/status code, should always

be 0 when sending to devices. 1 is acknowledge/success

from device, anything else is failure.

‣ C0 is always the operation code (see LcOperationCode

type in lcloud_controller.h)

‣ The rest of the registers are dependent on the type of

operation being performed (see next)

B0 C0 C1 C2 D0 D1

4-bits 8-bits 8-bits 8-bits 16-bits 16-bits

B1

Most significant bit Least significant bit

Operation types / the IO bus

• LC_POWER_ON - Initialize interface to a given device

‣ All other registers should be 0 on both send and receive

• LC_POWER_OFF - Power off the device

‣ All other registers should be 0 on both send and receive

• LC_DEVPROBE - Probe the bus to see what devices are present

‣ d0 - contains a bit mask of present devices, where device there are a possible

16 devices, where the bit 2^x=1 indicates that device ID x is present. For

example if the 2^4 (16) is present, then you know device with ID 4 is on the bus.

Operation types / the IO bus (cont.)

• LC_BLOCK_XFER - Transfer a block to the device

‣ c1 - the device ID for the device to read from

‣ c2 - LC_XFER_WRITE for write, LC_XFER_READ for read

‣ d0 - sector to read/write from

‣ d1 - block to read/write from

LCloudRegisterFrame lcloud_io_bus( LCloudRegisterFrame frm, void *xfer );

xfer is NULL for every command except LC_BLOCK_XFER, in

which you put a pointer to a buffer to read or write from.

Summary

• To summarize, your code will receive commands from

the virtual application (simulator). It will do the

following functions to implement the device driver:

a. Power on the devices using the power on

b. Probe the bus to see what devices are available (one)

c. On writes, you have to figure out where to place the

data (and remember it)

d. On reads, return the previously stored data in those

blocks

e. Power off the controller when asked to

Start

POWER ON

PROBE BUS

OPEN

READ/WRITE

CLOSE

Honors option

• Honors option: When you receive the indication to shut down the device

cluster, you must go back and erase all of the data you wrote to the array.

That is you must write all zeros you previously used in any write operation,

regardless of what file it may have been mapped to. The program on exit will

indicate via the log whether you have successfully completed the honors

option:

Testing your program

• The testing of the program is performed by using the simulated

workloads. The main function provided to you simply calls the

simulator. To test the program, you execute the simulator using

the -v option, as:

• If you have implemented everything correctly, the log should

display the following message:

./lcloud_sim -v cmpsc311-assign2-manifest.txt cmpsc311-assign2-workload.txt

LionCloud simulation completed successfully!!!

Getting started …

• Get the file from the canvas page.

• Change into your development directory and unpack the file:

% cd ~/cmpsc311

% cp assign2-starter.tgz cmpsc311

% cd cmpsc311

% tar xvfz assign2-starter.tgz

% cd assign2

% make

Install libraries

• You will have to install some libraries you will need for the assignment. Run

the following command in your terminal window.

sudo apt-get install libcurl4-gnutls-dev libgcrypt-dev

Hints

• Use the logMessage interface to

log information about how your

program is running. (see next

page)

• Carefully read and understand the

error messages that are being

written to the log.

• Review the simulator code to see

how the interfaces in the program

should operate.

!!!!

logMessage()

• Available in the cmpsc311_log.h – provides you a way to print out

information from your code, and works like printf()

‣ logMessage( LEVEL, “Stuff … %d”, parameters );

‣ Use the “LcDriverLevel” level for your code (global value)

logMessage(lcDriverLevel, “This is my code %d [%s]”, val, str );

Open() pseudo-code

Open (path) {

1) check if file already open

(fail if already open)

2) pick unique file handle

3) save filename and file information locally

4) set file pointer to first byte

5) if file not exists

set length to 0

return file handle

}

Read() pseudo-code

Read ( file handle, length, buffer ) {

1) check if file handle valid (is associated with open file)

2) check length to if it is valid

3) figure out what device/sector/block data for the read is

4) get the block

5) copy the data from the xfer block to buffer

6) update the buffer length

return the number of read bytes

}

First functions …

• The first functions you should write should create a register structure and

extract a register structure:

LCloudRegisterFrame create_lcloud_registers(…?) {

???

}

??? extract_lcloud_registers(LCloudRegisterFrame resp, …) {

???

}

Hint: use the bit operations to build packed registers ….

Packing

• To pack the values (variables b0, b1 ….), you need to combine some set of

shift operations and bitwise (&)

B0 C0 C1 C2 D0 D1

4-bits 8-bits 8-bits 8-bits 16-bits 16-bits

B1

Most significant bit Least significant bit

Hint:

a = 0011

b = 0011

c = (b<<2) & a

Now : c = 1111

Doing an operation

• For each operation, say LC_POWER_ON

1. Pack the registers using your create_lcloud_registers function

2. Set the xfer parameter (NULL for power on)

3. Call the lcloud_io_bus and get the return registers

4. Unpack the registers using your extract_lcloud_registers function

5. Check for the return values in the registers for failures, etc.

Doing an operation

• Example from PDM’s implementation of the filesystem

‣ the variable names should tell you something about what is going one)

‣ This particular code contains an operation into WRITE into the device …

‣ buf is a 256 byte character array (see last lecture)

/* Do the write operation, check result */

frm = create_lcloud_registers(0, 0, LC_BLOCK_XFER, did, LC_XFER_WRITE, sec, blk );

if ( (frm == -1) || ((rfrm = lcloud_io_bus(frm, buf)) == -1) ||

(extract_lcloud_registers(rfrm, &b0, &b1, &c0, &c1, &c2, &d0, &d1)) ||

(b0 != 1) || (b1 != 1) || (c0 != LC_BLOCK_XFER) ) {

logMessage( LOG_ERROR_LEVEL, "LC failure writing blkc [%d/%d/%d].", did, sec, blk );

return( -1 );

}

What you are doing (visually) ….

• Initially you will start with empty devices, all blocks are free.

• Once you power things on and process the open, you will see writes

• For this example, we are ignoring reads but it should be clear how to do

reads once you understand how to do writes.

• On the first write (#1) you will pick a block (any block, it is up to you).

• For the sake of this example, the write is exactly one block in size.

• You pick sector 0, block 0 (for one strategy), and write the block to it …

WR #1

• On the second write (#2) you will pick a block (any block, it is up to you, but you can’t pick

0,0 because it already has file data)

• For the sake of this example, the write is exactly one half block in size.

• You pick sector 1, block 2 (for one strategy), and write the block to it … BUT you have to

remember you have only used the first half of that block …

• On the third write (#3) you start by filling up what is unused by the previous

write in the block 1,2

• This write is one block long, so you split it into TWO writes the first half to 1,2

and the second half to a new block s-1, 1 (again up to you)

WR #1 WR #2 WR #3 WR #4

• And so on … i.e., as you add to the file you just allocate more blocks.

• Reads are the same, only you don’t do allocation, you just figure out how to read

the bytes from the blocks in one or more reads from the device.

• The whole assignment revolves around piecing together the reads/writes from

blocks.

Questions asked:

• Q: In the lcseek function, I am still unable to understand the phrase in the

slides 'The function should set the current position into the file to loc, where

0 is the first byte in the file'. Is loc referring to 'off' in size_t off? If so, does

this mean that off has to be equal to something?

• A: off is the “offset from zero”, so it is setting the absolute location. So,

‣ lcseek(10) - sets the file position to the 10th byte

‣ Lcseek(1000) - sets the file position to the 1000th byte


版权所有:留学生编程辅导网 2020 All Rights Reserved 联系方式:QQ:99515681 微信:codinghelp 电子信箱:99515681@qq.com
免责声明:本站部分内容从网络整理而来,只供参考!如有版权问题可联系本站删除。 站长地图

python代写
微信客服:codinghelp