C-Python and Endianness
Ganesh Pal
ganesh1pal at gmail.com
Sun Mar 26 02:47:40 EDT 2017
Hello Team ,
I want to write the hexadecimal string that is passed from python as it
is on disk in C , my problem is that the values are getting stored in
little endian and
the values are swapped it has been quite a pain for me to fix this , any
suggestion on how to fix this (I am on Python 2.7 and Linux).
Example :
if I pass a PyObject i.e “abcdef12345123” it should be written on disk
at the given offset as it i.e. “abcdef12345123”
CLI:
#inject_failures.py --optype=add --fixcrc=1 --object=baddr
--baddr=2,3,773463552:512 --offset=16 --mirror=1
--op_value='abcdef12345123' --size=8
(op_value is the new variable that is passed as string )
static PyObject *
py_corrupt_disk_object(PyObject *self, PyObject *args)
{
int size, optype, fixcrc;
long offset;
PyObject *baddr;
char *op_value = NULL;
if (!PyArg_ParseTuple(args,"Oliisi", &baddr, &offset, &size,
&optype,
&op_value,&fixcrc))
Py_RETURN_NONE;
d_locn_t locn = {};
locn.idx.devid = ((struct py_ifs_baddr*)baddr)->baddr.devid;
locn.idx.drive = ((struct py_ifs_baddr*)baddr)->baddr.drive;
locn.idx.subidx = ((struct py_ifs_baddr*)baddr)->baddr._subblk;
locn.idx.index = ((struct py_ifs_baddr*)baddr)->baddr._block;
d_print("Printing args in py_corrupt_disk_object: \n");
d_print("offset %lu \n",offset);
d_print("fixcrc %d \n",fixcrc);
d_print("size %d \n",size);
d_print("optype %d \n",optype);
d_print("op_value %s \n",op_value);
d_cpr_write(&locn, offset, size, optype, op_value, fixcrc);
Py_RETURN_NONE;
}
PyObject*
d_cpr_write(d_locn_t *locn, int offset, int size, int optype, char
*op_value, int fixcrc)
{
cpr_obj* obj = NULL;
struct po_typeinfo *tinfo = NULL;
int obj_size = 0;
d_print("The Values inside d_cpr_write():\n");
d_print("offset %d \n",offset);
d_print("fixcrc %d \n",fixcrc);
d_print("size %d \n",size);
d_print("optype %d \n",optype);
d_print("op_value %s \n",op_value);
if (locn->idx.subidx & BADDR_SIZE_512) {
obj_size = BUFFER_512;
tinfo = find_object('i');
if (locn_iaddr_to_linsnap(locn) != d_OK) {
d_log(d_ERR, "lin snap conversion failed\n");
Py_RETURN_NONE;
}
locn->flags |= DLFLAG_HASXIADDRHINT;
locn->xiaddrhint = d_index_to_baddr(locn->idx);
} else {
obj_size = BUFFER_8192;
tinfo = find_object('b');
}
if (tinfo == NULL) {
d_log(d_ERR, "Only Object i or b supported\n");
Py_RETURN_NONE;
}
obj = alloc_objarg();
// create cpr object
obj->tinfo = tinfo;
obj->locn = *locn;
unsigned char *buff = NULL;
if (!(buff = alloca(obj_size))) {
d_log(d_ERR, "buffer allocation failed\n");
Py_RETURN_NONE;
}
int index, xfered, bit_offset;
if ((xfered = (*obj->tinfo->read)(&obj->locn, buff, obj_size)) < 0)
{
d_log(d_ERR, "read failed %d\n", xfered);
Py_RETURN_NONE;
}
if (obj->tinfo->insane != NULL) {
if ((*obj->tinfo->insane)(&obj->locn, buff, obj_size, 0) <
0) {
d_log(d_ERR, "%c object sanity check failed\n",
obj->tinfo->type);
Py_RETURN_NONE;
}
}
d_print("Entering optype\n");
if (optype == 2) { //overwrite
unsigned long opval = strtol(op_value, NULL, 16);
d_print("after rev =%ld ", opval);
memcpy(&buff[offset], &opval, sizeof(opval));
}//End of overwrite
if (fixcrc)
obj->locn.flags |= DLFLAG_WRITE_CRC;
if (!obj->tinfo->write) {
d_log(d_ERR, "no write function supported\n");
Py_RETURN_NONE;
}
if ((xfered = (*obj->tinfo->write)(&obj->locn, buff, obj_size)) <
0) {
d_log(d_ERR, "write failed %d\n", xfered);
Py_RETURN_NONE;
}
Py_RETURN_NONE;
}
Output:
pipe1-2# inject_failures.py --optype=add --fixcrc=1 --object=baddr
--baddr=2,3,773463552:512 --offset=16 --mirror=1
--op_value='abcdef12345123' --size=8
> /usr/local_qa/bin/isi_corrupt.py(848)main()
-> if 'add' in options.optype and options.op_value is None:
(Pdb) c
c
> /usr/local_qa/bin/ inject_failures.py (185)corrupt_diskobject()
-> logging.info("Corrupting disk object %s at %s", obj_type, disk_object)
(Pdb) c
Printing args in py_corrupt_disk_object:
offset 16
fixcrc 1
size 8
optype 2
op_value abcdef12345123
The Values inside d_cpr_write():
offset 16
fixcrc 1
size 8
optype 2
op_value abcdef12345123
Entering optype
after rev =48358647703818531
If I do an hexdump on the file I can see that data is not written correctly
Before:
00000010 e0 01 04 00 01 00 00 00 02 00 00 00 00 00 00 00
|................|
After :
00000010 23 51 34 12 ef cd ab 00 02 00 00 00 00 00 00 00
|#Q4.............| ==>
1. I am on a little endian machine and is there a way that I can stop
this translation and write the values as it ( looks like we are swapping
the bytes )?
2. The value passed i.e op_value is a string and its getting printed
correctly at C layer,my value is always a hex decimal string of size 14 or
7 bytes.
3. Is there something that I can take care in python layer to avoid this
swap ?
Regards,
Ganesh
More information about the Python-list
mailing list