Example #1
0
static void
Per_dealloc(cPersistentObject *self)
{
    if (self->state >= 0)
    {
        /* If the cache has been cleared, then a non-ghost object
            isn't in the ring any longer.
        */
        if (self->ring.r_next != NULL)
        {
            /* if we're ghostifying an object, we better have some non-ghosts */
            assert(self->cache->non_ghost_count > 0);
            self->cache->non_ghost_count--;
            self->cache->total_estimated_size -=
                _estimated_size_in_bytes(self->estimated_size);
            ring_del(&self->ring);
        }
    }

    if (self->cache)
        cPersistenceCAPI->percachedel(self->cache, self->oid);
    Py_XDECREF(self->cache);
    Py_XDECREF(self->jar);
    Py_XDECREF(self->oid);
    Py_TYPE(self)->tp_free(self);
}
Example #2
0
static void
ghostify(cPersistentObject *self)
{
    PyObject **dictptr;

    /* are we already a ghost? */
    if (self->state == cPersistent_GHOST_STATE)
        return;

    /* Is it ever possible to not have a cache? */
    if (self->cache == NULL)
    {
        self->state = cPersistent_GHOST_STATE;
        return;
    }

    if (self->ring.r_next == NULL)
    {
        /* There's no way to raise an error in this routine. */
#ifdef Py_DEBUG
        fatal_1350(self, "ghostify", "claims to be in a cache but isn't");
#else
        return;
#endif
    }

    /* If we're ghostifying an object, we better have some non-ghosts. */
    assert(self->cache->non_ghost_count > 0);
    self->cache->non_ghost_count--;
    self->cache->total_estimated_size -=
        _estimated_size_in_bytes(self->estimated_size);
    ring_del(&self->ring);
    self->state = cPersistent_GHOST_STATE;
    dictptr = _PyObject_GetDictPtr((PyObject *)self);
    if (dictptr && *dictptr)
    {
        Py_DECREF(*dictptr);
        *dictptr = NULL;
    }

    /* We remove the reference to the just ghosted object that the ring
    * holds.  Note that the dictionary of oids->objects has an uncounted
    * reference, so if the ring's reference was the only one, this frees
    * the ghost object.  Note further that the object's dealloc knows to
    * inform the dictionary that it is going away.
    */
    Py_DECREF(self);
}
Example #3
0
static void
ghostify(cPersistentObject *self)
{
    PyObject **dictptr, *slotnames;

    /* are we already a ghost? */
    if (self->state == cPersistent_GHOST_STATE)
        return;

    /* Is it ever possible to not have a cache? */
    if (self->cache == NULL) 
    {
        self->state = cPersistent_GHOST_STATE;
        return;
    }

    if (self->ring.r_next == NULL)
    {
        /* There's no way to raise an error in this routine. */
#ifdef Py_DEBUG
        fatal_1350(self, "ghostify", "claims to be in a cache but isn't");
#else
        return;
#endif
    }

    /* If we're ghostifying an object, we better have some non-ghosts. */
    assert(self->cache->non_ghost_count > 0);
    self->cache->non_ghost_count--;
    self->cache->total_estimated_size -= 
        _estimated_size_in_bytes(self->estimated_size);
    ring_del(&self->ring);
    self->state = cPersistent_GHOST_STATE;

    /* clear __dict__ */
    dictptr = _PyObject_GetDictPtr((PyObject *)self);
    if (dictptr && *dictptr)
    {
        Py_DECREF(*dictptr);
        *dictptr = NULL;
    }

    /* clear all slots besides _p_*
     * ( for backward-compatibility reason we do this only if class does not
     *   override __new__ ) */
    if (Py_TYPE(self)->tp_new == Pertype.tp_new)
    {
        slotnames = pickle_slotnames(Py_TYPE(self));
        if (slotnames && slotnames != Py_None)
        {
            int i;

            for (i = 0; i < PyList_GET_SIZE(slotnames); i++)
            {
                PyObject *name;
                char *cname;
                int is_special;

                name = PyList_GET_ITEM(slotnames, i);
#ifdef PY3K
                if (PyUnicode_Check(name))
                {
                    PyObject *converted = convert_name(name);
                    cname = PyBytes_AS_STRING(converted);
#else
                if (PyBytes_Check(name))
                {
                    cname = PyBytes_AS_STRING(name);
#endif
                    is_special = !strncmp(cname, "_p_", 3);
#ifdef PY3K
                    Py_DECREF(converted);
#endif
                    if (is_special) /* skip persistent */
                    {
                        continue;
                    }
                }

                /* NOTE: this skips our delattr hook */
                if (PyObject_GenericSetAttr((PyObject *)self, name, NULL) < 0)
                    /* delattr of non-set slot will raise AttributeError - we
                     * simply ignore. */
                    PyErr_Clear();
            }
        }
        Py_XDECREF(slotnames);
    }

    /* We remove the reference to the just ghosted object that the ring
    * holds.  Note that the dictionary of oids->objects has an uncounted
    * reference, so if the ring's reference was the only one, this frees
    * the ghost object.  Note further that the object's dealloc knows to
    * inform the dictionary that it is going away.
    */
    Py_DECREF(self);
}

static int
changed(cPersistentObject *self)
{
    if ((self->state == cPersistent_UPTODATE_STATE ||
        self->state == cPersistent_STICKY_STATE)
        && self->jar)
    {
        PyObject *meth, *arg, *result;
        static PyObject *s_register;

        if (s_register == NULL)
            s_register = INTERN("register");
        meth = PyObject_GetAttr((PyObject *)self->jar, s_register);
        if (meth == NULL)
            return -1;
        arg = PyTuple_New(1);
        if (arg == NULL) 
        {
            Py_DECREF(meth);
            return -1;
        }
        Py_INCREF(self);
        PyTuple_SET_ITEM(arg, 0, (PyObject *)self);
        result = PyEval_CallObject(meth, arg);
        Py_DECREF(arg);
        Py_DECREF(meth);
        if (result == NULL)
            return -1;
        Py_DECREF(result);

        self->state = cPersistent_CHANGED_STATE;
    }

    return 0;
}

static int
readCurrent(cPersistentObject *self)
{
    if ((self->state == cPersistent_UPTODATE_STATE ||
        self->state == cPersistent_STICKY_STATE)
        && self->jar && self->oid)
    {
        static PyObject *s_readCurrent=NULL;
        PyObject *r;

        if (s_readCurrent == NULL)
            s_readCurrent = INTERN("readCurrent");

        r = PyObject_CallMethodObjArgs(self->jar, s_readCurrent, self, NULL);
        if (r == NULL)
            return -1;

        Py_DECREF(r);
    }

    return 0;
}

static PyObject *
Per__p_deactivate(cPersistentObject *self)
{
    if (self->state == cPersistent_UPTODATE_STATE && self->jar)
    {
        PyObject **dictptr = _PyObject_GetDictPtr((PyObject *)self);
        if (dictptr && *dictptr)
        {
            Py_DECREF(*dictptr);
            *dictptr = NULL;
        }
        /* Note that we need to set to ghost state unless we are
            called directly. Methods that override this need to
            do the same! */
        ghostify(self);
        if (PyErr_Occurred())
            return NULL;
    }

    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *
Per__p_activate(cPersistentObject *self)
{
    if (unghostify(self) < 0)
        return NULL;

    Py_INCREF(Py_None);
    return Py_None;
}

static int Per_set_changed(cPersistentObject *self, PyObject *v);

static PyObject *
Per__p_invalidate(cPersistentObject *self)
{
    signed char old_state = self->state;

    if (old_state != cPersistent_GHOST_STATE)
    {
        if (Per_set_changed(self, NULL) < 0)
            return NULL;
        ghostify(self);
        if (PyErr_Occurred())
            return NULL;
    }
    Py_INCREF(Py_None);
    return Py_None;
}
Example #4
0
// recover files from a "double quotes" listfile
void recover_list(char *des_dir, char *input_file,__u32 t_after, __u32 t_before, int flag){
	FILE  *f;
	char *lineptr = NULL ;
	char *filename = NULL ;
	char *p1 , *p2;
	size_t maxlen;
	size_t got;
	ext2_ino_t inode_nr;
	struct ring_buf *i_list;
	struct ext2_inode* r_inode;
	r_item *item = NULL;	
	
	f = fopen(input_file,"r");
	if (f) {
		rewind(f);
		maxlen = 512;
		lineptr = malloc(maxlen);
		filename = malloc(maxlen);
		if ((!lineptr) || (!filename))
			goto errout;
		while (! (feof(f))){
			got = getline (&lineptr, &maxlen, f);
		 	if (got != -1){
				p1 = strchr(lineptr,'"');
				p2 = strrchr(lineptr,'"');
				if ((p1) && (p2) && (p1 != p2)){
					p1++;
					*p2 = 0;
					strcpy(filename,p1);
					if (*filename == 0)
						continue;
					inode_nr = local_namei(NULL,filename,t_after,t_before,DELETED_OPT);
					if(! inode_nr){
#ifdef DEBUG
						printf("Filename %s not found\n",filename);
#endif
						continue;
					}
					i_list = get_j_inode_list(current_fs->super, inode_nr);
					item = get_undel_inode(i_list,t_after,t_before);

					if (item) {
						r_inode = (struct ext2_inode*)item->inode;
						if (! LINUX_S_ISDIR(r_inode->i_mode) ) 
							recover_file(des_dir,"", filename, r_inode, inode_nr ,flag);
						}
#ifdef DEBUG
						else
							printf("no Inode found for %s\n",filename);
#endif
					if (i_list) ring_del(i_list);
				}
#ifdef DEBUG
				else
					printf("Filename not found in : \"%s\"",lineptr);
#endif	
			}
		}

	}

errout:
	if (f) fclose(f);
	if (lineptr)
		free(lineptr);
	if (filename)
		free(filename); 
return ;
}
Example #5
0
// search inode by use imap (step1: flag 1 = only directory ; step2: flag 0 = only file)
static void search_imap_inode(char* des_dir, __u32 t_after, __u32 t_before, int flag)
{
struct ext2_group_desc 			*gdp;
struct 	ext2_inode_large 		*inode;
//struct dir_list_head_t 			*dir = NULL;
struct ring_buf* 			i_list = NULL;
r_item*					item = NULL;
int  					zero_flag, retval, load, x ,i ;
char 					*pathname = NULL;
char					*i_pathname = NULL;
char 					*buf= NULL;
unsigned char				*tmp_buf = NULL;
__u32 					blocksize, inodesize, inode_max, inode_per_group, block_count;
__u32 					inode_per_block , inode_block_group, group;
blk_t 					block_nr;
__u32   				c_time, d_time, mode;
ext2_ino_t 				first_block_inode_nr , inode_nr;


pathname = malloc(26);
blocksize = current_fs->blocksize;
inodesize = current_fs->super->s_inode_size;
inode_max = current_fs->super->s_inodes_count;
inode_per_group = current_fs->super->s_inodes_per_group;
buf = malloc(blocksize);
if (! (flag & 0x01) ){
	tmp_buf = malloc (12 * blocksize);
	if (!tmp_buf)
		goto errout;
	cookie = magic_open(MAGIC_MIME | MAGIC_NO_CHECK_COMPRESS | MAGIC_NO_CHECK_ELF | MAGIC_CONTINUE);
	if ((! cookie) ||  magic_load(cookie, NULL)){
		fprintf(stderr,"ERROR: can't find libmagic\n");
		goto errout;
	}
}

inode_per_block = blocksize / inodesize;
inode_block_group = inode_per_group / inode_per_block;

for (group = 0 ; group < current_fs->group_desc_count ; group++){
#ifdef EXT2_FLAG_64BITS
	gdp = ext2fs_group_desc(current_fs, current_fs->group_desc, group);
#else
	gdp = &current_fs->group_desc[group];
#endif
	zero_flag = 0;

	if (!(flag & 0x02)){ //skip this in disaster mode
		// NEXT GROUP IF INODE NOT INIT
		if (gdp->bg_flags & (EXT2_BG_INODE_UNINIT)) continue;
	
		// SET ZERO-FLAG IF FREE INODES == INODE/GROUP for fast ext3 
		if (gdp->bg_free_inodes_count == inode_per_group) zero_flag = 1;
	}

//FIXME for struct ext4_group_desc 48/64BIT	
	for (block_nr = gdp->bg_inode_table , block_count = 0 ;
			 block_nr < (gdp->bg_inode_table + inode_block_group); block_nr++, block_count++) {
		
		if (!(flag & 0x02)){ //skip this in disaster mode
			// break if the first block only zero inode
			if ((block_count ==1) && (zero_flag == (inode_per_block + 1))) break;
		}

//FIXME  inode_max ????	
		first_block_inode_nr = (group * inode_per_group) + (block_count * inode_per_block) + 1;
		load = 0;
		for (i = 0; i<inode_per_block;i++){
			if ( ! ext2fs_test_block_bitmap(imap,first_block_inode_nr + i)){
				load++;
				break;
			}
		}

		if (load){		 
			retval = read_block ( current_fs , &block_nr , buf);
			if (retval) return;

			for (inode_nr = first_block_inode_nr ,x = 0; x < inode_per_block ; inode_nr++ , x++){

				if ( ! ext2fs_test_block_bitmap(imap,inode_nr)){
	
					inode = (struct ext2_inode_large*) (buf + (x*inodesize));
					c_time = ext2fs_le32_to_cpu(inode->i_ctime);
					mode = ext2fs_le32_to_cpu(inode->i_mode);
					if ( ! ( flag & 0x02)) { 
						//no check this inode in disaster mode
 						if ((! c_time ) && (!(inode->i_mode & LINUX_S_IFMT)) ) {
							if(zero_flag) zero_flag++ ;
						continue;
						}
	
						d_time = ext2fs_le32_to_cpu(inode->i_dtime);
						if ( (! d_time) || d_time <= t_after){
							ext2fs_mark_generic_bitmap(imap,inode_nr);
						continue;
						}
					}
// 1. magical step 
					if (LINUX_S_ISDIR(mode) && ( flag & 0x01) && (pathname)){ 
						sprintf(pathname,"<%lu>",(long unsigned int)inode_nr);

	
						struct dir_list_head_t * dir = NULL;
						if (flag & 0x02){
							//disaster mode 
							//only search for undeleted entry 
							dir = get_dir3(NULL,0, inode_nr , "MAGIC-1",pathname, t_after,t_before, 0);
							if (dir) {
								lookup_local(des_dir, dir,t_after,t_before, RECOV_ALL | LOST_DIR_SEARCH );
								clear_dir_list(dir);
							}
						}
						else{   //search for all 
							dir = get_dir3(NULL,0, inode_nr , "MAGIC-1",pathname, t_after,t_before, DELETED_OPT);
							if (dir) {
								lookup_local(des_dir,dir,t_after,t_before,DELETED_OPT|RECOV_ALL|LOST_DIR_SEARCH);
								clear_dir_list(dir);
							}
						}

						
					}

// 2. magical step
					if (! (flag & 0x01) ){
						i_list = get_j_inode_list(current_fs->super, inode_nr);
						item = get_undel_inode(i_list,t_after,t_before);
						ext2fs_mark_generic_bitmap(imap,inode_nr);

						if (item) {
							if (! LINUX_S_ISDIR(item->inode->i_mode) ) {
								i_pathname = identify_filename(i_pathname, tmp_buf,
										(struct ext2_inode*)item->inode, inode_nr);
								sprintf(pathname,"<%lu>",(long unsigned int)inode_nr);
								recover_file(des_dir,"MAGIC-2", ((i_pathname)?i_pathname : pathname),
									     (struct ext2_inode*)item->inode, inode_nr, 0);
								if(i_pathname){
									free(i_pathname);
									i_pathname = NULL;
								}
							}
						}
						if (i_list) ring_del(i_list);
					}	
				}
			}
		}
	}
}
errout:
	if (pathname)
		 free(pathname);

	if(buf) {
		free(buf);
		buf = NULL;
	}

	if (tmp_buf){
		free(tmp_buf);
		tmp_buf = NULL;
	}
	if (cookie){
		magic_close(cookie);
		cookie = 0;
	}
return;
}