/* Field names for SYS_UPDATE. */
#define SYS_UPD_SRC_ENDPT m1_i1 /* source endpoint */
#define SYS_UPD_DST_ENDPT m1_i2 /* destination endpoint */
+#define SYS_UPD_FLAGS m1_i3 /* update flags */
+# define SYS_UPD_ROLLBACK 0x1 /* update is rollback */
+
/* Subfunctions for SYS_STATECTL */
#define SYS_STATE_CLEAR_IPC_REFS 1 /* clear IPC references */
typedef struct {
endpoint_t src;
endpoint_t dst;
- uint8_t padding[48];
+ int flags;
+ uint8_t padding[44];
} mess_lsys_vm_update;
_ASSERT_MSG_SIZE(mess_lsys_vm_update);
#define sys_resume(proc_ep) sys_runctl(proc_ep, RC_RESUME, 0)
int sys_runctl(endpoint_t proc_ep, int action, int flags);
-int sys_update(endpoint_t src_ep, endpoint_t dst_ep);
+int sys_update(endpoint_t src_ep, endpoint_t dst_ep, int flags);
int sys_statectl(int request, void* address, int length);
int sys_privctl(endpoint_t proc_ep, int req, void *p);
int sys_privquery_mem(endpoint_t proc_ep, phys_bytes physstart,
int vm_notify_sig(endpoint_t ep, endpoint_t ipc_ep);
int vm_set_priv(endpoint_t ep, void *buf, int sys_proc);
-int vm_update(endpoint_t src_e, endpoint_t dst_e);
+int vm_update(endpoint_t src_e, endpoint_t dst_e, int flags);
int vm_memctl(endpoint_t ep, int req);
int vm_query_exit(endpoint_t *endpt);
int vm_watch_exit(endpoint_t ep);
* The parameters for this kernel call are:
* m2_i1: SYS_UPD_SRC_ENDPT (source process endpoint)
* m2_i2: SYS_UPD_DST_ENDPT (destination process endpoint)
+ * m2_i3: SYS_UPD_FLAGS (update flags)
*/
#include "kernel/system.h"
endpoint_t old_endpoint;
int priv_flags;
int init_flags;
+ int sys_upd_flags = 0;
/* Get information about self. */
r = sys_whoami(&sef_self_endpoint, sef_self_name, SEF_SELF_NAME_MAXLEN,
#if USE_LIVEUPDATE
/* RS may wake up with the wrong endpoint, perfom the update in that case. */
if((sef_self_priv_flags & ROOT_SYS_PROC) && sef_self_endpoint != RS_PROC_NR) {
- r = vm_update(RS_PROC_NR, sef_self_endpoint);
+ r = vm_update(RS_PROC_NR, sef_self_endpoint, sys_upd_flags);
if(r != OK) {
panic("unable to update RS from instance %d to %d: %d",
RS_PROC_NR, sef_self_endpoint, r);
#include "syslib.h"
-int sys_update(endpoint_t src_ep, endpoint_t dst_ep)
+int sys_update(endpoint_t src_ep, endpoint_t dst_ep, int flags)
{
message m;
m.SYS_UPD_SRC_ENDPT = src_ep;
m.SYS_UPD_DST_ENDPT = dst_ep;
+ m.SYS_UPD_FLAGS = flags;
return _kernel_call(SYS_UPDATE, &m);
}
#include <string.h>
int
-vm_update(endpoint_t src_e, endpoint_t dst_e)
+vm_update(endpoint_t src_e, endpoint_t dst_e, int flags)
{
message m;
memset(&m, 0, sizeof(m));
m.m_lsys_vm_update.src = src_e;
m.m_lsys_vm_update.dst = dst_e;
+ m.m_lsys_vm_update.flags = flags;
return _taskcall(VM_PROC_NR, VM_RS_UPDATE, &m);
}
int srv_update(endpoint_t src_e, endpoint_t dst_e)
{
int r;
+ int sys_upd_flags = 0;
/* Ask VM to swap the slots of the two processes and tell the kernel to
* do the same. If VM is the service being updated, only perform the kernel
* initialization time.
*/
if(src_e != VM_PROC_NR) {
- r = vm_update(src_e, dst_e);
+ r = vm_update(src_e, dst_e, sys_upd_flags);
}
else {
- r = sys_update(src_e, dst_e);
+ r = sys_update(src_e, dst_e, sys_upd_flags);
}
return r;
#include <minix/syslib.h>
#include <minix/safecopies.h>
#include <minix/bitmap.h>
+#include <minix/rs.h>
#include <errno.h>
#include <string.h>
endpoint_t src_e, dst_e, reply_e;
int src_p, dst_p;
struct vmproc *src_vmp, *dst_vmp;
- int r;
+ int r, sys_upd_flags;
src_e = m_ptr->m_lsys_vm_update.src;
dst_e = m_ptr->m_lsys_vm_update.dst;
+ sys_upd_flags = m_ptr->m_lsys_vm_update.flags;
/* Lookup slots for source and destination process. */
if(vm_isokendpt(src_e, &src_p) != OK) {
dst_vmp = &vmproc[dst_p];
/* Let the kernel do the update first. */
- r = sys_update(src_e, dst_e);
+ r = sys_update(src_e, dst_e,
+ sys_upd_flags & SF_VM_ROLLBACK ? SYS_UPD_ROLLBACK : 0);
if(r != OK) {
return r;
}