)]}'
{"go/swift-rpc-losf/proto/fmgr.pb.go":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"8e830ed9f8a4fc7a005b9ea685f8952ce21d375c","unresolved":false,"context_lines":[{"line_number":1,"context_line":"// Code generated by protoc-gen-go. DO NOT EDIT."},{"line_number":2,"context_line":"// source: fmgr.proto"},{"line_number":3,"context_line":""},{"line_number":4,"context_line":"package filemgr"}],"source_content_type":"text/x-go","patch_set":5,"id":"7faddb67_38696320","line":1,"range":{"start_line":1,"start_character":3,"end_line":1,"end_character":34},"updated":"2019-07-16 23:57:28.000000000","message":"For my future reference: how should I go about validating the changes to a generated file? Presumably something like\n\n- git checkout @~ -- go/swift-rpc-losf/proto/fmgr.pb.go\n- \u003crun tool\u003e\n- git diff @ -- go/swift-rpc-losf/proto/fmgr.pb.go\n\nyeah? What\u0027s step 2 look like?","commit_id":"059ddeaca94a1a296f0f11799f177c62015885f8"},{"author":{"_account_id":25251,"name":"Alexandre Lécuyer","email":"alexandre.lecuyer@corp.ovh.com","username":"alecuyer"},"change_message_id":"1cba1f189ba61358437a33e7b8050b4d69aba2ec","unresolved":false,"context_lines":[{"line_number":1,"context_line":"// Code generated by protoc-gen-go. DO NOT EDIT."},{"line_number":2,"context_line":"// source: fmgr.proto"},{"line_number":3,"context_line":""},{"line_number":4,"context_line":"package filemgr"}],"source_content_type":"text/x-go","patch_set":5,"id":"7faddb67_afb06bde","line":1,"range":{"start_line":1,"start_character":3,"end_line":1,"end_character":34},"in_reply_to":"7faddb67_38696320","updated":"2019-07-17 20:18:32.000000000","message":"Step 2 would be:\nprotoc -I proto proto/fmgr.proto --go_out\u003dplugins\u003dgrpc:proto\nwhich requires the grpc C++ libs and the golang protoc compiler\n\nI wonder if it would be better to *not* include the generated files and have the build process generate them (with a couple of extra dependancy). However, if we\u0027re moving to HTTP, maybe that\u0027s moot.","commit_id":"059ddeaca94a1a296f0f11799f177c62015885f8"},{"author":{"_account_id":25251,"name":"Alexandre Lécuyer","email":"alexandre.lecuyer@corp.ovh.com","username":"alecuyer"},"change_message_id":"43a273714c05cd82dcae3f8deadf6bf38c510c8d","unresolved":false,"context_lines":[{"line_number":1,"context_line":"// Code generated by protoc-gen-go. DO NOT EDIT."},{"line_number":2,"context_line":"// source: fmgr.proto"},{"line_number":3,"context_line":""},{"line_number":4,"context_line":"package filemgr"}],"source_content_type":"text/x-go","patch_set":5,"id":"3fa7e38b_a2ff4ba9","line":1,"range":{"start_line":1,"start_character":3,"end_line":1,"end_character":34},"in_reply_to":"7faddb67_afb06bde","updated":"2019-09-25 14:53:00.000000000","message":"As I\u0027m updating this patch to work with rpc_http, an update to my initial message: ths \"plugins\" bit is not needed now, as we have removed gRPC, and the protoc syntax for python has changed with newer protobuf versions.\n\n// Python: protoc -I. --python_out\u003d. fmgr.proto\n// Golang : protoc -I proto proto/fmgr.proto --go_out\u003dproto\n\nThese two commands can be found as comments at the top of the fmgr.proto file.","commit_id":"059ddeaca94a1a296f0f11799f177c62015885f8"}],"swift/obj/fmgr_pb2.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"8e830ed9f8a4fc7a005b9ea685f8952ce21d375c","unresolved":false,"context_lines":[{"line_number":20,"context_line":"  name\u003d\u0027fmgr.proto\u0027,"},{"line_number":21,"context_line":"  package\u003d\u0027filemgr\u0027,"},{"line_number":22,"context_line":"  syntax\u003d\u0027proto3\u0027,"},{"line_number":23,"context_line":"  serialized_pb\u003d_b(\u0027\\n\\nfmgr.proto\\x12\\x07\\x66ilemgr\\\",\\n\\x12ListPartitionsInfo\\x12\\x16\\n\\x0epartition_bits\\x18\\x01 \\x01(\\r\\\"\u003e\\n\\x11ListPartitionInfo\\x12\\x11\\n\\tpartition\\x18\\x01 \\x01(\\r\\x12\\x16\\n\\x0epartition_bits\\x18\\x02 \\x01(\\r\\\"K\\n\\x0eListSuffixInfo\\x12\\x11\\n\\tpartition\\x18\\x01 \\x01(\\r\\x12\\x0e\\n\\x06suffix\\x18\\x02 \\x01(\\x0c\\x12\\x16\\n\\x0epartition_bits\\x18\\x03 \\x01(\\r\\\"\\x1b\\n\\nDirEntries\\x12\\r\\n\\x05\\x65ntry\\x18\\x01 \\x03(\\t\\\"1\\n\\x0bVolumeIndex\\x12\\r\\n\\x05index\\x18\\x02 \\x01(\\r\\x12\\x13\\n\\x0brepair_tool\\x18\\x03 \\x01(\\x08\\\"\\x86\\x01\\n\\x06Volume\\x12\\x14\\n\\x0cvolume_index\\x18\\x01 \\x01(\\r\\x12(\\n\\x0bvolume_type\\x18\\x02 \\x01(\\x0e\\x32\\x13.filemgr.VolumeType\\x12\\x14\\n\\x0cvolume_state\\x18\\x03 \\x01(\\r\\x12\\x11\\n\\tpartition\\x18\\x04 \\x01(\\r\\x12\\x13\\n\\x0bnext_offset\\x18\\x05 \\x01(\\x04\\\"i\\n\\x11GetNextOffsetInfo\\x12\\x14\\n\\x0cvolume_index\\x18\\x01 \\x01(\\r\\x12\\x13\\n\\x0bvolume_type\\x18\\x02 \\x01(\\r\\x12\\x14\\n\\x0cvolume_state\\x18\\x03 \\x01(\\r\\x12\\x13\\n\\x0brepair_tool\\x18\\x04 \\x01(\\x08\\\"\\\\\\n\\x0fListVolumesInfo\\x12\\x11\\n\\tpartition\\x18\\x01 \\x01(\\r\\x12!\\n\\x04type\\x18\\x02 \\x01(\\x0e\\x32\\x13.filemgr.VolumeType\\x12\\x13\\n\\x0brepair_tool\\x18\\x03 \\x01(\\x08\\\"+\\n\\x07Volumes\\x12 \\n\\x07volumes\\x18\\x01 \\x03(\\x0b\\x32\\x0f.filemgr.Volume\\\"\\\"\\n\\x10VolumeNextOffset\\x12\\x0e\\n\\x06offset\\x18\\x01 \\x01(\\x04\\\"\\xa5\\x01\\n\\rNewVolumeInfo\\x12\\x11\\n\\tpartition\\x18\\x01 \\x01(\\r\\x12!\\n\\x04type\\x18\\x02 \\x01(\\x0e\\x32\\x13.filemgr.VolumeType\\x12\\x14\\n\\x0cvolume_index\\x18\\x03 \\x01(\\r\\x12\\x0e\\n\\x06offset\\x18\\x04 \\x01(\\x04\\x12#\\n\\x05state\\x18\\x05 \\x01(\\x0e\\x32\\x14.filemgr.VolumeState\\x12\\x13\\n\\x0brepair_tool\\x18\\x06 \\x01(\\x08\\\"`\\n\\x0eNewVolumeState\\x12\\x14\\n\\x0cvolume_index\\x18\\x01 \\x01(\\r\\x12#\\n\\x05state\\x18\\x02 \\x01(\\x0e\\x32\\x14.filemgr.VolumeState\\x12\\x13\\n\\x0brepair_tool\\x18\\x03 \\x01(\\x08\\\"\\x10\\n\\x0eNewVolumeReply\\\"\\x10\\n\\x0e\\x44\\x65lObjectReply\\\"\\r\\n\\x0bRenameReply\\\"m\\n\\rNewObjectInfo\\x12\\x0c\\n\\x04name\\x18\\x01 \\x01(\\x0c\\x12\\x14\\n\\x0cvolume_index\\x18\\x02 \\x01(\\r\\x12\\x0e\\n\\x06offset\\x18\\x03 \\x01(\\x04\\x12\\x13\\n\\x0bnext_offset\\x18\\x04 \\x01(\\x04\\x12\\x13\\n\\x0brepair_tool\\x18\\x05 \\x01(\\x08\\\"\\x10\\n\\x0eNewObjectReply\\\"%\\n\\x15QuarantinedObjectName\\x12\\x0c\\n\\x04name\\x18\\x01 \\x01(\\x0c\\\"/\\n\\nObjectName\\x12\\x0c\\n\\x04name\\x18\\x01 \\x01(\\x0c\\x12\\x13\\n\\x0brepair_tool\\x18\\x02 \\x01(\\x08\\\"K\\n\\x0eLoadObjectInfo\\x12\\x0c\\n\\x04name\\x18\\x01 \\x01(\\x0c\\x12\\x16\\n\\x0eis_quarantined\\x18\\x02 \\x01(\\x08\\x12\\x13\\n\\x0brepair_tool\\x18\\x03 \\x01(\\x08\\\"A\\n\\nRenameInfo\\x12\\x0c\\n\\x04name\\x18\\x01 \\x01(\\x0c\\x12\\x10\\n\\x08new_name\\x18\\x02 \\x01(\\x0c\\x12\\x13\\n\\x0brepair_tool\\x18\\x03 \\x01(\\x08\\\"\u003c\\n\\x06Object\\x12\\x0c\\n\\x04name\\x18\\x01 \\x01(\\x0c\\x12\\x14\\n\\x0cvolume_index\\x18\\x02 \\x01(\\r\\x12\\x0e\\n\\x06offset\\x18\\x03 \\x01(\\x04\\\"7\\n\\x13LoadObjectsResponse\\x12 \\n\\x07objects\\x18\\x01 \\x03(\\x0b\\x32\\x0f.filemgr.Object\\\"3\\n\\x0cObjectPrefix\\x12\\x0e\\n\\x06prefix\\x18\\x01 \\x01(\\x0c\\x12\\x13\\n\\x0brepair_tool\\x18\\x02 \\x01(\\x08\\\"\\x07\\n\\x05\\x45mpty\\\"\\x0e\\n\\x0cGetStatsInfo\\\"@\\n\\x10PartitionContent\\x12,\\n\\x0c\\x66ile_entries\\x18\\x01 \\x03(\\x0b\\x32\\x16.filemgr.FullPathEntry\\\"@\\n\\rFullPathEntry\\x12\\x0e\\n\\x06suffix\\x18\\x01 \\x01(\\x0c\\x12\\r\\n\\x05ohash\\x18\\x02 \\x01(\\x0c\\x12\\x10\\n\\x08\\x66ilename\\x18\\x03 \\x01(\\x0c\\\"\\x1a\\n\\x07KvState\\x12\\x0f\\n\\x07isClean\\x18\\x01 \\x01(\\x08\\\"c\\n\\x07KVStats\\x12*\\n\\x05stats\\x18\\x01 \\x03(\\x0b\\x32\\x1b.filemgr.KVStats.StatsEntry\\x1a,\\n\\nStatsEntry\\x12\\x0b\\n\\x03key\\x18\\x01 \\x01(\\t\\x12\\r\\n\\x05value\\x18\\x02 \\x01(\\x04:\\x02\\x38\\x01*N\\n\\nVolumeType\\x12\\x12\\n\\x0eVOLUME_DEFAULT\\x10\\x00\\x12\\x14\\n\\x10VOLUME_TOMBSTONE\\x10\\x01\\x12\\x16\\n\\x12VOLUME_X_DELETE_AT\\x10\\x02*R\\n\\x0bVolumeState\\x12\\x0c\\n\\x08STATE_RW\\x10\\x00\\x12\\x18\\n\\x14STATE_COMPACTION_SRC\\x10\\x01\\x12\\x1b\\n\\x17STATE_COMPACTION_TARGET\\x10\\x02\\x32\\xa5\\x0c\\n\\x07\\x46ileMgr\\x12\\x43\\n\\x0eRegisterVolume\\x12\\x16.filemgr.NewVolumeInfo\\x1a\\x17.filemgr.NewVolumeReply\\\"\\x00\\x12:\\n\\x10UnregisterVolume\\x12\\x14.filemgr.VolumeIndex\\x1a\\x0e.filemgr.Empty\\\"\\x00\\x12\\x43\\n\\x0eRegisterObject\\x12\\x16.filemgr.NewObjectInfo\\x1a\\x17.filemgr.NewObjectReply\\\"\\x00\\x12\\x42\\n\\x10UnregisterObject\\x12\\x13.filemgr.ObjectName\\x1a\\x17.filemgr.DelObjectReply\\\"\\x00\\x12;\\n\\x0cRenameObject\\x12\\x13.filemgr.RenameInfo\\x1a\\x14.filemgr.RenameReply\\\"\\x00\\x12\\x41\\n\\rQuarantineDir\\x12\\x15.filemgr.ObjectPrefix\\x1a\\x17.filemgr.DelObjectReply\\\"\\x00\\x12\\x39\\n\\x10QuarantineObject\\x12\\x13.filemgr.ObjectName\\x1a\\x0e.filemgr.Empty\\\"\\x00\\x12;\\n\\x12UnquarantineObject\\x12\\x13.filemgr.ObjectName\\x1a\\x0e.filemgr.Empty\\\"\\x00\\x12L\\n\\x13LoadObjectsByPrefix\\x12\\x15.filemgr.ObjectPrefix\\x1a\\x1c.filemgr.LoadObjectsResponse\\\"\\x00\\x12;\\n\\x0bListVolumes\\x12\\x18.filemgr.ListVolumesInfo\\x1a\\x10.filemgr.Volumes\\\"\\x00\\x12\\x34\\n\\tGetVolume\\x12\\x14.filemgr.VolumeIndex\\x1a\\x0f.filemgr.Volume\\\"\\x00\\x12\\x44\\n\\x0eListPartitions\\x12\\x1b.filemgr.ListPartitionsInfo\\x1a\\x13.filemgr.DirEntries\\\"\\x00\\x12\\x42\\n\\rListPartition\\x12\\x1a.filemgr.ListPartitionInfo\\x1a\\x13.filemgr.DirEntries\\\"\\x00\\x12\u003c\\n\\nListSuffix\\x12\\x17.filemgr.ListSuffixInfo\\x1a\\x13.filemgr.DirEntries\\\"\\x00\\x12Q\\n\\x16ListPartitionRecursive\\x12\\x1a.filemgr.ListPartitionInfo\\x1a\\x19.filemgr.PartitionContent\\\"\\x00\\x12L\\n\\x16ListQuarantinedOHashes\\x12\\x0e.filemgr.Empty\\x1a\\x1e.filemgr.QuarantinedObjectName\\\"\\x00\\x30\\x01\\x12M\\n\\x14ListQuarantinedOHash\\x12\\x15.filemgr.ObjectPrefix\\x1a\\x1c.filemgr.LoadObjectsResponse\\\"\\x00\\x12\\x38\\n\\nLoadObject\\x12\\x17.filemgr.LoadObjectInfo\\x1a\\x0f.filemgr.Object\\\"\\x00\\x12H\\n\\rGetNextOffset\\x12\\x1a.filemgr.GetNextOffsetInfo\\x1a\\x19.filemgr.VolumeNextOffset\\\"\\x00\\x12\\x35\\n\\x08GetStats\\x12\\x15.filemgr.GetStatsInfo\\x1a\\x10.filemgr.KVStats\\\"\\x00\\x12@\\n\\x13LoadObjectsByVolume\\x12\\x14.filemgr.VolumeIndex\\x1a\\x0f.filemgr.Object\\\"\\x00\\x30\\x01\\x12\u003e\\n\\x11UpdateVolumeState\\x12\\x17.filemgr.NewVolumeState\\x1a\\x0e.filemgr.Empty\\\"\\x00\\x12\\x30\\n\\nSetKvState\\x12\\x10.filemgr.KvState\\x1a\\x0e.filemgr.Empty\\\"\\x00\\x12\\x30\\n\\nGetKvState\\x12\\x0e.filemgr.Empty\\x1a\\x10.filemgr.KvState\\\"\\x00\\x62\\x06proto3\u0027)"},{"line_number":24,"context_line":")"},{"line_number":25,"context_line":"_sym_db.RegisterFileDescriptor(DESCRIPTOR)"},{"line_number":26,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"7faddb67_18c90725","line":23,"updated":"2019-07-16 23:57:28.000000000","message":"... also auto-generated? Hopefully?","commit_id":"059ddeaca94a1a296f0f11799f177c62015885f8"},{"author":{"_account_id":25251,"name":"Alexandre Lécuyer","email":"alexandre.lecuyer@corp.ovh.com","username":"alecuyer"},"change_message_id":"1cba1f189ba61358437a33e7b8050b4d69aba2ec","unresolved":false,"context_lines":[{"line_number":20,"context_line":"  name\u003d\u0027fmgr.proto\u0027,"},{"line_number":21,"context_line":"  package\u003d\u0027filemgr\u0027,"},{"line_number":22,"context_line":"  syntax\u003d\u0027proto3\u0027,"},{"line_number":23,"context_line":"  serialized_pb\u003d_b(\u0027\\n\\nfmgr.proto\\x12\\x07\\x66ilemgr\\\",\\n\\x12ListPartitionsInfo\\x12\\x16\\n\\x0epartition_bits\\x18\\x01 \\x01(\\r\\\"\u003e\\n\\x11ListPartitionInfo\\x12\\x11\\n\\tpartition\\x18\\x01 \\x01(\\r\\x12\\x16\\n\\x0epartition_bits\\x18\\x02 \\x01(\\r\\\"K\\n\\x0eListSuffixInfo\\x12\\x11\\n\\tpartition\\x18\\x01 \\x01(\\r\\x12\\x0e\\n\\x06suffix\\x18\\x02 \\x01(\\x0c\\x12\\x16\\n\\x0epartition_bits\\x18\\x03 \\x01(\\r\\\"\\x1b\\n\\nDirEntries\\x12\\r\\n\\x05\\x65ntry\\x18\\x01 \\x03(\\t\\\"1\\n\\x0bVolumeIndex\\x12\\r\\n\\x05index\\x18\\x02 \\x01(\\r\\x12\\x13\\n\\x0brepair_tool\\x18\\x03 \\x01(\\x08\\\"\\x86\\x01\\n\\x06Volume\\x12\\x14\\n\\x0cvolume_index\\x18\\x01 \\x01(\\r\\x12(\\n\\x0bvolume_type\\x18\\x02 \\x01(\\x0e\\x32\\x13.filemgr.VolumeType\\x12\\x14\\n\\x0cvolume_state\\x18\\x03 \\x01(\\r\\x12\\x11\\n\\tpartition\\x18\\x04 \\x01(\\r\\x12\\x13\\n\\x0bnext_offset\\x18\\x05 \\x01(\\x04\\\"i\\n\\x11GetNextOffsetInfo\\x12\\x14\\n\\x0cvolume_index\\x18\\x01 \\x01(\\r\\x12\\x13\\n\\x0bvolume_type\\x18\\x02 \\x01(\\r\\x12\\x14\\n\\x0cvolume_state\\x18\\x03 \\x01(\\r\\x12\\x13\\n\\x0brepair_tool\\x18\\x04 \\x01(\\x08\\\"\\\\\\n\\x0fListVolumesInfo\\x12\\x11\\n\\tpartition\\x18\\x01 \\x01(\\r\\x12!\\n\\x04type\\x18\\x02 \\x01(\\x0e\\x32\\x13.filemgr.VolumeType\\x12\\x13\\n\\x0brepair_tool\\x18\\x03 \\x01(\\x08\\\"+\\n\\x07Volumes\\x12 \\n\\x07volumes\\x18\\x01 \\x03(\\x0b\\x32\\x0f.filemgr.Volume\\\"\\\"\\n\\x10VolumeNextOffset\\x12\\x0e\\n\\x06offset\\x18\\x01 \\x01(\\x04\\\"\\xa5\\x01\\n\\rNewVolumeInfo\\x12\\x11\\n\\tpartition\\x18\\x01 \\x01(\\r\\x12!\\n\\x04type\\x18\\x02 \\x01(\\x0e\\x32\\x13.filemgr.VolumeType\\x12\\x14\\n\\x0cvolume_index\\x18\\x03 \\x01(\\r\\x12\\x0e\\n\\x06offset\\x18\\x04 \\x01(\\x04\\x12#\\n\\x05state\\x18\\x05 \\x01(\\x0e\\x32\\x14.filemgr.VolumeState\\x12\\x13\\n\\x0brepair_tool\\x18\\x06 \\x01(\\x08\\\"`\\n\\x0eNewVolumeState\\x12\\x14\\n\\x0cvolume_index\\x18\\x01 \\x01(\\r\\x12#\\n\\x05state\\x18\\x02 \\x01(\\x0e\\x32\\x14.filemgr.VolumeState\\x12\\x13\\n\\x0brepair_tool\\x18\\x03 \\x01(\\x08\\\"\\x10\\n\\x0eNewVolumeReply\\\"\\x10\\n\\x0e\\x44\\x65lObjectReply\\\"\\r\\n\\x0bRenameReply\\\"m\\n\\rNewObjectInfo\\x12\\x0c\\n\\x04name\\x18\\x01 \\x01(\\x0c\\x12\\x14\\n\\x0cvolume_index\\x18\\x02 \\x01(\\r\\x12\\x0e\\n\\x06offset\\x18\\x03 \\x01(\\x04\\x12\\x13\\n\\x0bnext_offset\\x18\\x04 \\x01(\\x04\\x12\\x13\\n\\x0brepair_tool\\x18\\x05 \\x01(\\x08\\\"\\x10\\n\\x0eNewObjectReply\\\"%\\n\\x15QuarantinedObjectName\\x12\\x0c\\n\\x04name\\x18\\x01 \\x01(\\x0c\\\"/\\n\\nObjectName\\x12\\x0c\\n\\x04name\\x18\\x01 \\x01(\\x0c\\x12\\x13\\n\\x0brepair_tool\\x18\\x02 \\x01(\\x08\\\"K\\n\\x0eLoadObjectInfo\\x12\\x0c\\n\\x04name\\x18\\x01 \\x01(\\x0c\\x12\\x16\\n\\x0eis_quarantined\\x18\\x02 \\x01(\\x08\\x12\\x13\\n\\x0brepair_tool\\x18\\x03 \\x01(\\x08\\\"A\\n\\nRenameInfo\\x12\\x0c\\n\\x04name\\x18\\x01 \\x01(\\x0c\\x12\\x10\\n\\x08new_name\\x18\\x02 \\x01(\\x0c\\x12\\x13\\n\\x0brepair_tool\\x18\\x03 \\x01(\\x08\\\"\u003c\\n\\x06Object\\x12\\x0c\\n\\x04name\\x18\\x01 \\x01(\\x0c\\x12\\x14\\n\\x0cvolume_index\\x18\\x02 \\x01(\\r\\x12\\x0e\\n\\x06offset\\x18\\x03 \\x01(\\x04\\\"7\\n\\x13LoadObjectsResponse\\x12 \\n\\x07objects\\x18\\x01 \\x03(\\x0b\\x32\\x0f.filemgr.Object\\\"3\\n\\x0cObjectPrefix\\x12\\x0e\\n\\x06prefix\\x18\\x01 \\x01(\\x0c\\x12\\x13\\n\\x0brepair_tool\\x18\\x02 \\x01(\\x08\\\"\\x07\\n\\x05\\x45mpty\\\"\\x0e\\n\\x0cGetStatsInfo\\\"@\\n\\x10PartitionContent\\x12,\\n\\x0c\\x66ile_entries\\x18\\x01 \\x03(\\x0b\\x32\\x16.filemgr.FullPathEntry\\\"@\\n\\rFullPathEntry\\x12\\x0e\\n\\x06suffix\\x18\\x01 \\x01(\\x0c\\x12\\r\\n\\x05ohash\\x18\\x02 \\x01(\\x0c\\x12\\x10\\n\\x08\\x66ilename\\x18\\x03 \\x01(\\x0c\\\"\\x1a\\n\\x07KvState\\x12\\x0f\\n\\x07isClean\\x18\\x01 \\x01(\\x08\\\"c\\n\\x07KVStats\\x12*\\n\\x05stats\\x18\\x01 \\x03(\\x0b\\x32\\x1b.filemgr.KVStats.StatsEntry\\x1a,\\n\\nStatsEntry\\x12\\x0b\\n\\x03key\\x18\\x01 \\x01(\\t\\x12\\r\\n\\x05value\\x18\\x02 \\x01(\\x04:\\x02\\x38\\x01*N\\n\\nVolumeType\\x12\\x12\\n\\x0eVOLUME_DEFAULT\\x10\\x00\\x12\\x14\\n\\x10VOLUME_TOMBSTONE\\x10\\x01\\x12\\x16\\n\\x12VOLUME_X_DELETE_AT\\x10\\x02*R\\n\\x0bVolumeState\\x12\\x0c\\n\\x08STATE_RW\\x10\\x00\\x12\\x18\\n\\x14STATE_COMPACTION_SRC\\x10\\x01\\x12\\x1b\\n\\x17STATE_COMPACTION_TARGET\\x10\\x02\\x32\\xa5\\x0c\\n\\x07\\x46ileMgr\\x12\\x43\\n\\x0eRegisterVolume\\x12\\x16.filemgr.NewVolumeInfo\\x1a\\x17.filemgr.NewVolumeReply\\\"\\x00\\x12:\\n\\x10UnregisterVolume\\x12\\x14.filemgr.VolumeIndex\\x1a\\x0e.filemgr.Empty\\\"\\x00\\x12\\x43\\n\\x0eRegisterObject\\x12\\x16.filemgr.NewObjectInfo\\x1a\\x17.filemgr.NewObjectReply\\\"\\x00\\x12\\x42\\n\\x10UnregisterObject\\x12\\x13.filemgr.ObjectName\\x1a\\x17.filemgr.DelObjectReply\\\"\\x00\\x12;\\n\\x0cRenameObject\\x12\\x13.filemgr.RenameInfo\\x1a\\x14.filemgr.RenameReply\\\"\\x00\\x12\\x41\\n\\rQuarantineDir\\x12\\x15.filemgr.ObjectPrefix\\x1a\\x17.filemgr.DelObjectReply\\\"\\x00\\x12\\x39\\n\\x10QuarantineObject\\x12\\x13.filemgr.ObjectName\\x1a\\x0e.filemgr.Empty\\\"\\x00\\x12;\\n\\x12UnquarantineObject\\x12\\x13.filemgr.ObjectName\\x1a\\x0e.filemgr.Empty\\\"\\x00\\x12L\\n\\x13LoadObjectsByPrefix\\x12\\x15.filemgr.ObjectPrefix\\x1a\\x1c.filemgr.LoadObjectsResponse\\\"\\x00\\x12;\\n\\x0bListVolumes\\x12\\x18.filemgr.ListVolumesInfo\\x1a\\x10.filemgr.Volumes\\\"\\x00\\x12\\x34\\n\\tGetVolume\\x12\\x14.filemgr.VolumeIndex\\x1a\\x0f.filemgr.Volume\\\"\\x00\\x12\\x44\\n\\x0eListPartitions\\x12\\x1b.filemgr.ListPartitionsInfo\\x1a\\x13.filemgr.DirEntries\\\"\\x00\\x12\\x42\\n\\rListPartition\\x12\\x1a.filemgr.ListPartitionInfo\\x1a\\x13.filemgr.DirEntries\\\"\\x00\\x12\u003c\\n\\nListSuffix\\x12\\x17.filemgr.ListSuffixInfo\\x1a\\x13.filemgr.DirEntries\\\"\\x00\\x12Q\\n\\x16ListPartitionRecursive\\x12\\x1a.filemgr.ListPartitionInfo\\x1a\\x19.filemgr.PartitionContent\\\"\\x00\\x12L\\n\\x16ListQuarantinedOHashes\\x12\\x0e.filemgr.Empty\\x1a\\x1e.filemgr.QuarantinedObjectName\\\"\\x00\\x30\\x01\\x12M\\n\\x14ListQuarantinedOHash\\x12\\x15.filemgr.ObjectPrefix\\x1a\\x1c.filemgr.LoadObjectsResponse\\\"\\x00\\x12\\x38\\n\\nLoadObject\\x12\\x17.filemgr.LoadObjectInfo\\x1a\\x0f.filemgr.Object\\\"\\x00\\x12H\\n\\rGetNextOffset\\x12\\x1a.filemgr.GetNextOffsetInfo\\x1a\\x19.filemgr.VolumeNextOffset\\\"\\x00\\x12\\x35\\n\\x08GetStats\\x12\\x15.filemgr.GetStatsInfo\\x1a\\x10.filemgr.KVStats\\\"\\x00\\x12@\\n\\x13LoadObjectsByVolume\\x12\\x14.filemgr.VolumeIndex\\x1a\\x0f.filemgr.Object\\\"\\x00\\x30\\x01\\x12\u003e\\n\\x11UpdateVolumeState\\x12\\x17.filemgr.NewVolumeState\\x1a\\x0e.filemgr.Empty\\\"\\x00\\x12\\x30\\n\\nSetKvState\\x12\\x10.filemgr.KvState\\x1a\\x0e.filemgr.Empty\\\"\\x00\\x12\\x30\\n\\nGetKvState\\x12\\x0e.filemgr.Empty\\x1a\\x10.filemgr.KvState\\\"\\x00\\x62\\x06proto3\u0027)"},{"line_number":24,"context_line":")"},{"line_number":25,"context_line":"_sym_db.RegisterFileDescriptor(DESCRIPTOR)"},{"line_number":26,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"7faddb67_0fe3bfda","line":23,"in_reply_to":"7faddb67_18c90725","updated":"2019-07-17 20:18:32.000000000","message":"yes! the whole file is auto generated (see comment in obj/fmgr.proto). It requires an extra python package, grpcio-tools","commit_id":"059ddeaca94a1a296f0f11799f177c62015885f8"}],"swift/obj/header.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"8e830ed9f8a4fc7a005b9ea685f8952ce21d375c","unresolved":false,"context_lines":[{"line_number":24,"context_line":"VOLUME_HEADER_VERSION \u003d 1"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"OBJECT_START_MARKER \u003d \"SWIFTOBJ\""},{"line_number":27,"context_line":"VOLUME_START_MARKER \u003d \"SWIFTVOL\""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"# object alignment within a volume."},{"line_number":30,"context_line":"# this is needed so that FALLOC_FL_PUNCH_HOLE can actually return space back"}],"source_content_type":"text/x-python","patch_set":5,"id":"7faddb67_a18bb0c0","line":27,"updated":"2019-07-16 23:57:28.000000000","message":"Should we use\n\n b\"SWIFTOBJ\"\n\nand\n\n b\"SWIFTVOL\"\n\nhere? We\u0027re talking about actual bytes-on-disk, right? I think that\u0027ll clear up a fair number of py3 tests...","commit_id":"059ddeaca94a1a296f0f11799f177c62015885f8"},{"author":{"_account_id":25251,"name":"Alexandre Lécuyer","email":"alexandre.lecuyer@corp.ovh.com","username":"alecuyer"},"change_message_id":"1cba1f189ba61358437a33e7b8050b4d69aba2ec","unresolved":false,"context_lines":[{"line_number":24,"context_line":"VOLUME_HEADER_VERSION \u003d 1"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"OBJECT_START_MARKER \u003d \"SWIFTOBJ\""},{"line_number":27,"context_line":"VOLUME_START_MARKER \u003d \"SWIFTVOL\""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"# object alignment within a volume."},{"line_number":30,"context_line":"# this is needed so that FALLOC_FL_PUNCH_HOLE can actually return space back"}],"source_content_type":"text/x-python","patch_set":5,"id":"7faddb67_cfe847b4","line":27,"in_reply_to":"7faddb67_a18bb0c0","updated":"2019-07-17 20:18:32.000000000","message":"Right, will do","commit_id":"059ddeaca94a1a296f0f11799f177c62015885f8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"8e830ed9f8a4fc7a005b9ea685f8952ce21d375c","unresolved":false,"context_lines":[{"line_number":68,"context_line":"        Total object size (8 bytes)"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"    Version 2: similar but 64 chars for the filename"},{"line_number":71,"context_line":"    Version 3: Adds a \"state\" field (unsigned char)"},{"line_number":72,"context_line":"    \"\"\""},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"    def __init__(self, version\u003dOBJECT_HEADER_VERSION):"}],"source_content_type":"text/x-python","patch_set":5,"id":"7faddb67_58e21fa2","line":71,"updated":"2019-07-16 23:57:28.000000000","message":"What\u0027s the delta to v4?\n\nIt weirds me out a little that not all instances of ObjectHeader will have the same attributes available, but... meh. hasattr() and getattr() aren\u0027t so bad.","commit_id":"059ddeaca94a1a296f0f11799f177c62015885f8"},{"author":{"_account_id":25251,"name":"Alexandre Lécuyer","email":"alexandre.lecuyer@corp.ovh.com","username":"alecuyer"},"change_message_id":"1cba1f189ba61358437a33e7b8050b4d69aba2ec","unresolved":false,"context_lines":[{"line_number":68,"context_line":"        Total object size (8 bytes)"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"    Version 2: similar but 64 chars for the filename"},{"line_number":71,"context_line":"    Version 3: Adds a \"state\" field (unsigned char)"},{"line_number":72,"context_line":"    \"\"\""},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"    def __init__(self, version\u003dOBJECT_HEADER_VERSION):"}],"source_content_type":"text/x-python","patch_set":5,"id":"7faddb67_6ffcb36f","line":71,"in_reply_to":"7faddb67_58e21fa2","updated":"2019-07-17 20:18:32.000000000","message":"Yes, that\u0027s not great, and I think Kota already had reservations about this early on, and wanted to use fixed size headers.\n\nWe\u0027re aware it\u0027s not great and have already discussed it with Romain. If needed, we could design this differently and change the on-disk format if required, keeping a separate, non-upstream patch for our existing data.","commit_id":"059ddeaca94a1a296f0f11799f177c62015885f8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"41dc77ec8cd0615f85b9abd8c702201ef54916be","unresolved":false,"context_lines":[{"line_number":68,"context_line":"        Total object size (8 bytes)"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"    Version 2: similar but 64 chars for the filename"},{"line_number":71,"context_line":"    Version 3: Adds a \"state\" field (unsigned char)"},{"line_number":72,"context_line":"    \"\"\""},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"    def __init__(self, version\u003dOBJECT_HEADER_VERSION):"}],"source_content_type":"text/x-python","patch_set":5,"id":"7faddb67_72fb3ac0","line":71,"in_reply_to":"7faddb67_6ffcb36f","updated":"2019-07-17 20:54:05.000000000","message":"*shrug* I\u0027m not so worried about keeping the parsing for old formats -- serves us right for taking so long to review it! :P\n\nYou\u0027ve done a great job of making it easy to write the new packing/unpacking then (hopefully, mostly, modulo some py3 stuff) *never need to touch it again*.","commit_id":"059ddeaca94a1a296f0f11799f177c62015885f8"}],"swift/obj/vfile.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"8e830ed9f8a4fc7a005b9ea685f8952ce21d375c","unresolved":false,"context_lines":[{"line_number":264,"context_line":"        # create object header"},{"line_number":265,"context_line":"        header \u003d ObjectHeader(version\u003dOBJECT_HEADER_VERSION)"},{"line_number":266,"context_line":"        header.ohash \u003d si.ohash"},{"line_number":267,"context_line":"        # TODO: this is unused, always set to zero."},{"line_number":268,"context_line":"        header.policy_idx \u003d 0"},{"line_number":269,"context_line":"        header.data_offset \u003d len(header) + conf[\u0027metadata_reserve\u0027]"},{"line_number":270,"context_line":"        header.data_size \u003d 0"}],"source_content_type":"text/x-python","patch_set":5,"id":"7faddb67_58577f27","line":267,"updated":"2019-07-16 23:57:28.000000000","message":"Interesting -- I guess it\u0027s tracked somewhere at the slab level?\n\nAt some point, should we have a v5 header where we drop the policy_idx?","commit_id":"059ddeaca94a1a296f0f11799f177c62015885f8"},{"author":{"_account_id":25251,"name":"Alexandre Lécuyer","email":"alexandre.lecuyer@corp.ovh.com","username":"alecuyer"},"change_message_id":"1cba1f189ba61358437a33e7b8050b4d69aba2ec","unresolved":false,"context_lines":[{"line_number":264,"context_line":"        # create object header"},{"line_number":265,"context_line":"        header \u003d ObjectHeader(version\u003dOBJECT_HEADER_VERSION)"},{"line_number":266,"context_line":"        header.ohash \u003d si.ohash"},{"line_number":267,"context_line":"        # TODO: this is unused, always set to zero."},{"line_number":268,"context_line":"        header.policy_idx \u003d 0"},{"line_number":269,"context_line":"        header.data_offset \u003d len(header) + conf[\u0027metadata_reserve\u0027]"},{"line_number":270,"context_line":"        header.data_size \u003d 0"}],"source_content_type":"text/x-python","patch_set":5,"id":"7faddb67_cf0fe785","line":267,"in_reply_to":"7faddb67_58577f27","updated":"2019-07-17 20:18:32.000000000","message":"I think it\u0027s from early designs and we forgot to drop it when we switched to per-policy directories.\n\nNow, for policy-1, your volumes will live in:\n/sda/losf-1/volumes , similar to \"objects\", \"objects-1\", which means we don\u0027t really need to track that at all.\n\nso yes that\u0027s something that should be dropped","commit_id":"059ddeaca94a1a296f0f11799f177c62015885f8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"41dc77ec8cd0615f85b9abd8c702201ef54916be","unresolved":false,"context_lines":[{"line_number":264,"context_line":"        # create object header"},{"line_number":265,"context_line":"        header \u003d ObjectHeader(version\u003dOBJECT_HEADER_VERSION)"},{"line_number":266,"context_line":"        header.ohash \u003d si.ohash"},{"line_number":267,"context_line":"        # TODO: this is unused, always set to zero."},{"line_number":268,"context_line":"        header.policy_idx \u003d 0"},{"line_number":269,"context_line":"        header.data_offset \u003d len(header) + conf[\u0027metadata_reserve\u0027]"},{"line_number":270,"context_line":"        header.data_size \u003d 0"}],"source_content_type":"text/x-python","patch_set":5,"id":"7faddb67_32c86272","line":267,"in_reply_to":"7faddb67_cf0fe785","updated":"2019-07-17 20:54:05.000000000","message":"\u003e which means we don\u0027t really need to track that at all.\n\nI\u0027m not entirely convinced that this follows... at any rate, there\u0027s certainly prior art for writing down sotrage-policy redundantly: every .data has policy in xattrs currently, despite that same info being available in the path!\n\nI guess it could be helpful in case there was some xfs corruption at the objects-N level... say, a bit-flip that turns objects-1 to objects-5... though I\u0027m not sure that we actually *check* that anywhere...","commit_id":"059ddeaca94a1a296f0f11799f177c62015885f8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"8e830ed9f8a4fc7a005b9ea685f8952ce21d375c","unresolved":false,"context_lines":[{"line_number":686,"context_line":"    # This is about 30% faster than calling int() in the list comprehension"},{"line_number":687,"context_line":"    # above."},{"line_number":688,"context_line":"    idxs \u003d map(int, volumes_and_locks_idxs)"},{"line_number":689,"context_line":"    idxs.sort()"},{"line_number":690,"context_line":""},{"line_number":691,"context_line":"    # find the first \"hole\" in the indexes"},{"line_number":692,"context_line":"    for idx in xrange(1, len(idxs) + 1):"}],"source_content_type":"text/x-python","patch_set":5,"id":"7faddb67_a1b41081","line":689,"updated":"2019-07-16 23:57:28.000000000","message":"Hrm. But map() results don\u0027t have a .sort() on py3... what about\n\n idxs \u003d sorted(map(int, volumes_and_locks_idxs))\n\nAt that point, how much of a difference does it make to use map vs another generator, like\n\n idxs \u003d sorted(int(i) for i in volumes_and_locks_idxs)\n\n? I guess that maybe comes down to how much of the 30% improvement can be attributed to the set() removing duplicate work...","commit_id":"059ddeaca94a1a296f0f11799f177c62015885f8"},{"author":{"_account_id":25251,"name":"Alexandre Lécuyer","email":"alexandre.lecuyer@corp.ovh.com","username":"alecuyer"},"change_message_id":"1cba1f189ba61358437a33e7b8050b4d69aba2ec","unresolved":false,"context_lines":[{"line_number":686,"context_line":"    # This is about 30% faster than calling int() in the list comprehension"},{"line_number":687,"context_line":"    # above."},{"line_number":688,"context_line":"    idxs \u003d map(int, volumes_and_locks_idxs)"},{"line_number":689,"context_line":"    idxs.sort()"},{"line_number":690,"context_line":""},{"line_number":691,"context_line":"    # find the first \"hole\" in the indexes"},{"line_number":692,"context_line":"    for idx in xrange(1, len(idxs) + 1):"}],"source_content_type":"text/x-python","patch_set":5,"id":"7faddb67_0f9bbf17","line":689,"in_reply_to":"7faddb67_a1b41081","updated":"2019-07-17 20:18:32.000000000","message":"I think I remember something about the \"int\" function having to be looked up in the list comprehension vs map, but I\u0027m not sure. I\u0027ll look at this again and run tests against \"large\" number of volumes.","commit_id":"059ddeaca94a1a296f0f11799f177c62015885f8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"8e830ed9f8a4fc7a005b9ea685f8952ce21d375c","unresolved":false,"context_lines":[{"line_number":691,"context_line":"    # find the first \"hole\" in the indexes"},{"line_number":692,"context_line":"    for idx in xrange(1, len(idxs) + 1):"},{"line_number":693,"context_line":"        if idxs[idx - 1] !\u003d idx:"},{"line_number":694,"context_line":"            return idx"},{"line_number":695,"context_line":""},{"line_number":696,"context_line":"    # no hole found"},{"line_number":697,"context_line":"    return idx + 1"}],"source_content_type":"text/x-python","patch_set":5,"id":"7faddb67_c174acd1","line":694,"updated":"2019-07-16 23:57:28.000000000","message":"Alternatively,\n\n for idx, vol in enumerate(idxs, start\u003d1):\n     if idx !\u003d vol:\n         return idx\n\nIDK which I like more... *shrug* w/e\n\nI also feel like there ought to be a clever way to use bisect() to avoid the O(n) performance... but the interface isn\u0027t quite right for it...\n\nMeh, that last idea\u0027s probably too clever for its own good.","commit_id":"059ddeaca94a1a296f0f11799f177c62015885f8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"41dc77ec8cd0615f85b9abd8c702201ef54916be","unresolved":false,"context_lines":[{"line_number":691,"context_line":"    # find the first \"hole\" in the indexes"},{"line_number":692,"context_line":"    for idx in xrange(1, len(idxs) + 1):"},{"line_number":693,"context_line":"        if idxs[idx - 1] !\u003d idx:"},{"line_number":694,"context_line":"            return idx"},{"line_number":695,"context_line":""},{"line_number":696,"context_line":"    # no hole found"},{"line_number":697,"context_line":"    return idx + 1"}],"source_content_type":"text/x-python","patch_set":5,"id":"7faddb67_927b5626","line":694,"in_reply_to":"7faddb67_af12ab60","updated":"2019-07-17 20:54:05.000000000","message":"\u003e Certainly your proposal looks clearer.\n\nAgain, IDK about that ;-)\n\nI went with it, though, mainly since xrange isn\u0027t a thing on py3, I wasn\u0027t sure how big the set might be, and it felt a little silly to use six.moves.range for such a small thing.\n\n\u003e so far decided against adding more code\n\nSounds good; as a rule, less code means fewer bugs :-)","commit_id":"059ddeaca94a1a296f0f11799f177c62015885f8"},{"author":{"_account_id":25251,"name":"Alexandre Lécuyer","email":"alexandre.lecuyer@corp.ovh.com","username":"alecuyer"},"change_message_id":"1cba1f189ba61358437a33e7b8050b4d69aba2ec","unresolved":false,"context_lines":[{"line_number":691,"context_line":"    # find the first \"hole\" in the indexes"},{"line_number":692,"context_line":"    for idx in xrange(1, len(idxs) + 1):"},{"line_number":693,"context_line":"        if idxs[idx - 1] !\u003d idx:"},{"line_number":694,"context_line":"            return idx"},{"line_number":695,"context_line":""},{"line_number":696,"context_line":"    # no hole found"},{"line_number":697,"context_line":"    return idx + 1"}],"source_content_type":"text/x-python","patch_set":5,"id":"7faddb67_af12ab60","line":694,"in_reply_to":"7faddb67_c174acd1","updated":"2019-07-17 20:18:32.000000000","message":"Certainly your proposal looks clearer.\n\nI also thought about requesting it from the index-server, with the file locking protecting against races. But currently it would require running an iterator in the volume \"namespace\" in leveldb, so maybe not as fast as golang vs python would suggest.\nMaybe it could be cached. There are a few things I thought we could cache in the index-server to save CPU, but so far decided against adding more code.","commit_id":"059ddeaca94a1a296f0f11799f177c62015885f8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"223810409a3116a83519199a3737991802bcdfa1","unresolved":false,"context_lines":[{"line_number":622,"context_line":"        lock_file \u003d os.open(lock_file_path, os.O_WRONLY)"},{"line_number":623,"context_line":"    except OSError as e:"},{"line_number":624,"context_line":"        # if the volume lock file as been removed, create it"},{"line_number":625,"context_line":"        if e.errno \u003d\u003d errno.ENOENT:"},{"line_number":626,"context_line":"            lock_file \u003d os.open(lock_file_path,"},{"line_number":627,"context_line":"                                os.O_CREAT | os.O_EXCL | os.O_WRONLY, 0o600)"},{"line_number":628,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":6,"id":"7faddb67_0c950d33","line":625,"updated":"2019-07-17 18:38:52.000000000","message":"No else? Surely there should be an\n\n else:\n     raise\n\nright?","commit_id":"f71a172cc13e47ba92ece841042b574ebc6b0515"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e2a4d191113311e4ce83bc6c4b5176759e00a933","unresolved":false,"context_lines":[{"line_number":630,"context_line":"    try:"},{"line_number":631,"context_line":"        lock_file \u003d os.open(lock_file_path, os.O_WRONLY)"},{"line_number":632,"context_line":"    except OSError as e:"},{"line_number":633,"context_line":"        if e.errno !\u003d errno.ENOENT:"},{"line_number":634,"context_line":"            raise"},{"line_number":635,"context_line":"        # if the volume lock file as been removed, create it"},{"line_number":636,"context_line":"        lock_file \u003d os.open(lock_file_path,"},{"line_number":637,"context_line":"                            os.O_CREAT | os.O_EXCL | os.O_WRONLY, 0o600)"}],"source_content_type":"text/x-python","patch_set":9,"id":"3fa7e38b_1259a9fc","line":634,"range":{"start_line":633,"start_character":8,"end_line":634,"end_character":17},"updated":"2019-09-27 04:05:27.000000000","message":"Have I got this right? I think we risk hitting a NameError otherwise...","commit_id":"96853029255c6adf38b726e93d85562db36f5d5f"},{"author":{"_account_id":25251,"name":"Alexandre Lécuyer","email":"alexandre.lecuyer@corp.ovh.com","username":"alecuyer"},"change_message_id":"1939feedd0bd64a14494a9455664c71ba4eecddf","unresolved":false,"context_lines":[{"line_number":630,"context_line":"    try:"},{"line_number":631,"context_line":"        lock_file \u003d os.open(lock_file_path, os.O_WRONLY)"},{"line_number":632,"context_line":"    except OSError as e:"},{"line_number":633,"context_line":"        if e.errno !\u003d errno.ENOENT:"},{"line_number":634,"context_line":"            raise"},{"line_number":635,"context_line":"        # if the volume lock file as been removed, create it"},{"line_number":636,"context_line":"        lock_file \u003d os.open(lock_file_path,"},{"line_number":637,"context_line":"                            os.O_CREAT | os.O_EXCL | os.O_WRONLY, 0o600)"}],"source_content_type":"text/x-python","patch_set":9,"id":"3fa7e38b_d1b9cc78","line":634,"range":{"start_line":633,"start_character":8,"end_line":634,"end_character":17},"in_reply_to":"3fa7e38b_1259a9fc","updated":"2019-09-27 09:53:53.000000000","message":"That\u0027s right, thanks!","commit_id":"96853029255c6adf38b726e93d85562db36f5d5f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"24dad0c4d89c42b5390b84890283774bf3524e8b","unresolved":false,"context_lines":[{"line_number":261,"context_line":"        volume_file, lock_file, volume_path \u003d open_or_create_volume("},{"line_number":262,"context_line":"            socket_path, si.partition, extension, volume_dir,"},{"line_number":263,"context_line":"            conf, logger, size\u003dobj_size)"},{"line_number":264,"context_line":"        volume_index \u003d get_volume_index(volume_path)"},{"line_number":265,"context_line":""},{"line_number":266,"context_line":"        # create object header"},{"line_number":267,"context_line":"        header \u003d ObjectHeader(version\u003dOBJECT_HEADER_VERSION)"}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_60d78425","line":264,"range":{"start_line":264,"start_character":23,"end_line":264,"end_character":39},"updated":"2019-10-03 23:34:15.000000000","message":"open_or_create_volume should ensure this never raises a ValueError, right?\n\nYour new error-handling has me nervous ;-)","commit_id":"3623c48bc7ed6532395acac2e028d3752d3172b6"},{"author":{"_account_id":25251,"name":"Alexandre Lécuyer","email":"alexandre.lecuyer@corp.ovh.com","username":"alecuyer"},"change_message_id":"b137fcd6f9a239b2ff4c1ec28d861a6940e5f587","unresolved":false,"context_lines":[{"line_number":261,"context_line":"        volume_file, lock_file, volume_path \u003d open_or_create_volume("},{"line_number":262,"context_line":"            socket_path, si.partition, extension, volume_dir,"},{"line_number":263,"context_line":"            conf, logger, size\u003dobj_size)"},{"line_number":264,"context_line":"        volume_index \u003d get_volume_index(volume_path)"},{"line_number":265,"context_line":""},{"line_number":266,"context_line":"        # create object header"},{"line_number":267,"context_line":"        header \u003d ObjectHeader(version\u003dOBJECT_HEADER_VERSION)"}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_daa97c90","line":264,"range":{"start_line":264,"start_character":23,"end_line":264,"end_character":39},"in_reply_to":"3fa7e38b_60d78425","updated":"2019-10-04 16:03:08.000000000","message":"Ah yes it assumes the volume_path we get from the call above is correct.","commit_id":"3623c48bc7ed6532395acac2e028d3752d3172b6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"24dad0c4d89c42b5390b84890283774bf3524e8b","unresolved":false,"context_lines":[{"line_number":415,"context_line":"    creation_lock_path \u003d os.path.join(volume_dir, VCREATION_LOCK_NAME)"},{"line_number":416,"context_line":"    with open(creation_lock_path, \u0027w\u0027) as creation_lock_file:"},{"line_number":417,"context_line":"        # this may block"},{"line_number":418,"context_line":"        fcntl.flock(creation_lock_file, fcntl.LOCK_EX)"},{"line_number":419,"context_line":""},{"line_number":420,"context_line":"        index \u003d get_next_volume_index(volume_dir)"},{"line_number":421,"context_line":"        next_lock_name \u003d get_lock_file_name(index)"}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_434cd275","line":418,"range":{"start_line":418,"start_character":14,"end_line":418,"end_character":38},"updated":"2019-10-03 23:34:15.000000000","message":"The with block ensures that we close creation_lock_file, and the close() ensures we unlock it, yeah?","commit_id":"3623c48bc7ed6532395acac2e028d3752d3172b6"},{"author":{"_account_id":25251,"name":"Alexandre Lécuyer","email":"alexandre.lecuyer@corp.ovh.com","username":"alecuyer"},"change_message_id":"b137fcd6f9a239b2ff4c1ec28d861a6940e5f587","unresolved":false,"context_lines":[{"line_number":415,"context_line":"    creation_lock_path \u003d os.path.join(volume_dir, VCREATION_LOCK_NAME)"},{"line_number":416,"context_line":"    with open(creation_lock_path, \u0027w\u0027) as creation_lock_file:"},{"line_number":417,"context_line":"        # this may block"},{"line_number":418,"context_line":"        fcntl.flock(creation_lock_file, fcntl.LOCK_EX)"},{"line_number":419,"context_line":""},{"line_number":420,"context_line":"        index \u003d get_next_volume_index(volume_dir)"},{"line_number":421,"context_line":"        next_lock_name \u003d get_lock_file_name(index)"}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_9a7c6421","line":418,"range":{"start_line":418,"start_character":14,"end_line":418,"end_character":38},"in_reply_to":"3fa7e38b_434cd275","updated":"2019-10-04 16:03:08.000000000","message":"Yes, close() will unlock the file. Per fcntl man page:\n\"If  a  process  closes any file descriptor referring to a file, then all of the process\u0027s locks on that file are released, regardless of the file descriptor(s) on which the locks were obtained.\"","commit_id":"3623c48bc7ed6532395acac2e028d3752d3172b6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"24dad0c4d89c42b5390b84890283774bf3524e8b","unresolved":false,"context_lines":[{"line_number":430,"context_line":""},{"line_number":431,"context_line":"        try:"},{"line_number":432,"context_line":"            fcntl.flock(lock_file, fcntl.LOCK_EX | fcntl.LOCK_NB)"},{"line_number":433,"context_line":"        except IOError:"},{"line_number":434,"context_line":"            increment(logger, \u0027vfile.volume_creation.fail_other\u0027)"},{"line_number":435,"context_line":"            raise"},{"line_number":436,"context_line":""},{"line_number":437,"context_line":"    return lock_file"},{"line_number":438,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_439a92c5","line":435,"range":{"start_line":433,"start_character":8,"end_line":435,"end_character":17},"updated":"2019-10-03 23:34:15.000000000","message":"Should we close lock_file before raising? Should we unlink next_lock_path?","commit_id":"3623c48bc7ed6532395acac2e028d3752d3172b6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e18a19a2fba1459d063909af3be8955745694890","unresolved":false,"context_lines":[{"line_number":430,"context_line":""},{"line_number":431,"context_line":"        try:"},{"line_number":432,"context_line":"            fcntl.flock(lock_file, fcntl.LOCK_EX | fcntl.LOCK_NB)"},{"line_number":433,"context_line":"        except IOError:"},{"line_number":434,"context_line":"            increment(logger, \u0027vfile.volume_creation.fail_other\u0027)"},{"line_number":435,"context_line":"            raise"},{"line_number":436,"context_line":""},{"line_number":437,"context_line":"    return lock_file"},{"line_number":438,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_b3bdbf69","line":435,"range":{"start_line":433,"start_character":8,"end_line":435,"end_character":17},"in_reply_to":"3fa7e38b_3a677028","updated":"2019-10-05 02:31:18.000000000","message":"Done","commit_id":"3623c48bc7ed6532395acac2e028d3752d3172b6"},{"author":{"_account_id":25251,"name":"Alexandre Lécuyer","email":"alexandre.lecuyer@corp.ovh.com","username":"alecuyer"},"change_message_id":"b137fcd6f9a239b2ff4c1ec28d861a6940e5f587","unresolved":false,"context_lines":[{"line_number":430,"context_line":""},{"line_number":431,"context_line":"        try:"},{"line_number":432,"context_line":"            fcntl.flock(lock_file, fcntl.LOCK_EX | fcntl.LOCK_NB)"},{"line_number":433,"context_line":"        except IOError:"},{"line_number":434,"context_line":"            increment(logger, \u0027vfile.volume_creation.fail_other\u0027)"},{"line_number":435,"context_line":"            raise"},{"line_number":436,"context_line":""},{"line_number":437,"context_line":"    return lock_file"},{"line_number":438,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_3a677028","line":435,"range":{"start_line":433,"start_character":8,"end_line":435,"end_character":17},"in_reply_to":"3fa7e38b_439a92c5","updated":"2019-10-04 16:03:08.000000000","message":"you\u0027re right, I\u0027ll add it","commit_id":"3623c48bc7ed6532395acac2e028d3752d3172b6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"24dad0c4d89c42b5390b84890283774bf3524e8b","unresolved":false,"context_lines":[{"line_number":477,"context_line":"        else:"},{"line_number":478,"context_line":"            raise"},{"line_number":479,"context_line":""},{"line_number":480,"context_line":"    # lock the volume creation lock file"},{"line_number":481,"context_line":"    creation_lock_path \u003d os.path.join(volume_dir, VCREATION_LOCK_NAME)"},{"line_number":482,"context_line":"    with open(creation_lock_path, \u0027w\u0027) as creation_lock_file:"},{"line_number":483,"context_line":"        # this may block"}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_03f25a07","line":480,"updated":"2019-10-03 23:34:15.000000000","message":"Should we be using _create_new_lock_file here? It looks almost identical... except I think it may need to return next_lock_path as well?","commit_id":"3623c48bc7ed6532395acac2e028d3752d3172b6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e18a19a2fba1459d063909af3be8955745694890","unresolved":false,"context_lines":[{"line_number":477,"context_line":"        else:"},{"line_number":478,"context_line":"            raise"},{"line_number":479,"context_line":""},{"line_number":480,"context_line":"    # lock the volume creation lock file"},{"line_number":481,"context_line":"    creation_lock_path \u003d os.path.join(volume_dir, VCREATION_LOCK_NAME)"},{"line_number":482,"context_line":"    with open(creation_lock_path, \u0027w\u0027) as creation_lock_file:"},{"line_number":483,"context_line":"        # this may block"}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_73b74788","line":480,"in_reply_to":"3fa7e38b_03f25a07","updated":"2019-10-05 02:31:18.000000000","message":"Done -- also needed index","commit_id":"3623c48bc7ed6532395acac2e028d3752d3172b6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"24dad0c4d89c42b5390b84890283774bf3524e8b","unresolved":false,"context_lines":[{"line_number":506,"context_line":"    # create the volume"},{"line_number":507,"context_line":"    next_volume_name \u003d get_volume_name(index)"},{"line_number":508,"context_line":"    next_volume_path \u003d os.path.join(volume_dir, next_volume_name)"},{"line_number":509,"context_line":"    volume_file \u003d os.open(next_volume_path,"},{"line_number":510,"context_line":"                          os.O_CREAT | os.O_EXCL | os.O_WRONLY, 0o600)"},{"line_number":511,"context_line":""},{"line_number":512,"context_line":"    vol_header \u003d VolumeHeader()"}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_2012ecb2","line":509,"range":{"start_line":509,"start_character":18,"end_line":509,"end_character":25},"updated":"2019-10-03 23:34:15.000000000","message":"This could also blow up, yeah? Should we close lock_file and unlink next_lock_path?","commit_id":"3623c48bc7ed6532395acac2e028d3752d3172b6"},{"author":{"_account_id":25251,"name":"Alexandre Lécuyer","email":"alexandre.lecuyer@corp.ovh.com","username":"alecuyer"},"change_message_id":"b137fcd6f9a239b2ff4c1ec28d861a6940e5f587","unresolved":false,"context_lines":[{"line_number":506,"context_line":"    # create the volume"},{"line_number":507,"context_line":"    next_volume_name \u003d get_volume_name(index)"},{"line_number":508,"context_line":"    next_volume_path \u003d os.path.join(volume_dir, next_volume_name)"},{"line_number":509,"context_line":"    volume_file \u003d os.open(next_volume_path,"},{"line_number":510,"context_line":"                          os.O_CREAT | os.O_EXCL | os.O_WRONLY, 0o600)"},{"line_number":511,"context_line":""},{"line_number":512,"context_line":"    vol_header \u003d VolumeHeader()"}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_d0cabb9f","line":509,"range":{"start_line":509,"start_character":18,"end_line":509,"end_character":25},"in_reply_to":"3fa7e38b_2012ecb2","updated":"2019-10-04 16:03:08.000000000","message":"Yes! I think I would move this open() in the try block below with the rest of the \"IO\" operations","commit_id":"3623c48bc7ed6532395acac2e028d3752d3172b6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e18a19a2fba1459d063909af3be8955745694890","unresolved":false,"context_lines":[{"line_number":506,"context_line":"    # create the volume"},{"line_number":507,"context_line":"    next_volume_name \u003d get_volume_name(index)"},{"line_number":508,"context_line":"    next_volume_path \u003d os.path.join(volume_dir, next_volume_name)"},{"line_number":509,"context_line":"    volume_file \u003d os.open(next_volume_path,"},{"line_number":510,"context_line":"                          os.O_CREAT | os.O_EXCL | os.O_WRONLY, 0o600)"},{"line_number":511,"context_line":""},{"line_number":512,"context_line":"    vol_header \u003d VolumeHeader()"}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_93ba036c","line":509,"range":{"start_line":509,"start_character":18,"end_line":509,"end_character":25},"in_reply_to":"3fa7e38b_d0cabb9f","updated":"2019-10-05 02:31:18.000000000","message":"Done","commit_id":"3623c48bc7ed6532395acac2e028d3752d3172b6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"24dad0c4d89c42b5390b84890283774bf3524e8b","unresolved":false,"context_lines":[{"line_number":533,"context_line":"        # If the uploader is slow to send data to the object server, a crash"},{"line_number":534,"context_line":"        # may occur before the object is received and a call to fsync() is"},{"line_number":535,"context_line":"        # issued. We end up with volumes without a header."},{"line_number":536,"context_line":"        # Issue a fsync() here, at the cost of performance early on, until"},{"line_number":537,"context_line":"        # volumes have been created for all partitions."},{"line_number":538,"context_line":"        fsync(volume_file)"},{"line_number":539,"context_line":"        fsync_dir(volume_dir)"},{"line_number":540,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_2060ac32","line":537,"range":{"start_line":536,"start_character":69,"end_line":537,"end_character":54},"updated":"2019-10-03 23:34:15.000000000","message":"I\u0027m not sure where this part comes from. How will we know when we\u0027ve created volumes for all partitions?","commit_id":"3623c48bc7ed6532395acac2e028d3752d3172b6"},{"author":{"_account_id":25251,"name":"Alexandre Lécuyer","email":"alexandre.lecuyer@corp.ovh.com","username":"alecuyer"},"change_message_id":"b137fcd6f9a239b2ff4c1ec28d861a6940e5f587","unresolved":false,"context_lines":[{"line_number":533,"context_line":"        # If the uploader is slow to send data to the object server, a crash"},{"line_number":534,"context_line":"        # may occur before the object is received and a call to fsync() is"},{"line_number":535,"context_line":"        # issued. We end up with volumes without a header."},{"line_number":536,"context_line":"        # Issue a fsync() here, at the cost of performance early on, until"},{"line_number":537,"context_line":"        # volumes have been created for all partitions."},{"line_number":538,"context_line":"        fsync(volume_file)"},{"line_number":539,"context_line":"        fsync_dir(volume_dir)"},{"line_number":540,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_30ed4f25","line":537,"range":{"start_line":536,"start_character":69,"end_line":537,"end_character":54},"in_reply_to":"3fa7e38b_2060ac32","updated":"2019-10-04 16:03:08.000000000","message":"OK this is badly worded. You cannot know that you have created \"all\" volumes.\nWhat I\u0027m trying to say is that because new volume creation plateaus rather quickly when you add a new object-server, the performance impact of the fsync() there is not an issue. \n\n(Unless you run a short benchmark where you\u0027ll be disappointed if you create a single object per partition/volume and hit this path each time)","commit_id":"3623c48bc7ed6532395acac2e028d3752d3172b6"}],"swift/obj/vfile_utils.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"24dad0c4d89c42b5390b84890283774bf3524e8b","unresolved":false,"context_lines":[{"line_number":33,"context_line":"    Exceptions are part of the interface, subclass IOError to make it easier"},{"line_number":34,"context_line":"    to interface with diskfile.py"},{"line_number":35,"context_line":"    \"\"\""},{"line_number":36,"context_line":"    def __init__(self, *args, **kwargs):"},{"line_number":37,"context_line":"        super(VIOError, self).__init__(*args, **kwargs)"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"class VOSError(OSError):"}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_03b57aee","line":37,"range":{"start_line":36,"start_character":4,"end_line":37,"end_character":55},"updated":"2019-10-03 23:34:15.000000000","message":"I think we can drop this and just have the docstring, yeah?","commit_id":"3623c48bc7ed6532395acac2e028d3752d3172b6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e18a19a2fba1459d063909af3be8955745694890","unresolved":false,"context_lines":[{"line_number":33,"context_line":"    Exceptions are part of the interface, subclass IOError to make it easier"},{"line_number":34,"context_line":"    to interface with diskfile.py"},{"line_number":35,"context_line":"    \"\"\""},{"line_number":36,"context_line":"    def __init__(self, *args, **kwargs):"},{"line_number":37,"context_line":"        super(VIOError, self).__init__(*args, **kwargs)"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"class VOSError(OSError):"}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_33b1cf90","line":37,"range":{"start_line":36,"start_character":4,"end_line":37,"end_character":55},"in_reply_to":"3fa7e38b_03b57aee","updated":"2019-10-05 02:31:18.000000000","message":"Done","commit_id":"3623c48bc7ed6532395acac2e028d3752d3172b6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"24dad0c4d89c42b5390b84890283774bf3524e8b","unresolved":false,"context_lines":[{"line_number":37,"context_line":"        super(VIOError, self).__init__(*args, **kwargs)"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"class VOSError(OSError):"},{"line_number":41,"context_line":"    \"\"\""},{"line_number":42,"context_line":"    Exceptions are part of the interface, subclass OSError to make it easier"},{"line_number":43,"context_line":"    to interface with diskfile.py"}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_83c88a74","line":40,"updated":"2019-10-03 23:34:15.000000000","message":"In light of the IOError/OSError thing you spotted on py3, I wonder if we should just have one subclass on py3... *shrug*","commit_id":"3623c48bc7ed6532395acac2e028d3752d3172b6"}],"test/unit/obj/test_vfile.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"223810409a3116a83519199a3737991802bcdfa1","unresolved":false,"context_lines":[{"line_number":1070,"context_line":"        m_os_open.reset_mock()"},{"line_number":1071,"context_line":"        m_flock.reset_mock()"},{"line_number":1072,"context_line":"        m_os_close.reset_mock()"},{"line_number":1073,"context_line":"        m_flock.side_effect \u003d OSError(13, \"Permission denied\")"},{"line_number":1074,"context_line":"        self.assertRaises(OSError, vfile.open_volume, volume_path)"},{"line_number":1075,"context_line":"        m_os_open.assert_called_once_with(expected_lock_path, os.O_WRONLY)"},{"line_number":1076,"context_line":"        m_flock.assert_called_once_with(m_lock_file, fcntl.LOCK_EX |"}],"source_content_type":"text/x-python","patch_set":6,"id":"7faddb67_cc0ff585","line":1073,"updated":"2019-07-17 18:38:52.000000000","message":"Well this is interesting. On py3, this follows the IOError path :-/\n\n $ for p in python2 python3; do $p -c \u0027import errno; print(isinstance(OSError(errno.EACCES, \"message\"), IOError))\u0027; done\n False\n True\n\nHow often do we need to distinguish IOErrors from OSErrors?","commit_id":"f71a172cc13e47ba92ece841042b574ebc6b0515"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e2a4d191113311e4ce83bc6c4b5176759e00a933","unresolved":false,"context_lines":[{"line_number":1074,"context_line":"                                        fcntl.LOCK_NB)"},{"line_number":1075,"context_line":"        m_os_close.assert_called_once_with(m_lock_file)"},{"line_number":1076,"context_line":""},{"line_number":1077,"context_line":"        # Same test with an OSError"},{"line_number":1078,"context_line":"        m_os_open.reset_mock()"},{"line_number":1079,"context_line":"        m_flock.reset_mock()"},{"line_number":1080,"context_line":"        m_os_close.reset_mock()"},{"line_number":1081,"context_line":"        m_flock.side_effect \u003d OSError(13, \"Permission denied\")"},{"line_number":1082,"context_line":"        self.assertRaises(OSError, vfile.open_volume, volume_path)"},{"line_number":1083,"context_line":"        m_os_open.assert_called_once_with(expected_lock_path, os.O_WRONLY)"},{"line_number":1084,"context_line":"        m_flock.assert_called_once_with(m_lock_file, fcntl.LOCK_EX |"},{"line_number":1085,"context_line":"                                        fcntl.LOCK_NB)"},{"line_number":1086,"context_line":"        m_os_close.assert_called_once_with(m_lock_file)"},{"line_number":1087,"context_line":""},{"line_number":1088,"context_line":"    def test_get_lock_file_name(self):"},{"line_number":1089,"context_line":"        name \u003d vfile.get_lock_file_name(1)"}],"source_content_type":"text/x-python","patch_set":9,"id":"3fa7e38b_b24e9535","line":1086,"range":{"start_line":1077,"start_character":8,"end_line":1086,"end_character":55},"updated":"2019-09-27 04:05:27.000000000","message":"Fixed the str/bytes issue, but this is still going to bomb out. (Er, fail to bomb out -- the assertRaises fails.)\n\nWhat path was this exercising? In practice, is it really so different from the EACCESS case in lines 1042-1052? What does the actual fcntl module raise in various situations?\n\nWould test this be better with some other OSError, or raising an IOError/OSError from the open()?","commit_id":"96853029255c6adf38b726e93d85562db36f5d5f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c51374313c7227ee2b97305d954ac5401d6843cc","unresolved":false,"context_lines":[{"line_number":1074,"context_line":"                                        fcntl.LOCK_NB)"},{"line_number":1075,"context_line":"        m_os_close.assert_called_once_with(m_lock_file)"},{"line_number":1076,"context_line":""},{"line_number":1077,"context_line":"        # Same test with an OSError"},{"line_number":1078,"context_line":"        m_os_open.reset_mock()"},{"line_number":1079,"context_line":"        m_flock.reset_mock()"},{"line_number":1080,"context_line":"        m_os_close.reset_mock()"},{"line_number":1081,"context_line":"        m_flock.side_effect \u003d OSError(13, \"Permission denied\")"},{"line_number":1082,"context_line":"        self.assertRaises(OSError, vfile.open_volume, volume_path)"},{"line_number":1083,"context_line":"        m_os_open.assert_called_once_with(expected_lock_path, os.O_WRONLY)"},{"line_number":1084,"context_line":"        m_flock.assert_called_once_with(m_lock_file, fcntl.LOCK_EX |"},{"line_number":1085,"context_line":"                                        fcntl.LOCK_NB)"},{"line_number":1086,"context_line":"        m_os_close.assert_called_once_with(m_lock_file)"},{"line_number":1087,"context_line":""},{"line_number":1088,"context_line":"    def test_get_lock_file_name(self):"},{"line_number":1089,"context_line":"        name \u003d vfile.get_lock_file_name(1)"}],"source_content_type":"text/x-python","patch_set":9,"id":"3fa7e38b_0b172ca6","line":1086,"range":{"start_line":1077,"start_character":8,"end_line":1086,"end_character":55},"in_reply_to":"3fa7e38b_744d663c","updated":"2019-09-27 15:56:10.000000000","message":"\u003e should we catch (OSError, IOError) to be safe if the behavior ever changes?\n\nYeah, that sounds like a good plan to me.","commit_id":"96853029255c6adf38b726e93d85562db36f5d5f"},{"author":{"_account_id":25251,"name":"Alexandre Lécuyer","email":"alexandre.lecuyer@corp.ovh.com","username":"alecuyer"},"change_message_id":"1939feedd0bd64a14494a9455664c71ba4eecddf","unresolved":false,"context_lines":[{"line_number":1074,"context_line":"                                        fcntl.LOCK_NB)"},{"line_number":1075,"context_line":"        m_os_close.assert_called_once_with(m_lock_file)"},{"line_number":1076,"context_line":""},{"line_number":1077,"context_line":"        # Same test with an OSError"},{"line_number":1078,"context_line":"        m_os_open.reset_mock()"},{"line_number":1079,"context_line":"        m_flock.reset_mock()"},{"line_number":1080,"context_line":"        m_os_close.reset_mock()"},{"line_number":1081,"context_line":"        m_flock.side_effect \u003d OSError(13, \"Permission denied\")"},{"line_number":1082,"context_line":"        self.assertRaises(OSError, vfile.open_volume, volume_path)"},{"line_number":1083,"context_line":"        m_os_open.assert_called_once_with(expected_lock_path, os.O_WRONLY)"},{"line_number":1084,"context_line":"        m_flock.assert_called_once_with(m_lock_file, fcntl.LOCK_EX |"},{"line_number":1085,"context_line":"                                        fcntl.LOCK_NB)"},{"line_number":1086,"context_line":"        m_os_close.assert_called_once_with(m_lock_file)"},{"line_number":1087,"context_line":""},{"line_number":1088,"context_line":"    def test_get_lock_file_name(self):"},{"line_number":1089,"context_line":"        name \u003d vfile.get_lock_file_name(1)"}],"source_content_type":"text/x-python","patch_set":9,"id":"3fa7e38b_744d663c","line":1086,"range":{"start_line":1077,"start_character":8,"end_line":1086,"end_character":55},"in_reply_to":"3fa7e38b_b24e9535","updated":"2019-09-27 09:53:53.000000000","message":"Indeed that test looks redundant. We only care about the errno value and EACCES is already tested.\n\nA test for the failure to open the lock file as you suggest would be better.\n\nAs for the fcntl module: py2 raises an IOError on failures.\nthe fcntl module doc for py3 says:\n\n\"Changed in version 3.3: Operations in this module used to raise an IOError where they now raise an OSError.\"\n\nWhich is a little misleading. It raises a \"BlockingIOError\", which is a subclass of OSError/IOError.\n\nSo in practice, catching IOError is still fine with py3. But, since what we really care about is errno, should we catch (OSError, IOError) to be safe if the behavior ever changes? If so it should also be done in common/utils.py:lock_file() where there\u0027s the same situation. Let me know you what you think is best for this case, and I\u0027ll update the patch","commit_id":"96853029255c6adf38b726e93d85562db36f5d5f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"24dad0c4d89c42b5390b84890283774bf3524e8b","unresolved":false,"context_lines":[{"line_number":841,"context_line":"        try:"},{"line_number":842,"context_line":"            vfile.create_writable_volume(socket_path, partition, extension,"},{"line_number":843,"context_line":"                                         volume_dir, conf, logger)"},{"line_number":844,"context_line":"        except IOError:"},{"line_number":845,"context_line":"            pass"},{"line_number":846,"context_line":""},{"line_number":847,"context_line":"        try:"},{"line_number":848,"context_line":"            # how to assert close() arguments ?"}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_60cb041e","line":845,"range":{"start_line":844,"start_character":8,"end_line":845,"end_character":16},"updated":"2019-10-03 23:34:15.000000000","message":"I\u0027m guessing we want a\n\n with self.assertRaises(IOError):\n\ninstead?","commit_id":"3623c48bc7ed6532395acac2e028d3752d3172b6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e18a19a2fba1459d063909af3be8955745694890","unresolved":false,"context_lines":[{"line_number":841,"context_line":"        try:"},{"line_number":842,"context_line":"            vfile.create_writable_volume(socket_path, partition, extension,"},{"line_number":843,"context_line":"                                         volume_dir, conf, logger)"},{"line_number":844,"context_line":"        except IOError:"},{"line_number":845,"context_line":"            pass"},{"line_number":846,"context_line":""},{"line_number":847,"context_line":"        try:"},{"line_number":848,"context_line":"            # how to assert close() arguments ?"}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_53ac8b34","line":845,"range":{"start_line":844,"start_character":8,"end_line":845,"end_character":16},"in_reply_to":"3fa7e38b_30646fb9","updated":"2019-10-05 02:31:18.000000000","message":"Done","commit_id":"3623c48bc7ed6532395acac2e028d3752d3172b6"},{"author":{"_account_id":25251,"name":"Alexandre Lécuyer","email":"alexandre.lecuyer@corp.ovh.com","username":"alecuyer"},"change_message_id":"b137fcd6f9a239b2ff4c1ec28d861a6940e5f587","unresolved":false,"context_lines":[{"line_number":841,"context_line":"        try:"},{"line_number":842,"context_line":"            vfile.create_writable_volume(socket_path, partition, extension,"},{"line_number":843,"context_line":"                                         volume_dir, conf, logger)"},{"line_number":844,"context_line":"        except IOError:"},{"line_number":845,"context_line":"            pass"},{"line_number":846,"context_line":""},{"line_number":847,"context_line":"        try:"},{"line_number":848,"context_line":"            # how to assert close() arguments ?"}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_30646fb9","line":845,"range":{"start_line":844,"start_character":8,"end_line":845,"end_character":16},"in_reply_to":"3fa7e38b_60cb041e","updated":"2019-10-04 16:03:08.000000000","message":"Yes, I\u0027ll change it","commit_id":"3623c48bc7ed6532395acac2e028d3752d3172b6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"24dad0c4d89c42b5390b84890283774bf3524e8b","unresolved":false,"context_lines":[{"line_number":850,"context_line":"            # check that the volume and its lock file have been removed"},{"line_number":851,"context_line":"            self.assertEqual(os.listdir(tempdir), [\u0027volume_creation.lock\u0027])"},{"line_number":852,"context_line":"            m_register_volume.assert_not_called()"},{"line_number":853,"context_line":"        finally:"},{"line_number":854,"context_line":"            shutil.rmtree(tempdir)"},{"line_number":855,"context_line":""},{"line_number":856,"context_line":"    @mock.patch(\"swift.obj.vfile.get_next_volume_index\")"},{"line_number":857,"context_line":"    @mock.patch(\"swift.obj.vfile.rpc.list_volumes\")"}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_009ed006","line":854,"range":{"start_line":853,"start_character":8,"end_line":854,"end_character":34},"updated":"2019-10-03 23:34:15.000000000","message":"test.unit has a @with_tempdir decorator you might appreciate...\n\nOTOH, with some many mock.patch()es already, maybe you wouldn\u0027t ;-)","commit_id":"3623c48bc7ed6532395acac2e028d3752d3172b6"},{"author":{"_account_id":25251,"name":"Alexandre Lécuyer","email":"alexandre.lecuyer@corp.ovh.com","username":"alecuyer"},"change_message_id":"b137fcd6f9a239b2ff4c1ec28d861a6940e5f587","unresolved":false,"context_lines":[{"line_number":850,"context_line":"            # check that the volume and its lock file have been removed"},{"line_number":851,"context_line":"            self.assertEqual(os.listdir(tempdir), [\u0027volume_creation.lock\u0027])"},{"line_number":852,"context_line":"            m_register_volume.assert_not_called()"},{"line_number":853,"context_line":"        finally:"},{"line_number":854,"context_line":"            shutil.rmtree(tempdir)"},{"line_number":855,"context_line":""},{"line_number":856,"context_line":"    @mock.patch(\"swift.obj.vfile.get_next_volume_index\")"},{"line_number":857,"context_line":"    @mock.patch(\"swift.obj.vfile.rpc.list_volumes\")"}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_f05d77e9","line":854,"range":{"start_line":853,"start_character":8,"end_line":854,"end_character":34},"in_reply_to":"3fa7e38b_009ed006","updated":"2019-10-04 16:03:08.000000000","message":"Will take a look thanks! I discovered a few things when writing these but I\u0027m sure I have a lot more to find :)","commit_id":"3623c48bc7ed6532395acac2e028d3752d3172b6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"24dad0c4d89c42b5390b84890283774bf3524e8b","unresolved":false,"context_lines":[{"line_number":1075,"context_line":"        def fake_os_open(path, flags, mode\u003dNone):"},{"line_number":1076,"context_line":"            if path \u003d\u003d \"/path/to/volumes/v0000001\":"},{"line_number":1077,"context_line":"                return 123"},{"line_number":1078,"context_line":"            if not flags \u003d\u003d (os.O_CREAT | os.O_EXCL | os.O_WRONLY):"},{"line_number":1079,"context_line":"                raise OSError(errno.ENOENT,"},{"line_number":1080,"context_line":"                              \"No such file or directory: {}\".format(path))"},{"line_number":1081,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_809160f4","line":1078,"range":{"start_line":1078,"start_character":15,"end_line":1078,"end_character":27},"updated":"2019-10-03 23:34:15.000000000","message":"nit: flags !\u003d","commit_id":"3623c48bc7ed6532395acac2e028d3752d3172b6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e18a19a2fba1459d063909af3be8955745694890","unresolved":false,"context_lines":[{"line_number":1075,"context_line":"        def fake_os_open(path, flags, mode\u003dNone):"},{"line_number":1076,"context_line":"            if path \u003d\u003d \"/path/to/volumes/v0000001\":"},{"line_number":1077,"context_line":"                return 123"},{"line_number":1078,"context_line":"            if not flags \u003d\u003d (os.O_CREAT | os.O_EXCL | os.O_WRONLY):"},{"line_number":1079,"context_line":"                raise OSError(errno.ENOENT,"},{"line_number":1080,"context_line":"                              \"No such file or directory: {}\".format(path))"},{"line_number":1081,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_f3aa5717","line":1078,"range":{"start_line":1078,"start_character":15,"end_line":1078,"end_character":27},"in_reply_to":"3fa7e38b_70698789","updated":"2019-10-05 02:31:18.000000000","message":"Done","commit_id":"3623c48bc7ed6532395acac2e028d3752d3172b6"},{"author":{"_account_id":25251,"name":"Alexandre Lécuyer","email":"alexandre.lecuyer@corp.ovh.com","username":"alecuyer"},"change_message_id":"b137fcd6f9a239b2ff4c1ec28d861a6940e5f587","unresolved":false,"context_lines":[{"line_number":1075,"context_line":"        def fake_os_open(path, flags, mode\u003dNone):"},{"line_number":1076,"context_line":"            if path \u003d\u003d \"/path/to/volumes/v0000001\":"},{"line_number":1077,"context_line":"                return 123"},{"line_number":1078,"context_line":"            if not flags \u003d\u003d (os.O_CREAT | os.O_EXCL | os.O_WRONLY):"},{"line_number":1079,"context_line":"                raise OSError(errno.ENOENT,"},{"line_number":1080,"context_line":"                              \"No such file or directory: {}\".format(path))"},{"line_number":1081,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_70698789","line":1078,"range":{"start_line":1078,"start_character":15,"end_line":1078,"end_character":27},"in_reply_to":"3fa7e38b_809160f4","updated":"2019-10-04 16:03:08.000000000","message":"will fix","commit_id":"3623c48bc7ed6532395acac2e028d3752d3172b6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"24dad0c4d89c42b5390b84890283774bf3524e8b","unresolved":false,"context_lines":[{"line_number":1105,"context_line":"            if not flags \u003d\u003d (os.O_CREAT | os.O_EXCL | os.O_WRONLY):"},{"line_number":1106,"context_line":"                raise OSError(errno.EPERM, \"Permission denied\")"},{"line_number":1107,"context_line":"            else:"},{"line_number":1108,"context_line":"                return 456"},{"line_number":1109,"context_line":""},{"line_number":1110,"context_line":"        volume_path \u003d \"/path/to/volumes/v0000001\""},{"line_number":1111,"context_line":"        expected_lock_path \u003d \"/path/to/volumes/v0000001.writelock\""}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_e07294e3","line":1108,"range":{"start_line":1108,"start_character":16,"end_line":1108,"end_character":26},"updated":"2019-10-03 23:34:15.000000000","message":"I don\u0027t think this ever gets called...","commit_id":"3623c48bc7ed6532395acac2e028d3752d3172b6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e18a19a2fba1459d063909af3be8955745694890","unresolved":false,"context_lines":[{"line_number":1105,"context_line":"            if not flags \u003d\u003d (os.O_CREAT | os.O_EXCL | os.O_WRONLY):"},{"line_number":1106,"context_line":"                raise OSError(errno.EPERM, \"Permission denied\")"},{"line_number":1107,"context_line":"            else:"},{"line_number":1108,"context_line":"                return 456"},{"line_number":1109,"context_line":""},{"line_number":1110,"context_line":"        volume_path \u003d \"/path/to/volumes/v0000001\""},{"line_number":1111,"context_line":"        expected_lock_path \u003d \"/path/to/volumes/v0000001.writelock\""}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_13a61355","line":1108,"range":{"start_line":1108,"start_character":16,"end_line":1108,"end_character":26},"in_reply_to":"3fa7e38b_d0263b69","updated":"2019-10-05 02:31:18.000000000","message":"Done","commit_id":"3623c48bc7ed6532395acac2e028d3752d3172b6"},{"author":{"_account_id":25251,"name":"Alexandre Lécuyer","email":"alexandre.lecuyer@corp.ovh.com","username":"alecuyer"},"change_message_id":"b137fcd6f9a239b2ff4c1ec28d861a6940e5f587","unresolved":false,"context_lines":[{"line_number":1105,"context_line":"            if not flags \u003d\u003d (os.O_CREAT | os.O_EXCL | os.O_WRONLY):"},{"line_number":1106,"context_line":"                raise OSError(errno.EPERM, \"Permission denied\")"},{"line_number":1107,"context_line":"            else:"},{"line_number":1108,"context_line":"                return 456"},{"line_number":1109,"context_line":""},{"line_number":1110,"context_line":"        volume_path \u003d \"/path/to/volumes/v0000001\""},{"line_number":1111,"context_line":"        expected_lock_path \u003d \"/path/to/volumes/v0000001.writelock\""}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_d0263b69","line":1108,"range":{"start_line":1108,"start_character":16,"end_line":1108,"end_character":26},"in_reply_to":"3fa7e38b_e07294e3","updated":"2019-10-04 16:03:08.000000000","message":"copy pasted fake_os_open() from another test, will remove this bit","commit_id":"3623c48bc7ed6532395acac2e028d3752d3172b6"}]}
