Message ID | 1427434572-17552-2-git-send-email-lma@suse.com |
---|---|
State | New |
Headers | show |
On Fri, 27 Mar 2015 13:36:11 +0800 Lin Ma <lma@suse.com> wrote: > If backends implement the can_be_deleted and it returns false, > Then the qmp_object_del won't delete the given backends. > > Signed-off-by: Lin Ma <lma@suse.com> > --- > include/qom/object_interfaces.h | 14 ++++++++++++++ > qmp.c | 5 +++++ > qom/object_interfaces.c | 15 +++++++++++++++ > 3 files changed, 34 insertions(+) > > diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h > index b792283..012b653 100644 > --- a/include/qom/object_interfaces.h > +++ b/include/qom/object_interfaces.h > @@ -25,6 +25,8 @@ typedef struct UserCreatable { > * UserCreatableClass: > * @parent_class: the base class > * @complete: callback to be called after @obj's properties are set. > + * @can_be_deleted: callback to be called before an object is removed > + * to check if @obj can be removed safely. > * > * Interface is designed to work with -object/object-add/object_add > * commands. > @@ -47,6 +49,7 @@ typedef struct UserCreatableClass { > > /* <public> */ > void (*complete)(UserCreatable *uc, Error **errp); > + bool (*can_be_deleted)(UserCreatable *uc, Error **errp); > } UserCreatableClass; > > /** > @@ -59,4 +62,15 @@ typedef struct UserCreatableClass { > * nothing. > */ > void user_creatable_complete(Object *obj, Error **errp); > + > +/** > + * user_creatable_can_be_deleted: > + * @obj: the object whose can_be_deleted() method is called if defined > + * @errp: if an error occurs, a pointer to an area to store the error > + * > + * Wrapper to call can_be_deleted() method if one of types it's inherited > + * from implements USER_CREATABLE interface, otherwise the call does > + * nothing. > + */ > +bool user_creatable_can_be_deleted(Object *obj, Error **errp); > #endif > diff --git a/qmp.c b/qmp.c > index c479e77..dc61da1 100644 > --- a/qmp.c > +++ b/qmp.c > @@ -711,6 +711,11 @@ void qmp_object_del(const char *id, Error **errp) > error_setg(errp, "object id not found"); > return; > } > + > + if (!user_creatable_can_be_deleted(obj, errp)) { > + error_setg(errp, "%s is in used, can not be deleted", id); ^^^ is in use || is used > + return; > + } > object_unparent(obj); > } > > diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c > index 6360818..25ae6ca 100644 > --- a/qom/object_interfaces.c > +++ b/qom/object_interfaces.c > @@ -18,6 +18,21 @@ void user_creatable_complete(Object *obj, Error **errp) > } > } > > +bool user_creatable_can_be_deleted(Object *obj, Error **errp) > +{ > + > + UserCreatableClass *ucc; > + UserCreatable *uc = > + (UserCreatable *)object_dynamic_cast(obj, TYPE_USER_CREATABLE); direc cast is wron, pls use type specific caster with QOM objects in this case you can even drop dynamic cast since /objects holds only TYPE_USER_CREATABLE objects and just do UserCreatable *uc = USER_CREATABLE(obj) you don't check for null pointer anyway > + > + ucc = USER_CREATABLE_GET_CLASS(uc); > + if (ucc->can_be_deleted) { > + return ucc->can_be_deleted(uc, errp); > + } else { > + return true; > + } > +} > + > static void register_types(void) > { > static const TypeInfo uc_interface_info = {
在 2015年03月27日 22:35, Igor Mammedov 写道: > On Fri, 27 Mar 2015 13:36:11 +0800 > Lin Ma <lma@suse.com> wrote: > >> If backends implement the can_be_deleted and it returns false, >> Then the qmp_object_del won't delete the given backends. >> >> Signed-off-by: Lin Ma <lma@suse.com> >> --- >> include/qom/object_interfaces.h | 14 ++++++++++++++ >> qmp.c | 5 +++++ >> qom/object_interfaces.c | 15 +++++++++++++++ >> 3 files changed, 34 insertions(+) >> >> diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h >> index b792283..012b653 100644 >> --- a/include/qom/object_interfaces.h >> +++ b/include/qom/object_interfaces.h >> @@ -25,6 +25,8 @@ typedef struct UserCreatable { >> * UserCreatableClass: >> * @parent_class: the base class >> * @complete: callback to be called after @obj's properties are set. >> + * @can_be_deleted: callback to be called before an object is removed >> + * to check if @obj can be removed safely. >> * >> * Interface is designed to work with -object/object-add/object_add >> * commands. >> @@ -47,6 +49,7 @@ typedef struct UserCreatableClass { >> >> /* <public> */ >> void (*complete)(UserCreatable *uc, Error **errp); >> + bool (*can_be_deleted)(UserCreatable *uc, Error **errp); >> } UserCreatableClass; >> >> /** >> @@ -59,4 +62,15 @@ typedef struct UserCreatableClass { >> * nothing. >> */ >> void user_creatable_complete(Object *obj, Error **errp); >> + >> +/** >> + * user_creatable_can_be_deleted: >> + * @obj: the object whose can_be_deleted() method is called if defined >> + * @errp: if an error occurs, a pointer to an area to store the error >> + * >> + * Wrapper to call can_be_deleted() method if one of types it's inherited >> + * from implements USER_CREATABLE interface, otherwise the call does >> + * nothing. >> + */ >> +bool user_creatable_can_be_deleted(Object *obj, Error **errp); >> #endif >> diff --git a/qmp.c b/qmp.c >> index c479e77..dc61da1 100644 >> --- a/qmp.c >> +++ b/qmp.c >> @@ -711,6 +711,11 @@ void qmp_object_del(const char *id, Error **errp) >> error_setg(errp, "object id not found"); >> return; >> } >> + >> + if (!user_creatable_can_be_deleted(obj, errp)) { >> + error_setg(errp, "%s is in used, can not be deleted", id); > ^^^ is in use || is used Thanks for catching this. I'll modify it to 'in use' >> + return; >> + } >> object_unparent(obj); >> } >> >> diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c >> index 6360818..25ae6ca 100644 >> --- a/qom/object_interfaces.c >> +++ b/qom/object_interfaces.c >> @@ -18,6 +18,21 @@ void user_creatable_complete(Object *obj, Error **errp) >> } >> } >> >> +bool user_creatable_can_be_deleted(Object *obj, Error **errp) >> +{ >> + >> + UserCreatableClass *ucc; >> + UserCreatable *uc = >> + (UserCreatable *)object_dynamic_cast(obj, TYPE_USER_CREATABLE); > direc cast is wron, pls use type specific caster with QOM objects > in this case you can even drop dynamic cast since /objects holds > only TYPE_USER_CREATABLE objects and just do > UserCreatable *uc = USER_CREATABLE(obj) will do. > you don't check for null pointer anyway May I have your suggestion about checking the null pointer? says: if (!uc) { return false; // is this make sense? } > >> + >> + ucc = USER_CREATABLE_GET_CLASS(uc); >> + if (ucc->can_be_deleted) { >> + return ucc->can_be_deleted(uc, errp); >> + } else { >> + return true; >> + } >> +} >> + >> static void register_types(void) >> { >> static const TypeInfo uc_interface_info = { >
diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h index b792283..012b653 100644 --- a/include/qom/object_interfaces.h +++ b/include/qom/object_interfaces.h @@ -25,6 +25,8 @@ typedef struct UserCreatable { * UserCreatableClass: * @parent_class: the base class * @complete: callback to be called after @obj's properties are set. + * @can_be_deleted: callback to be called before an object is removed + * to check if @obj can be removed safely. * * Interface is designed to work with -object/object-add/object_add * commands. @@ -47,6 +49,7 @@ typedef struct UserCreatableClass { /* <public> */ void (*complete)(UserCreatable *uc, Error **errp); + bool (*can_be_deleted)(UserCreatable *uc, Error **errp); } UserCreatableClass; /** @@ -59,4 +62,15 @@ typedef struct UserCreatableClass { * nothing. */ void user_creatable_complete(Object *obj, Error **errp); + +/** + * user_creatable_can_be_deleted: + * @obj: the object whose can_be_deleted() method is called if defined + * @errp: if an error occurs, a pointer to an area to store the error + * + * Wrapper to call can_be_deleted() method if one of types it's inherited + * from implements USER_CREATABLE interface, otherwise the call does + * nothing. + */ +bool user_creatable_can_be_deleted(Object *obj, Error **errp); #endif diff --git a/qmp.c b/qmp.c index c479e77..dc61da1 100644 --- a/qmp.c +++ b/qmp.c @@ -711,6 +711,11 @@ void qmp_object_del(const char *id, Error **errp) error_setg(errp, "object id not found"); return; } + + if (!user_creatable_can_be_deleted(obj, errp)) { + error_setg(errp, "%s is in used, can not be deleted", id); + return; + } object_unparent(obj); } diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c index 6360818..25ae6ca 100644 --- a/qom/object_interfaces.c +++ b/qom/object_interfaces.c @@ -18,6 +18,21 @@ void user_creatable_complete(Object *obj, Error **errp) } } +bool user_creatable_can_be_deleted(Object *obj, Error **errp) +{ + + UserCreatableClass *ucc; + UserCreatable *uc = + (UserCreatable *)object_dynamic_cast(obj, TYPE_USER_CREATABLE); + + ucc = USER_CREATABLE_GET_CLASS(uc); + if (ucc->can_be_deleted) { + return ucc->can_be_deleted(uc, errp); + } else { + return true; + } +} + static void register_types(void) { static const TypeInfo uc_interface_info = {
If backends implement the can_be_deleted and it returns false, Then the qmp_object_del won't delete the given backends. Signed-off-by: Lin Ma <lma@suse.com> --- include/qom/object_interfaces.h | 14 ++++++++++++++ qmp.c | 5 +++++ qom/object_interfaces.c | 15 +++++++++++++++ 3 files changed, 34 insertions(+)