)]}'
{"doc/source/devref/ganesha.rst":[{"author":{"_account_id":6491,"name":"xing-yang","email":"xingyang105@gmail.com","username":"xing-yang"},"change_message_id":"ade7922e7683d8209dc21beb648c9ecd5c1c4663","unresolved":false,"context_lines":[{"line_number":129,"context_line":"method which returns the FSAL subblock (in Python represented as"},{"line_number":130,"context_line":"a dict with string keys and values). It has one mandatory key,"},{"line_number":131,"context_line":"``Name``, to which the value should be the name of the FSAL"},{"line_number":132,"context_line":"(eg.: ``{\"Name\": \"CEPH\"}``). Further content of it is"},{"line_number":133,"context_line":"optional and FSAL specific."},{"line_number":134,"context_line":""},{"line_number":135,"context_line":"Customizing Ganesha exports"}],"source_content_type":"text/x-rst","patch_set":6,"id":"7f231b9d_e23ba4ce","line":132,"range":{"start_line":132,"start_character":18,"end_line":132,"end_character":22},"updated":"2017-06-12 16:03:10.000000000","message":"Currently only GlusterFS driver uses GaneshaNASHelper. Is the plan to deprecate the GlusterFS driver and let CephFS driver to use GaneshaNASHelper2 in the future?  Any timeline for that?","commit_id":"a8e522961cfac486192a52e3bd6dc5f46992c443"},{"author":{"_account_id":6491,"name":"xing-yang","email":"xingyang105@gmail.com","username":"xing-yang"},"change_message_id":"1f5b70bfd11c368eb71fe585734d36fcef108c85","unresolved":false,"context_lines":[{"line_number":129,"context_line":"method which returns the FSAL subblock (in Python represented as"},{"line_number":130,"context_line":"a dict with string keys and values). It has one mandatory key,"},{"line_number":131,"context_line":"``Name``, to which the value should be the name of the FSAL"},{"line_number":132,"context_line":"(eg.: ``{\"Name\": \"CEPH\"}``). Further content of it is"},{"line_number":133,"context_line":"optional and FSAL specific."},{"line_number":134,"context_line":""},{"line_number":135,"context_line":"Customizing Ganesha exports"}],"source_content_type":"text/x-rst","patch_set":6,"id":"7f231b9d_5e258daa","line":132,"range":{"start_line":132,"start_character":18,"end_line":132,"end_character":22},"in_reply_to":"7f231b9d_2214fc4d","updated":"2017-06-12 21:20:57.000000000","message":"Thanks for the explanation.  I see the other patch on the CephFS driver has used GaneshaNASHelper2.  So this looks fine.","commit_id":"a8e522961cfac486192a52e3bd6dc5f46992c443"},{"author":{"_account_id":9003,"name":"Tom Barron","email":"tpb@dyncloud.net","username":"tbarron"},"change_message_id":"69a1c5a460d4e442a8e842c35a526281518a7b4c","unresolved":false,"context_lines":[{"line_number":129,"context_line":"method which returns the FSAL subblock (in Python represented as"},{"line_number":130,"context_line":"a dict with string keys and values). It has one mandatory key,"},{"line_number":131,"context_line":"``Name``, to which the value should be the name of the FSAL"},{"line_number":132,"context_line":"(eg.: ``{\"Name\": \"CEPH\"}``). Further content of it is"},{"line_number":133,"context_line":"optional and FSAL specific."},{"line_number":134,"context_line":""},{"line_number":135,"context_line":"Customizing Ganesha exports"}],"source_content_type":"text/x-rst","patch_set":6,"id":"7f231b9d_2214fc4d","line":132,"range":{"start_line":132,"start_character":18,"end_line":132,"end_character":22},"in_reply_to":"7f231b9d_e23ba4ce","updated":"2017-06-12 16:25:23.000000000","message":"GlusterFS driver is being used in the community so there are no plans to deprecate it.  That said, Red Hat is not actively developing that driver and does not currently plan to move it to GA status downstream (supported in subscription services).  I believe Ben has (informally at this point) proposed a support/testing matrix with categories like \"has vendor support\", \"has community support\", etc.  Gluster drivers would move to the latter category as long as there are community users and patchers (and even if the latter work at Red Hat as long as Red Hat isn\u0027t paying them to work on the glusterfs driver).\n\nDo let me know if you have other questions on this front.","commit_id":"a8e522961cfac486192a52e3bd6dc5f46992c443"}],"manila/share/drivers/ganesha/__init__.py":[{"author":{"_account_id":8056,"name":"Ramana Raja","email":"rraja@redhat.com","username":"Ram_Raja"},"change_message_id":"c676ce923a0d02c4509e6d3fa902052f1c3082b6","unresolved":false,"context_lines":[{"line_number":190,"context_line":"                existing_access_rules \u003d [existing_access_rules]"},{"line_number":191,"context_line":""},{"line_number":192,"context_line":"        wanted_rw_clients, wanted_ro_clients \u003d [], []"},{"line_number":193,"context_line":"        for rule in access_rules:"},{"line_number":194,"context_line":"            if rule[\u0027access_level\u0027] \u003d\u003d \u0027rw\u0027:"},{"line_number":195,"context_line":"                wanted_rw_clients.append(rule[\u0027access_to\u0027])"},{"line_number":196,"context_line":"            elif rule[\u0027access_level\u0027] \u003d\u003d \u0027ro\u0027:"}],"source_content_type":"text/x-python","patch_set":1,"id":"5a3905b3_b4a2ea98","line":193,"updated":"2017-01-25 08:43:32.000000000","message":"Need to validate access rules\u0027 access_type?","commit_id":"9ddf7be304bf5246856432f4c5d79acd18ef5e5c"},{"author":{"_account_id":8056,"name":"Ramana Raja","email":"rraja@redhat.com","username":"Ram_Raja"},"change_message_id":"f00264c464d73ef369f1549b19c9402c2528f75a","unresolved":false,"context_lines":[{"line_number":232,"context_line":"                })"},{"line_number":233,"context_line":"                self.ganesha.add_export(share[\u0027name\u0027], confdict)"},{"line_number":234,"context_line":"        else:"},{"line_number":235,"context_line":"            # No clients have access to the share. Remove export."},{"line_number":236,"context_line":"            self.ganesha.remove_export(share[\u0027name\u0027])"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a461143_71b9c7cb","line":235,"updated":"2017-01-31 09:54:18.000000000","message":"Don\u0027t raise an error if export is already removed. Example scenario: manila\u0027s share manager tries to remove an access rule that was not successfully applied in the first place.","commit_id":"9ddf7be304bf5246856432f4c5d79acd18ef5e5c"}],"manila/share/drivers/ganesha/manager.py":[{"author":{"_account_id":9521,"name":"Csaba Henk","email":"chenk@redhat.com","username":"chenk"},"change_message_id":"7dd8c95b3fecb77d01b441209442999c02ec43bd","unresolved":false,"context_lines":[{"line_number":353,"context_line":"        path \u003d self._write_export_file(name, confdict)"},{"line_number":354,"context_line":"        self._dbus_send_ganesha(\"UpdateExport\", \"string:\" + path,"},{"line_number":355,"context_line":"                                \"string:EXPORT(Export_Id\u003d%d)\" % xid)"},{"line_number":356,"context_line":""},{"line_number":357,"context_line":"    def remove_export(self, name):"},{"line_number":358,"context_line":"        \"\"\"Remove an export from Ganesha.\"\"\""},{"line_number":359,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"1a430d35_e7e599a8","line":356,"updated":"2017-02-03 22:41:01.000000000","message":"Ganesha supports the standard Unix service semantics of config re-read upon receiving SIGHUP from 2.4 on, see https://review.gerrithub.io/286512. \n\nBased on that feature, dbus usage could be dropped and the following workflow could be used for all Ganesha config changes:\n\n- write out config\n- kill(2) ganesha process with SIGHUP (os.kill in Python);\n   the pid of ganesha can be found, if it\u0027s ran with systemd,\n   by invoking \"systemctl status ganesa\" and serch for the\n   like starting with \"Main PID:\" and take the number that\n   comes after. (I don\u0027t know if there is a more direct method\n    that this.)\n\nThe requirement for this to work properly:\n\n- The validity of the config written out can be know statically\n  (ie. validity does not depend on the runime state of Ganesha,\n   like referring to entities in Ganesha which may go out of\n  existence; ie. validity can be known by adherence to\n   generic rules and involving non-changing startup parameters\n  of the Ganesha service).\n\nIf this holds, then we can know that correct data is written out\nas config of Ganesha and we can ignore any actual errors, as\non the  next time we deploy the whole config again, not relying\non previous values.\n\nNo need of implementing rollbacks and worrying about consistency.\n\n(Sanity of the Ganesha service, or rather the lack of that can\nbe a problem, but that wasn\u0027t and isn\u0027t to be addressed by\nthis piece of code. Rather it would be checked upon if some\nHA layer is implemented.)","commit_id":"9ddf7be304bf5246856432f4c5d79acd18ef5e5c"},{"author":{"_account_id":9003,"name":"Tom Barron","email":"tpb@dyncloud.net","username":"tbarron"},"change_message_id":"5617e3356bbccec8f0ac7a2c3ebfbdfc19081dbc","unresolved":false,"context_lines":[{"line_number":353,"context_line":"        path \u003d self._write_export_file(name, confdict)"},{"line_number":354,"context_line":"        self._dbus_send_ganesha(\"UpdateExport\", \"string:\" + path,"},{"line_number":355,"context_line":"                                \"string:EXPORT(Export_Id\u003d%d)\" % xid)"},{"line_number":356,"context_line":""},{"line_number":357,"context_line":"    def remove_export(self, name):"},{"line_number":358,"context_line":"        \"\"\"Remove an export from Ganesha.\"\"\""},{"line_number":359,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"1a430d35_f4b0b7df","line":356,"in_reply_to":"1a430d35_e7e599a8","updated":"2017-02-06 11:59:37.000000000","message":"Interesting idea.  Another potential advantage is just removal of a pretty big dependency.  I\u0027m having some issues setting up ganesha with dbus support on xenial currently (just worked on fedora).  Also, we may need to get ganesha running in the manila-test-image (or some other very small busybox shell type image) in which case the fewer dependencies the better.","commit_id":"9ddf7be304bf5246856432f4c5d79acd18ef5e5c"},{"author":{"_account_id":8056,"name":"Ramana Raja","email":"rraja@redhat.com","username":"Ram_Raja"},"change_message_id":"f7102257c64008ab1e1ecaf82f88e6385d577659","unresolved":false,"context_lines":[{"line_number":353,"context_line":"        path \u003d self._write_export_file(name, confdict)"},{"line_number":354,"context_line":"        self._dbus_send_ganesha(\"UpdateExport\", \"string:\" + path,"},{"line_number":355,"context_line":"                                \"string:EXPORT(Export_Id\u003d%d)\" % xid)"},{"line_number":356,"context_line":""},{"line_number":357,"context_line":"    def remove_export(self, name):"},{"line_number":358,"context_line":"        \"\"\"Remove an export from Ganesha.\"\"\""},{"line_number":359,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a30ddce_17060486","line":356,"in_reply_to":"1a430d35_e7e599a8","updated":"2017-03-09 11:45:11.000000000","message":"SIGHUP rereads all exports, and doesn\u0027t check if any export is no longer in the conf file. SIGHUP can dynamically add or update export, but can\u0027t remove an export. See,\nhttps://sourceforge.net/p/nfs-ganesha/mailman/nfs-ganesha-devel/thread/059801d219a1%24a3f99e80%24ebecdb80%24%40mindspring.com/#msg35396935\nI also checked to verify.\n\nAlso, I think dbus is a cleaner mechanism to dynamically\nadd, remove, or update a particular export. Can we just\nstick to one interface that works for all dynamic operations, dbus?\n\nAbout not needing rollbacks and consistency, you meant that even if we stick to dbus way of doing things, right? (Sorry, your nested i.e., statement in the requirements was quite mind boggling.)\n\nWe\u0027ve a rollback/consistency mechanism in add_export. Should I remove that or let it be?\n\nI\u0027m not going to bother about implementing a rollback/consistency mechanism for updating an export.\n\nThe current, remove_export is kind of confusing though. It\u0027s not \"idempotent\", as it errors out if  the export file has already been removed. This is an issue while force-deleting a share or denying a rule that ended up in an incomplete state. Do the comments I mention in remove_export make sense? Also, is the finally clause really needed? If a deny access ends up in a error state, the user is going to know that the operation didn\u0027t succeed and can try again, right?","commit_id":"9ddf7be304bf5246856432f4c5d79acd18ef5e5c"},{"author":{"_account_id":9521,"name":"Csaba Henk","email":"chenk@redhat.com","username":"chenk"},"change_message_id":"9b23ed5db71db8a7d26d9aeef80f473d2341c00f","unresolved":false,"context_lines":[{"line_number":353,"context_line":"        path \u003d self._write_export_file(name, confdict)"},{"line_number":354,"context_line":"        self._dbus_send_ganesha(\"UpdateExport\", \"string:\" + path,"},{"line_number":355,"context_line":"                                \"string:EXPORT(Export_Id\u003d%d)\" % xid)"},{"line_number":356,"context_line":""},{"line_number":357,"context_line":"    def remove_export(self, name):"},{"line_number":358,"context_line":"        \"\"\"Remove an export from Ganesha.\"\"\""},{"line_number":359,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a30ddce_32010939","line":356,"in_reply_to":"9a30ddce_17060486","updated":"2017-03-10 22:17:23.000000000","message":"\u003e SIGHUP rereads all exports, and doesn\u0027t check if any export is no longer in the conf file. SIGHUP can dynamically add or update export, but can\u0027t remove an export. See, https://sourceforge.net/p/nfs-ganesha/mailman/nfs-ganesha-devel/thread/059801d219a1%24a3f99e80%24ebecdb80%24%40mindspring.com/#msg35396935 I also checked to verify.\n\nNice research! Well, if that\u0027s the case, we are not able to make use of the SIGHUP mechanism.\n\n\u003e Also, I think dbus is a cleaner mechanism to dynamically add, remove, or update a particular export. Can we just stick to one interface that works for all dynamic operations, dbus?\n\u003e About not needing rollbacks and consistency, you meant that even if we stick to dbus way of doing things, right?\n\nLet\u0027s use the following ad-hoc terminology: an \"exact config reload\" is an action that reloads config directives from disk to the Ganesha service and it ends up with those and only those exports being present in the service, which are defined in the config files, and in a state adherent to the config directives.\n\nWhat I meant: if 1) we are able to trigger an exact config reload and 2) we can verify the newly created config\u0027s soundness on the generator\u0027s end before making any change, then we don\u0027t need to rollback. Why? Because then the permanent change we make -- writing the config files -- can be considered atomic. (It\u0027s not atomic at the I/O level; what I mean that either we succeed with making the changes, or there is a serious system malfunction / misconfiguration and then we are doomed and allowed to erupt in panic. No partial state from which we could move back how it was before.) Then whenever we need to make sure runtime status of the service matches the on-disk config, we can perform the exact config reload. (Please consider that this is not absolute truth, it all relies on the assumption that we can/choose to handle errors of disk changing operations as fatal.)\n\nI assumed SIGHUP is a cheap way to trigger an exact config reload. But then it\u0027s not.\n\nThe dbus based service management is not expected to do an exact config reload, it\u0027s just targeted partial update. So this in itself does not provide us exemption from rollback (along the lines sketched above). However, still there is a way to get at an exact config reload, namely, by restating the Ganesha service -- although it\u0027s not cheap. So if in case of error -- dbus call failing -- you are willing to restart the service, then you are applying the above scheme and you don\u0027t need a rollback. If you refrain from this, then I think you do need a rollback, ie. you should restore the old config file.\n\n\u003e (Sorry, your nested i.e., statement in the requirements was quite mind boggling.)\n\nIt was not nested, it was chained :P It would be nested if I opened a new \"ie.\" block to explain a part of the \"ie.\" stanza I\u0027m in. Chained is that further elucidations on the same thing are given in a sequence. Anyway, what I meant is the point 2) above, I hope that makes sense.\n\n\u003e We\u0027ve a rollback/consistency mechanism in add_export. Should I remove that or let it be?\n\nNote that this recovery code does not follow the model I came up with above. It does not treat disk changing operations as atomic, and implements fine grained rollback even if trouble strikes with that. So first of all, we should decide if we adopt my above approach of handling errors of disk changing operations as fatal. If you are not buying into that, this recovery code might be good.\n\n\u003e I\u0027m not going to bother about implementing a rollback/consistency mechanism for updating an export.\n\nThat does not sound sensible to me. \\add_export\u0027 and \u0027update_export\u0027 are variations to the same thing, adapted to different service states, and thus they should be implemented uniformly. Actually they should not exist as separate functions, rather add_export should take a Boolean parameter, say, already_exists, and its value should determine whether to send \"AddExport\" or \"UpdateExport\" on dbus.\n\n\u003e The current, remove_export is kind of confusing though. It\u0027s not \"idempotent\", as it errors out if the export file has already been removed. This is an issue while force-deleting a share or denying a rule that ended up in an incomplete state. Do the comments I mention in remove_export make sense?\n\nYes, I think it\u0027s better to be made idempotent, as we can\u0027t guarantee that the file is there. So probably we should try to remove the file under the condition it\u0027s checked to exist. \n\n\u003e Also, is the finally clause really needed? If a deny access ends up in a error state, the user is going to know that the operation didn\u0027t succeed and can try again, right?\n\nI think it\u0027s not strictly needed, but reasonable to have a finally there. We should exercise the best effort to get it done what the user is asking from us, and it\u0027s good to have the config file part done even if the whole operation is not successful.","commit_id":"9ddf7be304bf5246856432f4c5d79acd18ef5e5c"},{"author":{"_account_id":8056,"name":"Ramana Raja","email":"rraja@redhat.com","username":"Ram_Raja"},"change_message_id":"33fa1a4afadd88153f6b248675f3ba10a8eea99b","unresolved":false,"context_lines":[{"line_number":353,"context_line":"        path \u003d self._write_export_file(name, confdict)"},{"line_number":354,"context_line":"        self._dbus_send_ganesha(\"UpdateExport\", \"string:\" + path,"},{"line_number":355,"context_line":"                                \"string:EXPORT(Export_Id\u003d%d)\" % xid)"},{"line_number":356,"context_line":""},{"line_number":357,"context_line":"    def remove_export(self, name):"},{"line_number":358,"context_line":"        \"\"\"Remove an export from Ganesha.\"\"\""},{"line_number":359,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a30ddce_cfbd5103","line":356,"in_reply_to":"9a30ddce_32010939","updated":"2017-03-13 09:48:36.000000000","message":"\u003e Let\u0027s use the following ad-hoc terminology: an \"exact config reload\" is an action that reloads config directives from disk to the Ganesha service and it ends up with those and only those exports being present in the service, which are defined in the config files, and in a state adherent to the config directives.\n\nUnderstood. Thanks for the explanation.\n\nAdd/Update export\n~~~~~~~~~~~~~~~~~\n\nGot that we should apply the same mechanism, rollback or no rollback, for both add and update export.\n\nIf we\u0027re going to apply rollback mechanism for add and update export, how would you rollback an update to an export file? `cp` the original export file to a temp file;  if something goes wrong when rewriting the export file with updated access list or calling the dbus update export, then `mv` the temp file to the right location; and if nothing goes wrong, `rm` the temp file?\n\nA user\u0027s POV: let\u0027s say he requests to add a rule and the rule ends up in an error state, he can\u0027t figure out the stage at which add/update export went wrong and whether the rollback succeeded. He\u0027d have to request to deny the rule (manila allows rules in error state to be removed) and make sure that the rule was deleted successfully from manila DB to ensure consistency with the backend and reallow access to the same user cred (IP/user/cert/cephx ID).\n\nWhat are we worried about if we don\u0027t rollback for add and update export, and expect the user to delete errored out rules the best he can? If a rule ends up in an error state, it indicates to the user that the rule *might* not have been added or removed successfully from the backend, and does not indicate that the backend enforces the access rule as before trying to apply the rule. I\u0027m thinking without the roll back, add/update export method could be as simple as the one from line 349-355 (remember dbus update export call can dynamically add an export too.).\n\nLet me know if you prefer rollback or no rollback? And if you prefer doing rollback, do my thoughts on implementation of rolling back update export sound OK?\n\nRemove Export\n~~~~~~~~~~~~~\n\n\u003e I think it\u0027s not strictly needed, but reasonable to have a finally there. We should exercise the best effort to get it done what the user is asking from us, and it\u0027s good to have the config file part done even if the whole operation is not successful.\n\nIf we always want to remove the export config file, can we not switch the order of steps instead of using finally?\n\n* Read export file if it exists\n* Remove export file if it exists\n* Remove export dbus call","commit_id":"9ddf7be304bf5246856432f4c5d79acd18ef5e5c"},{"author":{"_account_id":8056,"name":"Ramana Raja","email":"rraja@redhat.com","username":"Ram_Raja"},"change_message_id":"9c9c7b3465331be812b9a5849e45fed3d66f60a1","unresolved":false,"context_lines":[{"line_number":353,"context_line":"        path \u003d self._write_export_file(name, confdict)"},{"line_number":354,"context_line":"        self._dbus_send_ganesha(\"UpdateExport\", \"string:\" + path,"},{"line_number":355,"context_line":"                                \"string:EXPORT(Export_Id\u003d%d)\" % xid)"},{"line_number":356,"context_line":""},{"line_number":357,"context_line":"    def remove_export(self, name):"},{"line_number":358,"context_line":"        \"\"\"Remove an export from Ganesha.\"\"\""},{"line_number":359,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a30ddce_227ef269","line":356,"in_reply_to":"9a30ddce_cfbd5103","updated":"2017-03-13 15:07:09.000000000","message":"\u003e If we always want to remove the export config file, can we not switch the order of steps instead of using finally?\n\nPlease ignore the above suggestion.\n\nI think we should remove the export file only if we\u0027re sure that export is removed from the in memory exports of the ganesha server. Otherwise if the dbus remove export call fails, and we manage to remove the export file, any subsequent call to remove the export (say when a deny access rule fails and rule ends up in error state, and you try to deny access rule again) will always fail without ganesha server restart as the export file would be missing. To determine whether the export is removed from the in memory exports, we\u0027d have to go through dbus ShowExports output, but this seems expensive, and I don\u0027t if it actually works.","commit_id":"9ddf7be304bf5246856432f4c5d79acd18ef5e5c"},{"author":{"_account_id":9521,"name":"Csaba Henk","email":"chenk@redhat.com","username":"chenk"},"change_message_id":"6ea166296ccd84619d87ebf03b4657a3598f8aba","unresolved":false,"context_lines":[{"line_number":353,"context_line":"        path \u003d self._write_export_file(name, confdict)"},{"line_number":354,"context_line":"        self._dbus_send_ganesha(\"UpdateExport\", \"string:\" + path,"},{"line_number":355,"context_line":"                                \"string:EXPORT(Export_Id\u003d%d)\" % xid)"},{"line_number":356,"context_line":""},{"line_number":357,"context_line":"    def remove_export(self, name):"},{"line_number":358,"context_line":"        \"\"\"Remove an export from Ganesha.\"\"\""},{"line_number":359,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"ffe62b97_68f033fe","line":356,"in_reply_to":"9a30ddce_cfbd5103","updated":"2017-03-28 14:11:45.000000000","message":"\u003e If we\u0027re going to apply rollback mechanism for add and update export, how would you rollback an update to an export file? `cp` the original export file to a temp file; if something goes wrong when rewriting the export file with updated access list or calling the dbus update export, then `mv` the temp file to the right location; and if nothing goes wrong, `rm` the temp file?\n\nI\u0027d just read in the original memory (before making any change) and write back from there upon rollback. There are functions to do that already, so thus you don\u0027t have to deal with I/O / fileops directly.\n\n\u003e What are we worried about if we don\u0027t rollback for add and update export, and expect the user to delete errored out rules the best he can? If a rule ends up in an error state, it indicates to the user that the rule *might* not have been added or removed successfully from the backend, and does not indicate that the backend enforces the access rule as before trying to apply the rule. I\u0027m thinking without the roll back, add/update export method could be as simple as the one from line 349-355 (remember dbus update export call can dynamically add an export too.).\n\u003e Let me know if you prefer rollback or no rollback? And if you prefer doing rollback, do my thoughts on implementation of rolling back update export sound OK?\n\nI think it would be nice if we could satisfy the following semantics:  by means of restarting the Ganesha service(s) exactly those exports will be in effect which correspond to non-faulty access rules. (If we have this, we can also add it to the lib docs to be explicit about it.) Then at least the admin has a tool to get back to a transparent state. To get at this, we need to roll back config file changes if the D-Bus¹ part fails.\n\nBut! another idea: can\u0027t we just care about the file changes? And as of the D-Bus: be happy if the D-Bus op succeeds, and fall back to restarting Ganesha if not (thus enforcing a state faithful to the persisted config). So then we don\u0027t roll back for the sake of D-Bus, rather enforce integrity. And then if we also adopt my earlier idea that an error about file changes is a panic situation, then we don\u0027t need to roll back for sake of file update issues -- as we give up instead. In this case no rollback needed at all. So D-Bus then is just an optimization but not an arbiter of success or failure.\n\n¹ Checked the project page to find out about correct spelling, which is D-Bus.","commit_id":"9ddf7be304bf5246856432f4c5d79acd18ef5e5c"},{"author":{"_account_id":8056,"name":"Ramana Raja","email":"rraja@redhat.com","username":"Ram_Raja"},"change_message_id":"1f065cfc111b468d0479d05311e6f8e72db3af8c","unresolved":false,"context_lines":[{"line_number":357,"context_line":"    def remove_export(self, name):"},{"line_number":358,"context_line":"        \"\"\"Remove an export from Ganesha.\"\"\""},{"line_number":359,"context_line":"        try:"},{"line_number":360,"context_line":"            confdict \u003d self._read_export_file(name)"},{"line_number":361,"context_line":"            self._remove_export_dbus(confdict[\"EXPORT\"][\"Export_Id\"])"},{"line_number":362,"context_line":"        finally:"},{"line_number":363,"context_line":"            # TODO(rraja): don\u0027t error out if export already removed?"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a461143_c98579cf","line":360,"updated":"2017-01-31 08:34:44.000000000","message":"Check export file exists, and then read the export file.\nIf export file does not exist, just log a warning, and continue.","commit_id":"9ddf7be304bf5246856432f4c5d79acd18ef5e5c"},{"author":{"_account_id":8056,"name":"Ramana Raja","email":"rraja@redhat.com","username":"Ram_Raja"},"change_message_id":"1f065cfc111b468d0479d05311e6f8e72db3af8c","unresolved":false,"context_lines":[{"line_number":358,"context_line":"        \"\"\"Remove an export from Ganesha.\"\"\""},{"line_number":359,"context_line":"        try:"},{"line_number":360,"context_line":"            confdict \u003d self._read_export_file(name)"},{"line_number":361,"context_line":"            self._remove_export_dbus(confdict[\"EXPORT\"][\"Export_Id\"])"},{"line_number":362,"context_line":"        finally:"},{"line_number":363,"context_line":"            # TODO(rraja): don\u0027t error out if export already removed?"},{"line_number":364,"context_line":"            self._rm_export_file(name)"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a461143_bb1f9059","line":361,"updated":"2017-01-31 08:34:44.000000000","message":"Again, just log warning if the export has already been removed by DBus?","commit_id":"9ddf7be304bf5246856432f4c5d79acd18ef5e5c"},{"author":{"_account_id":8056,"name":"Ramana Raja","email":"rraja@redhat.com","username":"Ram_Raja"},"change_message_id":"9c9c7b3465331be812b9a5849e45fed3d66f60a1","unresolved":false,"context_lines":[{"line_number":358,"context_line":"        \"\"\"Remove an export from Ganesha.\"\"\""},{"line_number":359,"context_line":"        try:"},{"line_number":360,"context_line":"            confdict \u003d self._read_export_file(name)"},{"line_number":361,"context_line":"            self._remove_export_dbus(confdict[\"EXPORT\"][\"Export_Id\"])"},{"line_number":362,"context_line":"        finally:"},{"line_number":363,"context_line":"            # TODO(rraja): don\u0027t error out if export already removed?"},{"line_number":364,"context_line":"            self._rm_export_file(name)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a30ddce_e2ee9a20","line":361,"in_reply_to":"3a461143_bb1f9059","updated":"2017-03-13 15:07:09.000000000","message":"How do we figure out with if the in memory export was already removed?","commit_id":"9ddf7be304bf5246856432f4c5d79acd18ef5e5c"},{"author":{"_account_id":9521,"name":"Csaba Henk","email":"chenk@redhat.com","username":"chenk"},"change_message_id":"6ea166296ccd84619d87ebf03b4657a3598f8aba","unresolved":false,"context_lines":[{"line_number":358,"context_line":"        \"\"\"Remove an export from Ganesha.\"\"\""},{"line_number":359,"context_line":"        try:"},{"line_number":360,"context_line":"            confdict \u003d self._read_export_file(name)"},{"line_number":361,"context_line":"            self._remove_export_dbus(confdict[\"EXPORT\"][\"Export_Id\"])"},{"line_number":362,"context_line":"        finally:"},{"line_number":363,"context_line":"            # TODO(rraja): don\u0027t error out if export already removed?"},{"line_number":364,"context_line":"            self._rm_export_file(name)"}],"source_content_type":"text/x-python","patch_set":1,"id":"ffe62b97_08cf6756","line":361,"in_reply_to":"9a30ddce_e2ee9a20","updated":"2017-03-28 14:11:45.000000000","message":"Well, the 1) Manila access db 2) Ganesha config 3) Ganesha runtime state is expected to be in sync (except the ephemeral out-of-sync state when a change is made to 1), which then drops us into the process of syncing from 1) towards 3), which is just being enacted here).\n\nThen, according to my last and favorite idea (as explained in my comment at line 356), if something unexpected happens at syncing up 3), we enforce integrity by restarting Ganesha and don\u0027t lose any sleep on deciphering Ganesha state.","commit_id":"9ddf7be304bf5246856432f4c5d79acd18ef5e5c"}]}
