Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

CA124008, HFX-1226: Report out-of-space, not patch-invalid #1821

Closed
wants to merge 1 commit into from

3 participants

@kaifengz

Merge pull request #1678 from thomassa/ca124008-patch-upload-enospc
Report out-of-space, not patch-invalid(cherry picked from commit 4d40bcb)

@johnelse johnelse Merge pull request #1678 from thomassa/ca124008-patch-upload-enospc
Report out-of-space, not patch-invalid(cherry picked from commit 4d40bcb)
ec69d72
@thomassa
Owner

Thank you for re-doing pullreq #1820 here, but this still isn't quite what we want. You have cherry-picked the commit that merged #1678 into the master branch, rather than cherry-picking the set of seven commits that are contained in #1678.

As I wrote on #1820,

Normally we do this sort of thing by using the git cherry-pick -x command on the set of commits that made up the original pull-request. That way we also get the history and original commit-messages.

You might find Jerome's pull-request duplicator tool useful:
https://github.com/xenserver/PRDup
https://github.com/jeromemaloberti/PRDup

@kaifengz

Created a new pull request #1848 as replacement; close this one.

@kaifengz kaifengz closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 9, 2014
  1. @johnelse @kaifengz

    Merge pull request #1678 from thomassa/ca124008-patch-upload-enospc

    johnelse authored kaifengz committed
    Report out-of-space, not patch-invalid(cherry picked from commit 4d40bcb)
This page is out of date. Refresh to see the latest.
Showing with 67 additions and 33 deletions.
  1. +67 −33 ocaml/xapi/xapi_pool_patch.ml
View
100 ocaml/xapi/xapi_pool_patch.ml
@@ -207,7 +207,11 @@ let read_in_and_check_patch length s path =
let run_path = extract_patch path in
Unixext.unlink_safe run_path
- with exn ->
+ with
+ | Unix.Unix_error (errno, _, _) when errno = Unix.ENOSPC ->
+ warn "Not enough space on filesystem to upload patch.";
+ raise (Api_errors.Server_error (Api_errors.out_of_space, [patch_dir]))
+ | exn ->
debug "Caught exception while checking signature: %s" (ExnHelper.string_of_exn exn);
Unixext.unlink_safe path;
raise (Api_errors.Server_error(Api_errors.invalid_patch, []))
@@ -235,6 +239,25 @@ let create_patch_record ~__context ?path patch_info =
exception CannotUploadPatchToSlave
+(* Experiments showed that we need about twice the amount of free
+ space on the filesystem as the size of the patch, which is where
+ the multiplier comes from. *)
+let assert_space_available ?(multiplier=2L) patch_size =
+ let open Unixext in
+ ignore (Unixext.mkdir_safe patch_dir 0o755);
+ let stat = statvfs patch_dir in
+ let free_bytes =
+ (* block size times free blocks *)
+ Int64.mul stat.f_frsize stat.f_bavail in
+ let really_required = Int64.mul multiplier patch_size in
+ if really_required > free_bytes
+ then
+ begin
+ warn "Not enough space on filesystem to upload patch. Required %Ld, \
+ but only %Ld available" really_required free_bytes;
+ raise (Api_errors.Server_error (Api_errors.out_of_space, [patch_dir]))
+ end
+
let pool_patch_upload_handler (req: Request.t) s _ =
debug "Patch Upload Handler - Entered...";
@@ -256,7 +279,11 @@ let pool_patch_upload_handler (req: Request.t) s _ =
debug "Patch Upload Handler - Sending headers...";
Http_svr.headers s (Http.http_200_ok ());
-
+
+ (match req.Request.content_length with
+ | None -> ()
+ | Some size -> assert_space_available size);
+
read_in_and_check_patch req.Request.content_length s new_path;
try
@@ -465,40 +492,47 @@ let pool_patch_download_handler (req: Request.t) s _ =
let get_patch_to_local ~__context ~self =
if not (Pool_role.is_master ()) then
begin
+ let length = Db.Pool_patch.get_size ~__context ~self in
+ assert_space_available length;
let path = Db.Pool_patch.get_filename ~__context ~self in
let pool_secret = !Xapi_globs.pool_secret in
let uuid = Db.Pool_patch.get_uuid ~__context ~self in
- Server_helpers.exec_with_new_task ~task_in_database:true ~subtask_of:(Context.get_task_id __context)
- ~session_id:(Context.get_session_id __context) (Printf.sprintf "Get patch %s from master" uuid)
- (fun __context ->
- let task = Context.get_task_id __context in
- let uri = Printf.sprintf "%s?pool_secret=%s&uuid=%s&task_id=%s"
- Constants.pool_patch_download_uri pool_secret uuid (Ref.string_of task) in
- let request = Xapi_http.http_request ~version:"1.1"
- Http.Get uri in
- let length = Some (Db.Pool_patch.get_size ~__context ~self) in
- let master_address = Pool_role.get_master_address () in
- let open Xmlrpc_client in
- let transport = SSL(SSL.make ~use_stunnel_cache:true ~task_id:(Ref.string_of task) (), master_address, !Xapi_globs.https_port) in
- try
- with_transport transport
- (with_http request
- (fun (response, fd) ->
- let _ = Unixext.mkdir_safe patch_dir 0o755 in
- read_in_and_check_patch length fd path
- )
- )
- with _ ->
- begin
- let error = Db.Task.get_error_info ~__context ~self:task in
- if List.length error > 0
- then
- begin
- debug "Error %s fetching patch from master." (List.hd error);
- raise (Api_errors.Server_error (List.hd error, List.tl error))
- end
- else raise (Api_errors.Server_error (Api_errors.cannot_fetch_patch, [uuid]))
- end)
+ Server_helpers.exec_with_new_task
+ ~task_in_database:true ~subtask_of:(Context.get_task_id __context)
+ ~session_id:(Context.get_session_id __context)
+ (Printf.sprintf "Get patch %s from master" uuid)
+
+ (fun __context ->
+ let task = Context.get_task_id __context in
+ let uri = Printf.sprintf "%s?pool_secret=%s&uuid=%s&task_id=%s"
+ Constants.pool_patch_download_uri
+ pool_secret uuid (Ref.string_of task) in
+ let request = Xapi_http.http_request ~version:"1.1" Http.Get uri in
+ let master_address = Pool_role.get_master_address () in
+ let open Xmlrpc_client in
+ let transport = SSL(SSL.make ~use_stunnel_cache:true
+ ~task_id:(Ref.string_of task) (),
+ master_address, !Xapi_globs.https_port) in
+
+ try
+ with_transport transport
+ (with_http request
+ (fun (response, fd) ->
+ let _ = Unixext.mkdir_safe patch_dir 0o755 in
+ read_in_and_check_patch (Some length) fd path))
+
+ with _ ->
+ begin
+ let error = Db.Task.get_error_info ~__context ~self:task in
+ if List.length error > 0
+ then
+ begin
+ debug "Error %s fetching patch from master." (List.hd error);
+ raise (Api_errors.Server_error (List.hd error, List.tl error))
+ end
+ else raise (Api_errors.Server_error
+ (Api_errors.cannot_fetch_patch, [uuid]))
+ end)
end
open Db_filter
Something went wrong with that request. Please try again.