#define _GNU_SOURCE #include #include #include #include #include #include #include typedef struct _processInfo { char *fname; int64_t filesize; } processInfo; processInfo pinfo[1024]; int pnum; static char ** makeCommandQemuNbd(bool sync, char *key_encrypted_qcow2, char *fileName) { int num = 0; int pos = 0; char **ret; if (key_encrypted_qcow2) { num = 6 + (sync ? 1 : 0); ret = (char **)malloc(sizeof(*ret) * num); ret[pos++] = (char *)"qemu-nbd"; // 0 ret[pos++] = (char *)"--object"; // 1 asprintf (&ret[pos++], "secret,id=sec0,data=%s", key_encrypted_qcow2); ret[pos++] = (char *)"--image-opts"; // 3 asprintf (&ret[pos++], "driver=qcow2,encrypt.format=luks,encrypt.key-secret=sec0,file.filename=%s", fileName); if (sync) ret[pos++] = (char *)"--cache=writethrough"; // 5 ret[pos++] = NULL; // 5 or 6 } else { num = 5 + (sync ? 1 : 0); ret = (char **)malloc(sizeof(*ret) * num); ret[pos++] = (char *)"qemu-nbd"; // 0 ret[pos++] = (char *)"-f"; // 1 ret[pos++] = (char *)"qcow2"; // 2 ret[pos++] = fileName; // 3 if (sync) ret[pos++] = (char *)"--cache=writethrough"; // 4 ret[pos++] = NULL; // 4 or 5 } return ret; } void sigHandler(int num) { // do nothing } #define TEST_NORMAL 0 struct nbd_handle * openNbd(processInfo *pi, bool isWritethrough) { struct nbd_handle *nbd; fprintf(stderr, "Before nbd_create\n"); nbd = nbd_create (); if (nbd == NULL) { fprintf(stderr, "nbd_create failed. %s\n", nbd_get_error ()); return nbd; } #if TEST_NORMAL // not encrypted file char **args = makeCommandQemuNbd(isWritethrough, (char*)NULL, (char *)"/tmp/my.qcow2"); #else char **args = makeCommandQemuNbd(isWritethrough, (char*)"abc123", pi->fname); #endif fprintf(stderr, "Before nbd_connect_systemd_socket_activation\n"); int ret = nbd_connect_systemd_socket_activation (nbd, args); free(args); if (ret == -1) { fprintf(stderr, "nbd_connect_systemd_socket_activation failed. %s\n", nbd_get_error ()); return nbd; } fprintf(stderr, "After nbd_connect_systemd_socket_activation\n"); pi->filesize = nbd_get_size(nbd); fprintf(stderr, "size=%ld\n", pi->filesize); return nbd; } int main(int argc, char *argv[]) { pnum = 0; pinfo[0].fname = (char*)"/tmp/empty.qcow2"; signal(SIGUSR1, sigHandler); pid_t pid; if ((pid = fork()) == 0) { struct nbd_handle *nbd = openNbd(pinfo, false); if (nbd) { nbd_shutdown (nbd, 0); nbd_close (nbd); } } else { uint64_t i; for (i = 0; i < 10000000; i++) { kill(pid, SIGUSR1); } fprintf(stderr, "kill end\n"); } }