Skip to content

Commit

Permalink
Refactor memcr-client code to create libmemcrclient.so licensed as LG…
Browse files Browse the repository at this point in the history
…PL2.1
  • Loading branch information
meecash committed Feb 6, 2025
1 parent b58f2b8 commit ea8ef65
Show file tree
Hide file tree
Showing 9 changed files with 778 additions and 103 deletions.
25 changes: 25 additions & 0 deletions COPYING
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,28 @@ General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.

================================================================================

memcrclient_proto.h and libmemcrclient shared libarary are licensed by
Global Service B.V. under the GNU Lesser General Public License version 2.1
only, as per COPYING.LGPL2.1.

Please use the following copyright for source for libmemcrlient shared library
source code:

Copyright (C) <YEAR> <NAME>

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, see <https://www.gnu.org/licenses/>.

501 changes: 501 additions & 0 deletions COPYING.LGPL2.1

Large diffs are not rendered by default.

18 changes: 15 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ GOFF = ./gen-offsets.sh
B ?= .


all: $(B)/memcr $(B)/memcr-client
all: $(B)/memcr $(B)/memcr-client ${B}/libmemcrclient.so

ifeq ($(ENCRYPT), 1)
all: $(B)/libencrypt.so
Expand Down Expand Up @@ -150,11 +150,23 @@ $(B)/memcr: $(B)/memcr.o $(B)/cpu.o $(B)/enter.o
@stat -c "-> %n: %s bytes <-" $@
@size $@

${B}/libmemcrclient.o: libmemcrclient.c
$(CC) $(CFLAGS) -fPIC -c $< -o $@

${B}/libmemcrclient.a: ${B}/libmemcrclient.o
ar rcs $@ $^
@stat -c "-> %n: %s bytes <-" $@
@size $@

${B}/libmemcrclient.so: ${B}/libmemcrclient.o
$(CC) $(CFLAGS) -shared -Wl,-soname,$(@F) $^ -o $@
@stat -c "-> %n: %s bytes <-" $@
@size $@

$(B)/memcr-client.o: memcr-client.c
$(CC) $(CFLAGS) -DGIT_VERSION='"$(GIT_VERSION)"' -I$(B) -c $< -o $@

$(B)/memcr-client: $(B)/memcr-client.o
$(B)/memcr-client: $(B)/memcr-client.o ${B}/libmemcrclient.a
$(CC) $(CFLAGS) $^ -o $@
@stat -c "-> %n: %s bytes <-" $@
@size $@
Expand All @@ -175,7 +187,7 @@ endif


clean:
rm -f $(B)/*.o $(B)/*.s $(B)/*.bin $(B)/parasite-blob.h $(B)/memcr $(B)/memcr-client $(B)/libencrypt.so
rm -f $(B)/*.o $(B)/*.s $(B)/*.bin $(B)/parasite-blob.h $(B)/memcr $(B)/memcr-client $(B)/*.so ${B}/*.a
$(MAKE) -C tests clean


Expand Down
135 changes: 135 additions & 0 deletions libmemcrclient.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
* Copyright 2023 Comcast Cable Communications Management, LLC
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <https://www.gnu.org/licenses/>.
*
*/

#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>
#include <getopt.h>
#include <stdlib.h>

#include "memcrclient_proto.h"
#include "libmemcrclient.h"

static int xconnect(struct sockaddr *addr, socklen_t addrlen)
{
int cd, ret;

cd = socket(addr->sa_family, SOCK_STREAM, 0);
if (cd < 0) {
fprintf(stderr, "socket() failed: %m\n");
return -1;
}

ret = connect(cd, addr, addrlen);
if (ret < 0) {
fprintf(stderr, "connect() failed: %m\n");
close(cd);
return ret;
}

return cd;
}

static int connect_unix(const char *path)
{
struct sockaddr_un addr = {
.sun_family = AF_UNIX,
};

snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", path);

return xconnect((struct sockaddr *)&addr, sizeof(addr));
}

static int connect_tcp(int port)
{
struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_addr.s_addr = inet_addr("127.0.0.1"),
.sin_port = htons(port),
};

return xconnect((struct sockaddr *)&addr, sizeof(addr));
}

static int send_cmd(int cd, struct service_command cmd)
{
int ret;
struct service_response resp = {0};

ret = write(cd, &cmd, sizeof(struct service_command));
if (ret != sizeof(struct service_command)) {
fprintf(stderr, "%s() write request failed: ret %d, errno %m\n", __func__, ret);
return -1;
}

ret = read(cd, &resp, sizeof(struct service_response));
if (ret != sizeof(struct service_response)) {
fprintf(stderr, "%s() read response failed: ret %d, errno %m\n", __func__, ret);
return -1;
}

fprintf(stdout, "Procedure finished with %s status.\n", MEMCR_OK == resp.resp_code ? "OK" : "ERROR");

return resp.resp_code;
}


int memcr_client_connect(const char* comm_location)
{
int cd;
int port = atoi(comm_location);

if (port > 0)
cd = connect_tcp(port);
else
cd = connect_unix(comm_location);

if (cd < 0) {
fprintf(stderr, "Connection creation failed!\n");
}
return cd;
}

void memcr_client_disconnect(const int cd)
{
close(cd);
}

int memcr_client_checkpoint(const int cd, const unsigned int pid)
{
struct service_command cmd = {0};

cmd.cmd = MEMCR_CHECKPOINT;
cmd.pid = pid;

return send_cmd(cd, cmd);
}

int memcr_client_restore(const int cd, const unsigned int pid)
{
struct service_command cmd = {0};

cmd.cmd = MEMCR_RESTORE;
cmd.pid = pid;

return send_cmd(cd, cmd);
}
54 changes: 54 additions & 0 deletions libmemcrclient.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright 2023 Comcast Cable Communications Management, LLC
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <https://www.gnu.org/licenses/>.
*
*/

#ifndef __MEMCR_CLIENT_LIB_H__
#define __MEMCR_CLIENT_LIB_H__

/* open connection to memcr daemon
* params:
* comm_location - string containing the TCP socket port, or path to UNIX domain socket file
* result:
* connection descryptor
*/
int memcr_client_connect(const char* comm_location);

/* close connection to memcr daemon
* params:
* cd - connection descriptor returned by memcr_client_connect
*/
void memcr_client_disconnect(const int cd);

/* suspend process
* params:
* cd - connection descriptor returned by memcr_client_connect
* pid - pid of process to suspend
* result:
* 0 on success, <0 on error
*/
int memcr_client_checkpoint(const int cd, const unsigned int pid);

/* restore process
* params:
* cd - connection descriptor returned by memcr_client_connect
* pid - pid of process to suspend
* result:
* 0 on success, <0 on error
*/
int memcr_client_restore(const int cd, const unsigned int pid);

#endif /* __MEMCR_CLIENT_LIB_H__ */
85 changes: 5 additions & 80 deletions memcr-client.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,70 +26,7 @@
#include <stdlib.h>

#include "memcr.h"

static int xconnect(struct sockaddr *addr, socklen_t addrlen)
{
int cd, ret;

cd = socket(addr->sa_family, SOCK_STREAM, 0);
if (cd < 0) {
fprintf(stderr, "socket() failed: %m\n");
return -1;
}

ret = connect(cd, addr, addrlen);
if (ret < 0) {
fprintf(stderr, "connect() failed: %m\n");
close(cd);
return ret;
}

return cd;
}

static int connect_unix(const char *path)
{
struct sockaddr_un addr = {
.sun_family = AF_UNIX,
};

snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", path);

return xconnect((struct sockaddr *)&addr, sizeof(addr));
}

static int connect_tcp(int port)
{
struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_addr.s_addr = inet_addr("127.0.0.1"),
.sin_port = htons(port),
};

return xconnect((struct sockaddr *)&addr, sizeof(addr));
}

static int send_cmd(int cd, struct service_command cmd)
{
int ret;
struct service_response resp = {0};

ret = write(cd, &cmd, sizeof(struct service_command));
if (ret != sizeof(struct service_command)) {
fprintf(stderr, "%s() write request failed: ret %d, errno %m\n", __func__, ret);
return -1;
}

ret = read(cd, &resp, sizeof(struct service_response));
if (ret != sizeof(struct service_response)) {
fprintf(stderr, "%s() read response failed: ret %d, errno %m\n", __func__, ret);
return -1;
}

fprintf(stdout, "Procedure finished with %s status.\n", MEMCR_OK == resp.resp_code ? "OK" : "ERROR");

return resp.resp_code;
}
#include "libmemcrclient.h"

static void print_version(void)
{
Expand Down Expand Up @@ -117,9 +54,7 @@ int main(int argc, char *argv[])
int ret, cd, opt;
int checkpoint = 0;
int restore = 0;
int port = -1;
int option_index;
struct service_command cmd = {0};
char *comm_location = NULL;
int pid = 0;

Expand Down Expand Up @@ -171,12 +106,7 @@ int main(int argc, char *argv[])
return -1;
}

port = atoi(comm_location);

if (port > 0)
cd = connect_tcp(port);
else
cd = connect_unix(comm_location);
cd = memcr_client_connect(comm_location);

if (cd < 0) {
fprintf(stderr, "Connection creation failed!\n");
Expand All @@ -185,21 +115,16 @@ int main(int argc, char *argv[])

if (checkpoint) {
fprintf(stdout, "Will checkpoint %d.\n", pid);
cmd.cmd = MEMCR_CHECKPOINT;
cmd.pid = pid;
ret = send_cmd(cd, cmd);
ret = memcr_client_checkpoint(cd, pid);
}

if (restore) {
fprintf(stdout, "Will restore %d.\n", pid);
cmd.cmd = MEMCR_RESTORE;
cmd.pid = pid;
ret = send_cmd(cd, cmd);
ret = memcr_client_restore(cd, pid);
}

fprintf(stdout, "Command executed, exiting.\n");
close(cd);
memcr_client_disconnect(cd);

return ret;
}

1 change: 1 addition & 0 deletions memcr.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
#endif

#include "memcr.h"
#include "memcrclient_proto.h"
#include "arch/cpu.h"
#include "arch/enter.h"
#include "parasite-blob.h"
Expand Down
Loading

0 comments on commit ea8ef65

Please sign in to comment.