Exemple #1
0
char *
virSystemdGetMachineNameByPID(pid_t pid)
{
    DBusConnection *conn;
    DBusMessage *reply = NULL;
    char *name = NULL, *object = NULL;

    if (virSystemdHasMachined() < 0)
        goto cleanup;

    if (!(conn = virDBusGetSystemBus()))
        goto cleanup;

    if (virDBusCallMethod(conn, &reply, NULL,
                          "org.freedesktop.machine1",
                          "/org/freedesktop/machine1",
                          "org.freedesktop.machine1.Manager",
                          "GetMachineByPID",
                          "u", pid) < 0)
        goto cleanup;

    if (virDBusMessageDecode(reply, "o", &object) < 0)
        goto cleanup;

    virDBusMessageUnref(reply);
    reply = NULL;

    VIR_DEBUG("Domain with pid %lld has object path '%s'",
              (long long) pid, object);

    if (virDBusCallMethod(conn, &reply, NULL,
                          "org.freedesktop.machine1",
                          object,
                          "org.freedesktop.DBus.Properties",
                          "Get",
                          "ss",
                          "org.freedesktop.machine1.Machine",
                          "Name") < 0)
        goto cleanup;

    if (virDBusMessageDecode(reply, "v", "s", &name) < 0)
        goto cleanup;

    VIR_DEBUG("Domain with pid %lld has machine name '%s'",
              (long long) pid, name);

 cleanup:
    VIR_FREE(object);
    virDBusMessageUnref(reply);

    return name;
}
Exemple #2
0
VIR_MOCK_WRAP_RET_ARGS(dbus_connection_send_with_reply_and_block,
                       DBusMessage *,
                       DBusConnection *, connection,
                       DBusMessage *, message,
                       int, timeout_milliseconds,
                       DBusError *, error)
{
    DBusMessage *reply = NULL;
    const char *service = dbus_message_get_destination(message);
    const char *member = dbus_message_get_member(message);
    size_t i;
    size_t nargs = 0;
    char **args = NULL;
    char *type = NULL;

    VIR_MOCK_REAL_INIT(dbus_connection_send_with_reply_and_block);

    if (STREQ(service, "org.freedesktop.DBus") &&
        STREQ(member, "ListNames")) {
        const char *svc1 = "org.foo.bar.wizz";
        const char *svc2 = VIR_FIREWALL_FIREWALLD_SERVICE;
        DBusMessageIter iter;
        DBusMessageIter sub;
        reply = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
        dbus_message_iter_init_append(reply, &iter);
        dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
                                         "s", &sub);

        if (!dbus_message_iter_append_basic(&sub,
                                            DBUS_TYPE_STRING,
                                            &svc1))
            goto error;
        if (!fwDisabled &&
            !dbus_message_iter_append_basic(&sub,
                                            DBUS_TYPE_STRING,
                                            &svc2))
            goto error;
        dbus_message_iter_close_container(&iter, &sub);
    } else if (STREQ(service, VIR_FIREWALL_FIREWALLD_SERVICE) &&
               STREQ(member, "passthrough")) {
        bool isAdd = false;
        bool doError = false;

        if (virDBusMessageDecode(message,
                                 "sa&s",
                                 &type,
                                 &nargs,
                                 &args) < 0)
            goto error;

        for (i = 0; i < nargs; i++) {
            /* Fake failure on the command with this IP addr */
            if (STREQ(args[i], "-A")) {
                isAdd = true;
            } else if (isAdd && STREQ(args[i], "192.168.122.255")) {
                doError = true;
            }
        }

        if (fwBuf) {
            if (STREQ(type, "ipv4"))
                virBufferAddLit(fwBuf, IPTABLES_PATH);
            else if (STREQ(type, "ipv4"))
                virBufferAddLit(fwBuf, IP6TABLES_PATH);
            else
                virBufferAddLit(fwBuf, EBTABLES_PATH);
        }
        for (i = 0; i < nargs; i++) {
            if (fwBuf) {
                virBufferAddLit(fwBuf, " ");
                virBufferEscapeShell(fwBuf, args[i]);
            }
        }
        if (fwBuf)
            virBufferAddLit(fwBuf, "\n");
        if (doError) {
            dbus_set_error_const(error,
                                 "org.firewalld.error",
                                 "something bad happened");
        } else {
            if (nargs == 1 &&
                STREQ(type, "ipv4") &&
                STREQ(args[0], "-L")) {
                if (virDBusCreateReply(&reply,
                                       "s", TEST_FILTER_TABLE_LIST) < 0)
                    goto error;
            } else if (nargs == 3 &&
                       STREQ(type, "ipv4") &&
                       STREQ(args[0], "-t") &&
                       STREQ(args[1], "nat") &&
                       STREQ(args[2], "-L")) {
                if (virDBusCreateReply(&reply,
                                       "s", TEST_NAT_TABLE_LIST) < 0)
                    goto error;
            } else {
                if (virDBusCreateReply(&reply,
                                       "s", "success") < 0)
                    goto error;
            }
        }
    } else {
        reply = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
    }

 cleanup:
    VIR_FREE(type);
    for (i = 0; i < nargs; i++)
        VIR_FREE(args[i]);
    VIR_FREE(args);
    return reply;

 error:
    virDBusMessageUnref(reply);
    reply = NULL;
    if (error && !dbus_error_is_set(error))
        dbus_set_error_const(error,
                             "org.firewalld.error",
                             "something unexpected happened");

    goto cleanup;
}
Exemple #3
0
void
virSystemdNotifyStartup(void)
{
#ifdef HAVE_SYS_UN_H
    const char *path;
    const char *msg = "READY=1";
    int fd;
    struct sockaddr_un un = {
        .sun_family = AF_UNIX,
    };
    struct iovec iov = {
        .iov_base = (char *)msg,
        .iov_len = strlen(msg),
    };
    struct msghdr mh = {
        .msg_name = &un,
        .msg_iov = &iov,
        .msg_iovlen = 1,
    };

    if (!(path = virGetEnvBlockSUID("NOTIFY_SOCKET"))) {
        VIR_DEBUG("Skipping systemd notify, not requested");
        return;
    }

    /* NB sun_path field is *not* NUL-terminated, hence >, not >= */
    if (strlen(path) > sizeof(un.sun_path)) {
        VIR_WARN("Systemd notify socket path '%s' too long", path);
        return;
    }

    memcpy(un.sun_path, path, strlen(path));
    if (un.sun_path[0] == '@')
        un.sun_path[0] = '\0';

    mh.msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(path);

    fd = socket(AF_UNIX, SOCK_DGRAM, 0);
    if (fd < 0) {
        VIR_WARN("Unable to create socket FD");
        return;
    }

    if (sendmsg(fd, &mh, MSG_NOSIGNAL) < 0)
        VIR_WARN("Failed to notify systemd");

    VIR_FORCE_CLOSE(fd);
#endif /* HAVE_SYS_UN_H */
}

static int
virSystemdPMSupportTarget(const char *methodName, bool *result)
{
    int ret;
    DBusConnection *conn;
    DBusMessage *message = NULL;
    char *response;

    ret = virDBusIsServiceEnabled("org.freedesktop.login1");
    if (ret < 0)
        return ret;

    if ((ret = virDBusIsServiceRegistered("org.freedesktop.login1")) < 0)
        return ret;

    if (!(conn = virDBusGetSystemBus()))
        return -1;

    ret = -1;

    if (virDBusCallMethod(conn,
                          &message,
                          NULL,
                          "org.freedesktop.login1",
                          "/org/freedesktop/login1",
                          "org.freedesktop.login1.Manager",
                          methodName,
                          NULL) < 0)
        return ret;

    if ((ret = virDBusMessageDecode(message, "s", &response)) < 0)
        goto cleanup;

    *result = STREQ("yes", response) || STREQ("challenge", response);

    ret = 0;

 cleanup:
    virDBusMessageUnref(message);
    VIR_FREE(response);

    return ret;
}

int virSystemdCanSuspend(bool *result)
{
    return virSystemdPMSupportTarget("CanSuspend", result);
}

int virSystemdCanHibernate(bool *result)
{
    return virSystemdPMSupportTarget("CanHibernate", result);
}

int virSystemdCanHybridSleep(bool *result)
{
    return virSystemdPMSupportTarget("CanHybridSleep", result);
}