[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-API] [PATCH] CA-32077 Gracefully handle missing /etc/xensource-inventory file



# HG changeset patch
# User Thomas Sanders <thomas.sanders@xxxxxxxxxx>
# Date 1286306824 -3600
# Node ID 3e9d27f796957dff0942ad3b12b54036356669a2
# Parent  8095e7b9208492ce7584f2a0ba61209afc4479db
CA-32077 Gracefully handle missing /etc/xensource-inventory file

xapi was failing nastily on start-up if the xensource-inventory file was
missing.  Now it generates a minimal one if none exists. This does not include
a build number, so version.ml now falls back to using a build number from the
Make environment if one is not available from the inventory, i.e. it falls
back to the behaviour from before Matthias's commit for CA-43574 (build number
from xensource-inventory).

Signed-off-by: Thomas Sanders <thomas.sanders@xxxxxxxxxx>

diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -107,11 +107,11 @@ import-v6:
 version:
        echo "(* This file is autogenerated.  Grep for 
e17512ce-ba7c-11df-887b-0026b9799147 (random uuid) to see where it comes from. 
;o) *)" > ocaml/util/version.ml
        echo "let hg_id = \"$(shell hg id | sed -r 's/(.+)\s.*/\1/g')\"" >> 
ocaml/util/version.ml
-       echo "let hostname = \"$(shell hostname)\"" >> ocaml/util/version.ml
-       echo "let date = \"$(shell date -u +%Y-%m-%d)\"" >> 
ocaml/util/version.ml
+       echo "let hostname = \"$(shell hostname)\""                     >> 
ocaml/util/version.ml
+       echo "let date = \"$(shell date -u +%Y-%m-%d)\""        >> 
ocaml/util/version.ml
        echo "let product_version = \"$(PRODUCT_VERSION)\"" >> 
ocaml/util/version.ml
-       echo "let product_brand = \"$(PRODUCT_BRAND)\"" >> ocaml/util/version.ml
-       echo "let build_number = Util_inventory.lookup \"BUILD_NUMBER\" (* 
\"$(BUILD_NUMBER)\" *)" >> ocaml/util/version.ml
+       echo "let product_brand = \"$(PRODUCT_BRAND)\""         >> 
ocaml/util/version.ml
+       echo "let build_number = Util_inventory.lookup 
~default:\"$(BUILD_NUMBER)\" \"BUILD_NUMBER\"" >> ocaml/util/version.ml
  
  .PHONY: clean
  clean:
diff --git a/ocaml/util/util_inventory.ml b/ocaml/util/util_inventory.ml
--- a/ocaml/util/util_inventory.ml
+++ b/ocaml/util/util_inventory.ml
@@ -1,5 +1,5 @@
 (*
- * Copyright (C) 2006-2009 Citrix Systems Inc.
+ * Copyright (C) 2006-2010 Citrix Systems Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published
@@ -20,10 +20,33 @@ open Threadext
 module D = Debug.Debugger(struct let name="xapi" end)
 open D
 
+let inventory_filename = Util_globs_inventory.inventory_filename
+
+(* Keys which must exist: *)
+let _installation_uuid         = "INSTALLATION_UUID"
+let _control_domain_uuid       = "CONTROL_DOMAIN_UUID"
+let _management_interface      = "MANAGEMENT_INTERFACE"
+
+(* Optional keys: *)
+let _current_interfaces                = "CURRENT_INTERFACES"
+let _oem_manufacturer          = "OEM_MANUFACTURER"
+let _oem_model                         = "OEM_MODEL"
+let _oem_build_number          = "OEM_BUILD_NUMBER"
+let _machine_serial_number     = "MACHINE_SERIAL_NUMBER"
+let _machine_serial_name       = "MACHINE_SERIAL_NAME"
+
 let loaded_inventory = ref false
 let inventory = Hashtbl.create 10
 let inventory_m = Mutex.create ()
 
+(* Compute the minimum necessary inventory file contents *)
+let minimum_default_entries () = 
+  let host_uuid = Uuid.string_of_uuid (Uuid.make_uuid ()) in
+  let dom0_uuid = Uuid.string_of_uuid (Uuid.make_uuid ()) in
+  [ _installation_uuid, host_uuid;
+    _control_domain_uuid, dom0_uuid;
+    _management_interface, "" ]
+
 (* trim any quotes off the ends *)
 let strip_quotes v =
        if String.length v >= 2
@@ -39,7 +62,17 @@ let parse_inventory_entry line =
                        Some (k, strip_quotes ++ String.strip String.isspace $ 
v)
                | _ -> None
 
+let string_of_table h = 
+       let lines = List.fold_left (fun acc (k, v) ->
+               Printf.sprintf "%s='%s'\n" k v :: acc) [] h in
+       String.concat "" lines
+
 let read_inventory_contents () =
+       if not (Sys.file_exists inventory_filename) then begin
+               warn "%s does not exist: generating a minimal one" 
inventory_filename;
+               Unixext.write_string_to_file inventory_filename (
+                       string_of_table (minimum_default_entries ()))
+       end;
        (* Perhaps we should blank the old inventory before we read the new one?
           What is the desired behaviour? *)
        Unixext.file_lines_iter (fun line ->
@@ -47,7 +80,7 @@ let read_inventory_contents () =
                        | Some (k, v) -> Hashtbl.add inventory k v
                        | None -> warn
                                "Failed to parse line from xensource-inventory 
file: %s" line)
-               Util_globs_inventory.inventory_filename;
+               inventory_filename;
        loaded_inventory := true
 
 let read_inventory () = Mutex.execute inventory_m read_inventory_contents
@@ -57,18 +90,19 @@ let reread_inventory () = Mutex.execute 
 
 exception Missing_inventory_key of string
 
-let lookup key =
-       if not (!loaded_inventory) then read_inventory();
-       if not (Hashtbl.mem inventory key)
-       then raise (Missing_inventory_key key);
-       Hashtbl.find inventory key
+let lookup ?default key =
+       (if not (!loaded_inventory) then read_inventory());
+       if (Hashtbl.mem inventory key)
+       then
+               Hashtbl.find inventory key
+       else
+               match default with
+                       | None   -> raise (Missing_inventory_key key)
+                       | Some v -> v
 
 let flush_to_disk_locked () =
-       let lines = Hashtbl.fold
-               (fun k v acc -> Printf.sprintf "%s='%s'\n" k v :: acc)
-               inventory [] in
-       Unixext.write_string_to_file Util_globs_inventory.inventory_filename
-               $ String.concat "" lines
+       let h = Hashtbl.fold (fun k v acc -> (k, v) :: acc) inventory [] in
+       Unixext.write_string_to_file inventory_filename (string_of_table h)
 
 let update key value = Mutex.execute inventory_m (fun () ->
        Hashtbl.clear inventory;
@@ -81,25 +115,3 @@ let remove key = Mutex.execute inventory
        read_inventory_contents ();
        Hashtbl.remove inventory key;
        flush_to_disk_locked ())
-
-let _product_brand = "PRODUCT_BRAND"
-let _product_name = "PRODUCT_NAME"
-let _product_version = "PRODUCT_VERSION='0.5.1'"
-let _build_number = "BUILD_NUMBER"
-let _kernel_version = "KERNEL_VERSION"
-let _xen_version = "XEN_VERSION"
-let _installation_date = "INSTALLATION_DATE"
-let _default_sr = "DEFAULT_SR"
-let _primary_disk = "PRIMARY_DISK"
-let _backup_partition = "BACKUP_PARTITION"
-let _installation_uuid = "INSTALLATION_UUID"
-let _default_sr_physdevs = "DEFAULT_SR_PHYSDEVS"
-let _control_domain_uuid = "CONTROL_DOMAIN_UUID"
-let _management_interface = "MANAGEMENT_INTERFACE"
-let _current_interfaces = "CURRENT_INTERFACES"
-let _dom0_mem = "DOM0_MEM"
-let _oem_manufacturer = "OEM_MANUFACTURER"
-let _oem_model = "OEM_MODEL"
-let _oem_build_number = "OEM_BUILD_NUMBER"
-let _machine_serial_number = "MACHINE_SERIAL_NUMBER"
-let _machine_serial_name = "MACHINE_SERIAL_NAME"
diff --git a/ocaml/util/util_inventory.mli b/ocaml/util/util_inventory.mli
--- a/ocaml/util/util_inventory.mli
+++ b/ocaml/util/util_inventory.mli
@@ -1,5 +1,5 @@
 (*
- * Copyright (C) 2006-2009 Citrix Systems Inc.
+ * Copyright (C) 2006-2010 Citrix Systems Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published
@@ -25,9 +25,9 @@ val read_inventory: unit -> unit
 (** Clears the copy of the inventory file in memory and reads the file from 
disk. *)
 val reread_inventory: unit -> unit
 
-(** Return the value of key [key] in the inventory file. Throws 
{!Missing_inventory_key}
- *  if the key does not exist. *)
-val lookup: string -> string
+(** Return the value of key [key] in the inventory file. If the key does not 
exist,
+ *  returns the default if supplied, or throws {!Missing_inventory_key} 
otherwise. *)
+val lookup: ?default:string -> string -> string
 
 (** Remove the key with the given name from the inventory file, if it exists. 
*)
 val remove: string -> unit
@@ -40,6 +40,9 @@ val update: string -> string -> unit
 val parse_inventory_entry: string -> (string * string) option
 
 (* Keys defined in Geneva *)
+(** UUID of the Host object in the xapi database *)
+val _installation_uuid : string
+(*
 (** Brand name, such as "XenServer" *)
 val _product_brand : string
 
@@ -70,15 +73,12 @@ val _primary_disk : string
 (** Device path of backup partition *)
 val _backup_partition : string
 
-(** UUID of the Host object in the xapi database *)
-val _installation_uuid : string
-
 (** Device path of the default SR used for local storage *)
 val _default_sr_physdevs : string
 
 (** Memory size of dom0 (?) *)
 val _dom0_mem : string
-
+*)
 
 (* Keys defined in Rio *)
 (** UUID of the control domain (dom0) *)

Attachment: xen-api.hg.patch
Description: Text Data

_______________________________________________
xen-api mailing list
xen-api@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/mailman/listinfo/xen-api

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.