Articles
Scratchpad - Documenting Edify for Android Updater-Scripts based off of recovery source code
I'm going to be updating the syntax of each of these functions/commands in the edify scripting language used by Android to run updater-scripts. At this point, all I have done is extracted the edify commands and listed which file they are in, next I will be documenting the syntax of each command, and after that, we'll get some examples for reference up for everyone. Also, it appears that the version of the update-binary that you use affects the syntax that you are using. The syntax detailed here is for the latest update-binary per the source on kernel.orgThis is just a draft scratch-pad for my work in progress.
Virtually all of the commands in Edify are functions, and return data to the script when the function call is completed. You can use the returned value of the function to test for success or failure.
For example:
ifelse(mount("yaffs2", "MTD", "system", "/system") == "system", ui_print("Mounted!"), ui_print("Mount Failed!");
This command would attempt to mound the MTD partition named "system" to "/system".
If the mount succeeds, the script will display "Mounted!", otherwise it will display "Mount Failed!"
edify commands:
********************
| Functions from: platform/bootable/recovery.git/updater/install.c | |
| Function Name: | mount |
| Function Syntax: | mount(fs_type, partition_type, location, mount_point) |
| Parameter Details: |
fs_type = "yaffs2" | "ext4" partition_type="MTD" | "EMMC" location = partition | device mount_point = target folder to mount FS. |
| Description: |
Action: Mounts a filesystem in the defined mount point. Returns: The mount point. if successful, null if failed. |
| Example: | |
| Function Name: | is_mounted |
| Function Syntax: | is_mounted(mount_point) |
| Parameter Details: | mount_point = string, mount point to check if is mounted. |
| Description: |
Action: Checks if a filesystem is mounted. Returns: The mount point if it is mounted, otherwise, returns null. |
| Example: | |
| Function Name: | unmount |
| Function Syntax: | unmount(mount_point) |
| Parameter Details: | mount_point = string, mount point to unmount. |
| Description: |
Action: Unmounts the filesystem. Returns: The mount point that was dismounted if successful, otherwise it returns null. |
| Example: | |
| Function Name: | format |
| Function Syntax: | format(fs_type, partition_type, location) |
| Parameter Details: | fs_type = string,"yaffs2" | "ext4"
partition_type= string, "MTD" | "EMMC" location = string, partition | device |
| Description: | Formats a filesystem as specified. |
| Example: | |
| Function Name: | delete |
| Function Syntax: | delete(file1, file2, ..., fileN) |
| Parameter Details: | string, file to delete |
| Description: | Delete's a file. at least 1 file must be specified. Multiple files can be specified as multiple arguments. |
| Example: | |
| Function Name: | delete_recursive |
| Function Syntax: | delete_recursive(dir1, dir2,...,dirN) |
| Parameter Details: | string, directory to recursively delete. |
| Description: | Delete's a folder and all contents under that folder. At least 1 directory must be specified. Multiple directories can be specified as additional arguments. |
| Example: | |
| Function Name: | show_progress |
| Function Syntax: | show_progress(frac, sec) |
| Parameter Details: |
frac = fraction of progress completed sec = total seconds? |
| Description: | need to test. |
| Example: | |
| Function Name: | set_progress |
| Function Syntax: | set_prograss(frac) |
| Parameter Details: | frac=fraction of progress |
| Description: | I assume it updates progress bar with new progress, need to test. |
| Example: | |
| Function Name: | package_extract_dir |
| Function Syntax: | package_extract_dir(package_path, destination_path) |
| Parameter Details: |
package_path = string, directory in package to extract destination_path = string, target point to extract files to |
| Description: | Extract the all of the files in a directory in the package to the target specified. |
| Example: | |
| Function Name: | package_extract_file |
| Function Syntax: |
package_extract_file(package_path) or package_extract_file(package_path, destination_path) |
| Parameter Details: |
package_path = string, file in the package you want to extract destination_path, target folder to extract the file to. |
| Description: |
If a single argument is specified returns the contents of the file. Extract a single file from your update package to the target specified |
| Example: | |
| Function Name: | file_getprop |
| Function Syntax: | file_getprop(file, key) |
| Parameter Details: |
file = string, filename to check key = string, key in file to return the value of |
| Description: |
Get a property out of any file as log as the file format is "key"="value" where key is the name of the property stored in the file, and "value" i # = Comment lines Blank lines are OK key=value |
| Example: | |
| Function Name: | symlink |
| Function Syntax: | symlink(target, src1, src2, ..., srcN) |
| Parameter Details: |
target = string, the target of the symbolic link srcX = the symbolic link to create that points to the target |
| Description: |
Unlinks any existing symbolic links before creating the new symbolic links. |
| Example: | |
| Function Name: | set_perm |
| Function Syntax: | set_perm(uid, gid, mode, file1, file2, ..., fileN) |
| Parameter Details: |
uid = user id gid = group id mode = permission mode fileX = file to set permission on |
| Description: | Set permissions of a file or set of files specified. At least 1 file must be specified (the first four parameters are required) |
| Example: | |
| Function Name: | set_perm_recursive |
| Function Syntax: | set_perm_recursive(uid, gid, dirmode, filemode, dir1, dir2, ...dirN) |
| Parameter Details: |
uid = user id gid = group id dirmode = permission to set to directories contained within the specified directory filemode = permission to set to files contained within the specified directory dirX = directory to set permission on |
| Description: | Set permissions of a directory or set of directories and all files and folders within them. At least 1 directory must be specified (The first 5 parameters are required.) |
| Example: | |
| Function Name: | getprop |
| Function Syntax: | getprop(key) |
| Parameter Details: | key = string, the property you want the system to return |
| Description: | This function returns the value of the property specified. This is used to query platform information from the build.props file. |
| Example: | |
| Function Name: | write_raw_image |
| Function Syntax: | write_raw_image(file, partition) |
| Parameter Details: |
file - string, the source .img file to be read from partition - string, the destination partition to write the .img file to |
| Description: | This function writes an img file to a partition. |
| Example: | |
| Function Name: | apply_patch |
| Function Syntax: | apply_patch(srcfile, tgtfile, tgtsha1, tgtsize, sha1_1, patch_1, ..., sha1_x, patch1_x) |
| Parameter Details: |
srcfile - string, source file to be patched (file to read in) tgtfile - string, destination file to write the patched file to tgtsha1 - string, sha1 hash of the target file as it should hash out after the patches apply properly sha1_x - string, sha1 hash of the patch data that's to be written to the target file patch1_x- string, actual patch to apply to the target file |
| Description: | This function is used to apply patches to a file. I need to research the format of the patch string, and also, if my assumptions on what the parameters mean are correct. need to check source code for the "applypatch" function that is called from here/ |
| Example: | |
| Function Name: | apply_patch_check |
| Function Syntax: | apply_patch_check(file, sha1_1, ..., sha1_x) |
| Parameter Details: |
file - string, file to check sha1_x - hash to check for? |
| Description: | Either checks if a file has been properly patched, or checks if a file can be patched. Need to check the source code of the "applypatch_check" function that is called from here. |
| Example: | |
| Function Name: | apply_patch_space |
| Function Syntax: | apply_patch_space(bytes) |
| Parameter Details: | bytes = number of bytes to check for |
| Description: | Checks the cache to verify that there is enough space to write the patched files to it and returns something. Need to test this function to verifyre |
| Example: | |
| Function Name: | read_file |
| Function Syntax: | read_file(filename) |
| Parameter Details: | filename - string, the filename to read the contents of |
| Description: | This function returns the contents of a file. |
| Example: | |
| Function Name: | sha1_check |
| Function Syntax: |
sha1_check(data) or sha1_check(data, sha1_hex, ..., sha1_hexN) |
| Parameter Details: |
data - the contents of file to calculate the sha1 hash of - must be in the read_file format sha1_hexN - A particular sha1_hex string that you want the file data to match |
| Description: | If only data is specified, then the function returns the sha1_hex string of the data. The optional parameters are used if you want to verify that the file you are checking for is one of a list of hashes. It reutrns the hash it matches, or returns nothing if it doesn't match any of the mentioned hashses. |
| Example: | |
| Function Name: | ui_print |
| Function Syntax: | ui_print(msg1, ..., msgN) |
| Parameter Details: | msg - String, message to be outputted to the user during the patch process |
| Description: | This function prints/echo's a message to the console while the script is running. At least 1 parameter needs to be specified, you can specify additional msg parameters and they will be concatenated to the output. |
| Example: | |
| Function Name: | run_program |
| Function Syntax: | run_program(prog, arg1, .., argN) |
| Parameter Details: |
prog - string, program to execute argN - string, arguments for the program that is being executed |
| Description: | Executes a program with the arguments specified. Returns a string, I assume it is the buffer of the stdout of the program executed, need to test. |
| Example: | |
| Functions from: platform/bootable/recovery.git/edify/expr.c | |
| Function Name: | ifelse |
| Function Syntax: | ifelse(condition, truecondition, falsecondition) |
| Parameter Details: |
condition - an expression to evaluate truecondition - Edify script block to execute if true falsecodnition - Edify script block to execute if false |
| Description: | This is the if-then construct of the Edify scripting language. The truecondition or falsecondition arguments can be a single edify command or a script block. Script blocks can be formed by enclosing the parameter with parenthesis, and seperating the commands with semicolons. |
| Example: |
ifelse("true",(ui_print("Line 1");ui_print("Line 2");),ui_print("Won't See This)); since the condition is "true", Edify will evaluate the second parameter (which is underlined). Notice the open and close parenthesis turns that whole script block into one paremeter. The third parameter will not be evaluated. |
| Function Name: | abort |
| Function Syntax: | abort() |
| Parameter Details: | no paremeters |
| Description: | Aborts script execution. |
| Example: | |
| Function Name: | assert |
| Function Syntax: | assert(condition) |
| Parameter Details: | condition - boolean |
| Description: | If condition evaluates to false, stops script execution, otherwise continues processing. |
| Example: | |
| Function Name: | concat |
| Function Syntax: | |
| Parameter Details: | |
| Description: | |
| Example: | |
| Function Name: | is_substring |
| Function Syntax: | |
| Parameter Details: | |
| Description: | |
| Example: | |
| Function Name: | stdout |
| Function Syntax: | |
| Parameter Details: | |
| Description: | |
| Example: | |
| Function Name: | sleep |
| Function Syntax: | |
| Parameter Details: | |
| Description: | |
| Example: | |
| Function Name: | less_than_int |
| Function Syntax: | |
| Parameter Details: | |
| Description: | |
| Example: | |
| Function Name: | greater_than_int |
| Function Syntax: | |
| Parameter Details: | |
| Description: | |
| Example: | |
Last Updated on Thursday, 19 May 2011 21:57.
Calling 64bit scripts from a 32bit application
This is one of those weird tidbits of information that was extremely difficult to find, yet extremely helpful to have. 64bit Windows utilizes the "SYSWOW64" layer to create a 32bit operating environment for applications. So when an application references a DLL in c:\windows\system32 (which oddly enough contains 64bit binaries in it) it is redirected to c:\windows\syswow64 (which oddly enough has 32bit binaries in it). The same holds true for the "C:\Program Files" folder (64bit) and the "C:\Program Files (x86)" folder (32bit).
I utilize a network management product (Solarwinds Application Performance Monitor) that is a 32bit application that runs on Windows Server 2008 64bit server which can execute user created scripts to monitor virtually anything you could think of. I needed to execute a powershell script to monitor the mount status of my Exchange 2007 information stores.
The server had Exchange 2007 management tools installed on it, and Microsoft's installation routine wouldn't allow me to install a 32bit version of the Exchange Management tools on my 64bit version of Windows. Furthermore, the 64bit installation of Exchange Management tools doesn't install the 32bit powershell extensions to manage Exchange. And to add insult to injury, the Exchange 2007 version of the powershell cmdlets do not support being remote execution using WS-Management.
Now this doesn't sound to bad, write a 64bit script, and call the 64bit version of powershell from a 32bit process. Well that can be a doosey, without this following tidbit of information:
If you are running within a 32bit application space, Microsoft has left a small crack open to allow you to execute 64bit code through the "sysnative" folder. Now, this isn't a normal folder, but if you access "C:\Windows\Sysnative" from a 32bit application it places you into the real "System32" folder (not the System32 folder that really points to SYSWOW64).
So in the end, I wrote a simple 32bit script, that in turn executed a 64bit script by calling:
c:\windows\sysnative\windowspowershell\v1.0\powershell.exe -file
Drop me a note if this tidbit of knowledge was useful!
Cisco UCS - Memory Architecture & Catalina
NUMA + Catalina = WIN!
In order to fully appreciate the memory architecture present in the Cisco UCS blade servers, we must first discuss the inherent memory architecture of the Nehalem Xeon processors. Prior to the release of Nehalem, all other x86 and x64 processors from Intel where based on a uniform memory access (UMA) architecture. AMD had introduced a non-uniform memory access (NUMA) architecture with their Opteron platform, which has proven to be a very effective memory architecture. So effective, that Intel decided to also implement this architecture.
Last Updated on Sunday, 30 January 2011 17:44.
Cisco UCS - A SynfulGeek view:
Cisco Servers, whatevs... Big whoop.
What is the hype around Cisco's entry to the server market, all about? In my opinon, it's actually a huge game changer. Just as virtualization changed how we look at servers, so to does UCS change how we look at compute resources.
The UCS platform is Cisco's first jump into a general server platform. In order to succeed in this environment, Cisco had to create a platform unlike others in the market, and had to leverage their unique networking abilities. What does a networking company know about server hardware? That's a fair question, let's explore this a little bit.
Last Updated on Sunday, 30 January 2011 17:45.
EMC Celerra VSA - Great tool, now let's break the shackles
Set this virtual appliance free!
I've been playing with the Celerra VSA in our lab environment in order to have a platform to test Celerra CIFS/NFS/iSCSI features. After closely following Chad's great posts and videos and using the OVF template on the Virtual Geek blog, I became quickly enamoured with the idea of using this great tool on my Cisco UCS based vSphere cluster. (Chad's excellent articles, video tutorials, and OVF template are available on his site, here)
The lab gear where I work is quite extensive, and having four Cisco UCS blades with dual Nehalem processors each, backed by an EMC CLARiiON array, connected over 10gbps switch Fabric, I was hoping for some rocking performance. Unfortunately, I was a little remiss to see this virtual appliance using the "Flexible" NIC, and the standard LSI Logic SCSI adapters, which don't perform as well as their Virtual Hardware 7 counterparts, the VMXNET3 adapter, and the PVSCSI controller.
I say it's time to break the shackles on this virtual appliance, and get a VMXNET3 / PVSCSI based version of this tool. So far in my limitted testing over a period of one day, I've been able to get PVSCSI to work, and VMXNET3 to work individually, but there are a few kinks I need to work out.
Last Updated on Sunday, 30 January 2011 17:46.


