summaryrefslogtreecommitdiffstats
path: root/code-update/ubi-code-update.md
blob: 1845b941b80a65d922f38828e6b840e278fdc399 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
OpenBMC UBI Code Update
==============

Two BMC Code Updates layouts are available:

 * Static, non-UBI layout - The default code update

 * UBI layout - enabled via `obmc-ubi-fs` distro feature

This document describes the UBI code update. The non-UBI code update can be
found here: [code-update.md](code-update.md)

### Steps to Update

The following are the steps to update the BMC if the UBI layout is enabled.

1. Get a UBI BMC image tar:
After building OpenBMC, you will end up with a set of image files in
`tmp/deploy/images/<platform>/`. `obmc-phosphor-image-<platform>.ubi.mtd.tar` is
the UBI BMC tar image. The UBI BMC tar image contains 5 files: u-boot,
kernel, ro, and rw partitions and the MANIFEST file, which contains information
about the image such as the image purpose and version. A MANIFEST file might
look like
```
purpose=xyz.openbmc_project.Software.Version.VersionPurpose.BMC
version=v1.99.10
```

2. Transfer the generated UBI BMC image to the BMC via one of the following
methods:
  * Method 1: Via scp: Copy the generated UBI BMC image to the `/tmp/images/`
    directory on the BMC.
  * Method 2: Via REST Upload:
  https://github.com/openbmc/docs/blob/master/rest-api.md#uploading-images
  * Method 3: Via TFTP: Perform a POST request to call the `DownloadViaTFTP`
    method of `/xyz/openbmc_project/software`.

3. Note the version id generated for that image file. The version id is a hash
value of 8 hexadecimal numbers, generated by SHA-512 hashing the version
string contained in the image and taking the first 8 characters. Get the
version id via one of the following methods:

  * Method 1: From the BMC command line, note the most recent directory name
    created under `/tmp/images/`, in this example it'd be `2a1022fe`:

      ```
      # ls -l /tmp/images/
      total 0
      drwx------    2 root     root            80 Aug 22 07:54 2a1022fe
      drwx------    2 root     root            80 Aug 22 07:53 488449a2
      ```

  * Method 2: This method *only* works if there are no `Ready` images at the
    start of transferring the image. Using the REST API, note the object that
    has its Activation property set to Ready, in this example it'd be `2a1022fe`:

      ```
      $ curl -b cjar -k https://${bmc}/xyz/openbmc_project/software/enumerate
      {
        "data": {
          "/xyz/openbmc_project/software/2a1022fe": {
            "Activation": "xyz.openbmc_project.Software.Activation.Activations.Ready",
      ```

 * Method 3: Calculate the version id beforehand from the image with:

      ```
      tar xfO <UBI BMC tar image> MANIFEST | sed -ne '/version=/ {s/version=//;p}' | head -n1 | tr -d '\n' | sha512sum | cut -b 1-8
      ```


4. To initiate the update, set the `RequestedActivation` property of the desired
image to `Active`, substitute ``<id>`` with the hash value noted on the previous
step, this will write the contents of the image to a UBI volume in the BMC chip
via one of the following methods:

  * Method 1: From the BMC command line:

      ```
      busctl set-property xyz.openbmc_project.Software.BMC.Updater \
        /xyz/openbmc_project/software/<id> \
        xyz.openbmc_project.Software.Activation RequestedActivation s \
        xyz.openbmc_project.Software.Activation.RequestedActivations.Active

      ```

  * Method 2: Using the REST API:

      ```
      curl -b cjar -k -H "Content-Type: application/json" -X PUT \
        -d '{"data":
        "xyz.openbmc_project.Software.Activation.RequestedActivations.Active"}' \
        https://${bmc}/xyz/openbmc_project/software/<id>/attr/RequestedActivation
      ```

5. (Optional) Check the flash progress. This interface is only available during
the activation progress and is not present once the activation is completed
via one of the following:

  * Method 1: From the BMC command line:

      ```
      busctl get-property xyz.openbmc_project.Software.BMC.Updater  \
        /xyz/openbmc_project/software/<id> \
        xyz.openbmc_project.Software.ActivationProgress Progress
      ```

  * Method 2: Using the REST API:

      ```
      curl -b cjar -k https://${bmc}/xyz/openbmc_project/software/<id>/attr/Progress
      ```

6. Check that the activation is complete by verifying the "Activation" property
is set to "Active" via one of the following methods:

  * Method 1: From the BMC command line:

      ```
      busctl get-property xyz.openbmc_project.Software.BMC.Updater \
        /xyz/openbmc_project/software/<id> \
        xyz.openbmc_project.Software.Activation Activation
      ```

  * Method 2: Using the REST API:

      ```
      curl -b cjar -k https://${bmc}/xyz/openbmc_project/software/<id>
      ```

7. Reboot the BMC for the image to take effect.

  * Method 1: From the BMC command line:

      ```
      reboot
      ```

  * Method 2: Using the REST API:

      ```
      curl -c cjar -b cjar -k -H "Content-Type: application/json" -X PUT \
          -d '{"data": "xyz.openbmc_project.State.BMC.Transition.Reboot"}' \
          https://${bmc}/xyz/openbmc_project/state/bmc0/attr/RequestedBMCTransition
      ```

### Associations

In addition to all software images, several associations are listed at
`/xyz/openbmc_project/software/`:

```
curl -c cjar -b cjar -k -H "Content-Type: application/json" -X GET  \
    https://${bmc}/xyz/openbmc_project/software/
{
  "data": [
    "/xyz/openbmc_project/software/46e65782",
    "/xyz/openbmc_project/software/493a00ad",
    "/xyz/openbmc_project/software/88c153b1",
    "/xyz/openbmc_project/software/active",
    "/xyz/openbmc_project/software/functional"
  ],
  "message": "200 OK",
  "status": "ok"
}
```

1. A "functional" association to the "running" BMC and host images

There is only one functional association per BMC and one functional association per host.
The functional/running BMC image is the BMC image with the lowest priority when
rebooting the BMC. The functional image does not update until the BMC is rebooted.
The functional host image behaves the same way except that it updates on a
power on or reboot of the host.

```
curl -c cjar -b cjar -k -H "Content-Type: application/json" -X GET \
    https://${bmc}/xyz/openbmc_project/software/functional
{
  "data": {
    "endpoints": [
      "/xyz/openbmc_project/software/46e65782",
      "/xyz/openbmc_project/software/493a00ad"
    ]
  },
  "message": "200 OK",
  "status": "ok"
}
```

2. An "active" association to the active BMC and host images

Note: Several BMC images might be active, this is true for the host images
as well.

```
curl -c cjar -b cjar -k -H "Content-Type: application/json" -X GET \
    https://${bmc}/xyz/openbmc_project/software/active
{
  "data": {
    "endpoints": [
      "/xyz/openbmc_project/software/46e65782",
      "/xyz/openbmc_project/software/493a00ad",
      "/xyz/openbmc_project/software/88c153b1"
    ]
  },
  "message": "200 OK",
  "status": "ok"
}
```

An additional association is located at `/xyz/openbmc_project/software/<id>/inventory`
for "associating" a software image with an inventory item.

```
curl -c cjar -b cjar -k -H "Content-Type: application/json" -X GET \
   https://${bmc}/xyz/openbmc_project/software/493a00ad/inventory
{
  "data": {
    "endpoints": [
      "/xyz/openbmc_project/inventory/system/chassis/motherboard/boxelder/bmc"
    ]
  },
  "message": "200 OK",
  "status": "ok"
}
```

To get all software images associated with an inventory item:

```
curl -c cjar -b cjar -k -H "Content-Type: application/json" -X GET  \
    https://${bmc}/xyz/openbmc_project/inventory/system/chassis/activation
{
  "data": {
    "endpoints": [
      "/xyz/openbmc_project/software/46e65782"
    ]
  },
  "message": "200 OK",
  "status": "ok"
}
```

### MANIFEST File

A file named "MANIFEST" must be included in any image tar uploaded, downloaded
via TFTP, or copied to the BMC.

The MANIFEST file format must be key=value (e.g. version=v1.99.10).
It should include the following fields:

* version - The version of the image
* purpose - The image's purpose (e.g.
xyz.openbmc_project.Software.Version.VersionPurpose.BMC or
xyz.openbmc_project.Software.Version.VersionPurpose.Host). Accepted purpose
values can be found at
[Version interface](https://github.com/openbmc/phosphor-dbus-interfaces/blob/6f69ae5b33ee224358cb4c2061f4ad44c6b36d70/xyz/openbmc_project/Software/Version.interface.yaml)
under "VersionPurpose" values.

Other optional fields are:
* extended_version - A more detailed version, which could include versions of
different components in the image.

### Deleting an Image

To delete an image:

```
curl -c cjar -b cjar -k -H "Content-Type: application/json" \
    -X POST https://${bmc}/xyz/openbmc_project/software/<$id>/action/delete \
    -d "{\"data\": [] }"
```

Note: The image must be non-functional ("non-running").

To delete all non-functional images, whether BMC or host images:

```
curl -c cjar -b cjar -k -H "Content-Type: application/json" \
    -X POST https://${bmc}/xyz/openbmc_project/software/action/deleteAll \
    -d "{\"data\": [] }"
```

### Software Field Mode

Field mode is meant for systems shipped from manufacturing to a customer.
Field mode offers a way to provide security and ensure incorrect patches don't
get loaded on the system by accident. The software implementation of the field
mode interface disables patching of the BMC by not mounting `/usr/local`, which
in turn disables host patching at `/usr/local/share/pnor/`.
Enabling field mode is intended to be a one-way operation which means that once
enabled, there is no REST API provided to disable it.

Field mode can be enabled by running the following command:

```
curl -b cjar -k -H 'Content-Type: application/json' -X PUT -d '{"data":1}'  \
    https://${bmc}/xyz/openbmc_project/software/attr/FieldModeEnabled

```

Although field mode is meant to be a one-way operation, it can be disabled
by a user with admin privileges by running the following commands on the BMC:

```
fw_setenv fieldmode

systemctl unmask usr-local.mount

reboot
```

More information on field mode can be found here:
https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/xyz/openbmc_project/Control/FieldMode.interface.yaml

### Software Factory Reset

Software factory reset resets the BMC and host firmware to its factory state
by clearing out any read/write data.
To software factory reset run the following command and then reboot the BMC:

```
curl -b cjar -k -H 'Content-Type: application/json' -X POST -d '{"data":[]}' \
    https://${bmc}/xyz/openbmc_project/software/action/Reset

```

The factory reset on the BMC side will clear `/var`, `/home`, and `/etc`.
On the host side, the factory reset will clear the read/write volume for each
host image on the system, clear the shared preserve host volume, pnor-prsv, and
clear any host patches located in `/usr/local/share/pnor/`.

The factory reset interface can be found here:
https://github.com/openbmc/phosphor-dbus-interfaces/blob/02b39246d45ea029a1652a49cc20eab7723dd63b/xyz/openbmc_project/Common/FactoryReset.interface.yaml

### Image Storage Location

When a BMC image is activated (i.e. when "RequestedActivation" is set to "Active"),
UBI volumes are created on the BMC chip for the image. The alternate BMC chip
can also be used to store images. This is determined by "BMC_RO_MTD". Using both
the alternate BMC chip and the BMC chip allows for multiple BMC images to be
stored. By default, only the BMC chip is used. To use both, set "BMC_RO_MTD" to
"alt-bmc+bmc".

### Implementation

More information about the implementation of the UBI code update can be found at
https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/xyz/openbmc_project/Software
and https://github.com/openbmc/phosphor-bmc-code-mgmt
OpenPOWER on IntegriCloud